diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-16 07:00:40 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-16 07:00:40 -0700 |
| commit | dcb68831eac76dbfda1cf5930d3003d938890d34 (patch) | |
| tree | eb0f406a90219e1387b57e483f3d56f17e327d81 | |
| parent | 0bae94aab8208b7107a2dda5de6ce046466663fd (diff) | |
| parent | c71bf113dfdf426bdaf106636f573ef87b6613a0 (diff) | |
| download | linux-dcb68831eac76dbfda1cf5930d3003d938890d34.tar.gz linux-dcb68831eac76dbfda1cf5930d3003d938890d34.zip | |
Merge tag 'block-7.2-20260815' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux
Pull block fix from Jens Axboe:
"A single fix for a regression in this cycle, where drbd would leak
shared secrets over netlink. This restores the behavior to match
what we had before"
* tag 'block-7.2-20260815' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux:
drbd: don't leak the shared secret to unprivileged netlink dumps
| -rw-r--r-- | drivers/block/drbd/drbd_nl.c | 39 |
1 files changed, 25 insertions, 14 deletions
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 @@ -3307,6 +3307,26 @@ nla_put_failure: } /* + * 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 * attribute tables. @@ -3621,7 +3641,8 @@ put_result: 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 @@ next_resource: 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; |
