All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexander Aring <aahringo@redhat.com>
To: teigland@redhat.com
Cc: aahringo@redhat.com, gfs2@lists.linux.dev
Subject: [PATCH RESEND dlm/next 2/8] dlm: require CAP_SYS_ADMIN for dlm-monitor device
Date: Tue,  1 Sep 2026 13:47:09 -0400	[thread overview]
Message-ID: <20260901174715.3825582-3-aahringo@redhat.com> (raw)
In-Reply-To: <20260901174715.3825582-1-aahringo@redhat.com>

From: Haofeng Li <lihaofeng@kylinos.cn>

monitor_device_open() in fs/dlm/user.c performs only
atomic_inc(&dlm_monitor_opened) and sets dlm_monitor_unused = 0; it
does no capability check.  monitor_device_close() does
atomic_dec_and_test(&dlm_monitor_opened) and, when the count reaches
zero, calls dlm_stop_lockspaces() — which stops every lockspace on
the node.  The miscdevice is also registered with no .mode field.

Attack chain (when the device node is reachable by an unprivileged
opener — see mitigation note below):

  1. attacker open("/dev/dlm-monitor") with no cap check; the
     global counter goes 0 -> 1
  2. attacker close(fd); atomic_dec_and_test reaches zero again
     and dlm_stop_lockspaces() runs -> every DLM lockspace on the
     local node is stopped.  Other cluster members then observe
     the node losing its lockspaces (membership / recovery side
     effects), so the impact is not strictly local to GFS2 /
     OCFS2 / lvmlockd / cluster-md workloads on this node.
  variant: attacker holds the fd open indefinitely to suppress
     the intended stop when dlm_controld later closes its own fd
     (inverse abuse — recovery / shutdown stalls)

Mitigation: devtmpfs creates /dev/dlm-monitor as 0600 root:root on
a stock kernel, so unprivileged open is blocked by the node mode,
not by a kernel cap check.  The gap is real wherever the node is
reachable (udev MODE=0666, container bind-mount, fd via SCM_RIGHTS,
or any setup where dlm_controld shares its monitor fd).

Reproduction (kernel 7.2.0-rc3, dlm loaded, no live lockspace):

  # ./exploit_h3   # as root
  [*] lockspace devices present: 0
  [!!!] AUTH BYPASS: opened /dev/dlm-monitor, no cap check (fd=3)
  [VULNERABLE] monitor open auth bypass demonstrated

  $ setpriv --reuid 65534 --regid 65534 ./exploit_h3
  [OK ] open denied: Permission denied   # node 0600, not cap check

The destructive close path is opt-in in the PoX
(--i-know-it-stops-lockspaces); we did not drive it here.  Driving
the close path on a node with active lockspaces would stop them;
on this throw-away node there are none, but we keep the opt-in gate
so the same PoX is safe to re-run on production-like clusters.

Fix: gate monitor_device_open() on capable(CAP_SYS_ADMIN) and set
.mode = 0600 on monitor_device, matching the dlm_controld-only
intended usage.

Acked-by: Alexander Aring <aahringo@redhat.com>
Signed-off-by: Haofeng Li <lihaofeng@kylinos.cn>
Signed-off-by: Alexander Aring <aahringo@redhat.com>
---
 fs/dlm/user.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index a8ed4c8fdc5bd..cd7e142ca670d 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/miscdevice.h>
+#include <linux/capability.h>
 #include <linux/init.h>
 #include <linux/wait.h>
 #include <linux/file.h>
@@ -910,6 +911,10 @@ static int ctl_device_close(struct inode *inode, struct file *file)
 
 static int monitor_device_open(struct inode *inode, struct file *file)
 {
+	/* dlm_controld is the only expected opener; last close stops LS. */
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
 	atomic_inc(&dlm_monitor_opened);
 	dlm_monitor_unused = 0;
 	return 0;
@@ -958,6 +963,7 @@ static struct miscdevice monitor_device = {
 	.name  = "dlm-monitor",
 	.fops  = &monitor_device_fops,
 	.minor = MISC_DYNAMIC_MINOR,
+	.mode  = 0600,
 };
 
 int __init dlm_user_init(void)
-- 
2.43.0


  parent reply	other threads:[~2026-09-01 17:47 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-01 17:47 [PATCH RESEND dlm/next 0/8] dlm: pending fixes based on v7.3-rc1 Alexander Aring
2026-09-01 17:47 ` [PATCH RESEND dlm/next 1/8] dlm: gate dlm_plock device on CAP_SYS_ADMIN Alexander Aring
2026-09-01 17:47 ` Alexander Aring [this message]
2026-09-01 17:47 ` [PATCH RESEND dlm/next 3/8] dlm: validate userspace lock resource name length Alexander Aring
2026-09-01 17:47 ` [PATCH RESEND dlm/next 4/8] dlm: fix buffer overflow from negative len in dlm_search_rsb_tree Alexander Aring
2026-09-01 17:47 ` [PATCH RESEND dlm/next 5/8] dlm: validate lock modes in recovery messages Alexander Aring
2026-09-01 17:47 ` [PATCH RESEND dlm/next 6/8] dlm: fix NULL pointer dereference in dlm_dump_rsb_name() Alexander Aring
2026-09-01 17:47 ` [PATCH RESEND dlm/next 7/8] dlm: wait for outstanding SRCU callbacks to complete in exit paths Alexander Aring
2026-09-02 13:24   ` Alexander Aring
2026-09-01 17:47 ` [PATCH RESEND dlm/next 8/8] dlm: fix variable key length lookup Alexander Aring

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260901174715.3825582-3-aahringo@redhat.com \
    --to=aahringo@redhat.com \
    --cc=gfs2@lists.linux.dev \
    --cc=teigland@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.