summaryrefslogtreecommitdiff
path: root/scripts/Makefile.thinlto
diff options
context:
space:
mode:
authorHaofeng Li <lihaofeng@kylinos.cn>2026-09-01 13:47:08 -0400
committerDavid Teigland <teigland@redhat.com>2026-09-02 09:01:51 -0500
commitf53374bd432b51d7c7f0a879f0229c7c56e1dd7c (patch)
tree66d1f3e042be76d17b57971c1cc684b2f9612832 /scripts/Makefile.thinlto
parentcee9395acd8043be0644b25c34bfa86623f2b935 (diff)
downloadlinux-f53374bd432b51d7c7f0a879f0229c7c56e1dd7c.tar.gz
linux-f53374bd432b51d7c7f0a879f0229c7c56e1dd7c.zip
dlm: gate dlm_plock device on CAP_SYS_ADMIN
fs/dlm/plock.c registers /dev/dlm_plock via a miscdevice whose file_operations has no .open callback and whose .mode field is unset. The kernel therefore performs no capability check on open, and any process that can open the node becomes an unprivileged plock daemon with full read+write access to the pending-plock queue. Attack chain (when the device node is reachable by an unprivileged opener — see mitigation note below): 1. attacker open("/dev/dlm_plock") succeeds with no cap check 2. dev_read() drains pending plock requests straight to user space, leaking dlm_plock_info fields: fsid, number (resource id / inode), start, end, owner, pid, ex, wait 3. dev_write() matches an attacker-supplied dlm_plock_info against a pending op on recv_list (matched on fsid+number+ owner+pid+start+end+ex+wait) and memcpy()'s it into the in-kernel op, including a forged .rv == 0 4. when a matched op exists, the forged result is then applied: for async ops (op->data != NULL), dlm_plock_callback() runs posix_lock_file(); for sync ops, the requester wakes and proceeds as if the cluster had granted the lock. Either way the requester ends up holding a POSIX lock without a real DLM grant, or sees attacker-chosen rv that breaks lock correctness. With no pending op on recv_list, dev_write() still returns sizeof(info) but does nothing beyond a pr_debug ("dlm dev_write no op ...") — so a syntactically accepted write does not by itself prove an applied grant. Mitigation: on a stock kernel, devtmpfs creates /dev/dlm_plock as 0600 root:root, so steps 1-4 are only reachable where the node is exposed to a less privileged principal — e.g. udev MODE=0666, container bind-mount of the node, or an fd passed via SCM_RIGHTS. The in-kernel capability gap is real regardless of node mode. Reproduction (kernel 7.2.0-rc3, dlm loaded): # ./exploit_h2 # as root [*] node /dev/dlm_plock mode=0600 uid=0 gid=0 [!!!] AUTH BYPASS: opened with no capability check (fd=3) [!!!] FORGE ACCEPTED: kernel accepted forged plock result (rv=0); pending ops are grant-forgeable [VULNERABLE] open + read-leak + grant-forge demonstrated The "FORGE ACCEPTED" line means dev_write() returned sizeof(info), i.e. the write path is reachable and the version check passed; it does not by itself mean a grant was applied. Demonstrating an actual forged grant requires a concurrent plock op on recv_list to match against. $ setpriv --reuid 65534 --regid 65534 ./exploit_h2 [OK ] open denied: Permission denied # devtmpfs 0600, not a kernel cap check Fix: add a .open callback that requires CAP_SYS_ADMIN, and set .mode = 0600 on the miscdevice so the explicit expectation matches the devtmpfs default and survives future defaults. Acked-by: Alexander Aring <aahringo@redhat.com> Signed-off-by: Haofeng Li <lihaofeng@kylinos.cn> Signed-off-by: Alexander Aring <aahringo@redhat.com> Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'scripts/Makefile.thinlto')
0 files changed, 0 insertions, 0 deletions