Commit c71bf113dfdf for kernel

commit c71bf113dfdf426bdaf106636f573ef87b6613a0
Author: Christoph Böhmwalder <christoph.boehmwalder@linbit.com>
Date:   Fri Aug 14 17:16:17 2026 +0200

    drbd: don't leak the shared secret to unprivileged netlink dumps

    The conversion to explicit netlink serialization dropped the
    exclude_sensitive parameter from net_conf_to_skb(), so each caller has
    to sanitize by hand. Two dump paths were missed:
    drbd_nl_get_connections_dumpit() and the volume-less connection branch
    of get_one_status(). Neither op carries GENL_ADMIN_PERM, so any
    unprivileged local user could read the CRAM-HMAC secret.

    Add a net_conf_to_skb_sanitized() wrapper and route all three callers
    through it.

    Fixes: 8098eeb693c4 ("drbd: replace genl_magic with explicit netlink serialization")
    Reported-by: Vivek Parikh <vivek.parikh@breachx.ai>
    Signed-off-by: Christoph Böhmwalder <christoph.boehmwalder@linbit.com>
    Link: https://patch.msgid.link/20260814151617.73752-1-christoph.boehmwalder@linbit.com
    Signed-off-by: Jens Axboe <axboe@kernel.dk>

diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c
index f9ffcd67607b..b77f901fc3ef 100644
--- a/drivers/block/drbd/drbd_nl.c
+++ b/drivers/block/drbd/drbd_nl.c
@@ -3306,6 +3306,26 @@ static int nla_put_drbd_cfg_context(struct sk_buff *skb,
 	return -EMSGSIZE;
 }

+/*
+ * net_conf_to_skb() serializes the shared secret verbatim. Any path that can
+ * answer a request from an unprivileged process must pass exclude_sensitive,
+ * so the secret is blanked in a private copy before it reaches the skb.
+ */
+static int net_conf_to_skb_sanitized(struct sk_buff *skb, struct net_conf *nc,
+				     bool exclude_sensitive)
+{
+	struct net_conf nc_clean;
+
+	if (!exclude_sensitive)
+		return net_conf_to_skb(skb, nc);
+
+	nc_clean = *nc;
+	memset(nc_clean.shared_secret, 0, sizeof(nc_clean.shared_secret));
+	nc_clean.shared_secret_len = 0;
+
+	return net_conf_to_skb(skb, &nc_clean);
+}
+
 /*
  * The generic netlink dump callbacks are called outside the genl_lock(), so
  * they cannot use the simple attribute parsing code which uses global
@@ -3621,7 +3641,8 @@ int drbd_nl_get_connections_dumpit(struct sk_buff *skb, struct netlink_callback
 			goto out;
 		net_conf = rcu_dereference(connection->net_conf);
 		if (net_conf) {
-			err = net_conf_to_skb(skb, net_conf);
+			err = net_conf_to_skb_sanitized(skb, net_conf,
+							!capable(CAP_SYS_ADMIN));
 			if (err)
 				goto out;
 		}
@@ -3842,18 +3863,8 @@ static int nla_put_status_info(struct sk_buff *skb, struct drbd_device *device,
 		struct net_conf *nc;

 		nc = rcu_dereference(first_peer_device(device)->connection->net_conf);
-		if (nc) {
-			if (exclude_sensitive) {
-				struct net_conf nc_clean = *nc;
-
-				memset(nc_clean.shared_secret, 0,
-				       sizeof(nc_clean.shared_secret));
-				nc_clean.shared_secret_len = 0;
-				err = net_conf_to_skb(skb, &nc_clean);
-			} else {
-				err = net_conf_to_skb(skb, nc);
-			}
-		}
+		if (nc)
+			err = net_conf_to_skb_sanitized(skb, nc, exclude_sensitive);
 	}
 	rcu_read_unlock();
 	if (err)
@@ -4058,7 +4069,7 @@ static int get_one_status(struct sk_buff *skb, struct netlink_callback *cb)
 				struct net_conf *nc;

 				nc = rcu_dereference(connection->net_conf);
-				if (nc && net_conf_to_skb(skb, nc) != 0)
+				if (nc && net_conf_to_skb_sanitized(skb, nc, true) != 0)
 					goto cancel;
 			}
 			goto done;