[PATCH net] net: drop_monitor: fix info leak in NET_DM_ATTR_PAYLOAD

Yehyeong Lee posted 1 patch 2 days, 11 hours ago
There is a newer version of this series
net/core/drop_monitor.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
[PATCH net] net: drop_monitor: fix info leak in NET_DM_ATTR_PAYLOAD
Posted by Yehyeong Lee 2 days, 11 hours ago
net_dm_packet_report_fill() and net_dm_hw_packet_report_fill() open code
the NET_DM_ATTR_PAYLOAD attribute to avoid zeroing the packet payload
before overwriting it with skb_copy_bits():

	attr = skb_put(msg, nla_total_size(payload_len));
	attr->nla_type = NET_DM_ATTR_PAYLOAD;
	attr->nla_len = nla_attr_size(payload_len);
	if (skb_copy_bits(skb, 0, nla_data(attr), payload_len))
		goto nla_put_failure;

skb_put() reserves nla_total_size(payload_len), i.e. the header plus the
NLA_ALIGN() padding, but only payload_len bytes are copied in. When
payload_len is not a multiple of 4 the 1-3 padding bytes are never
initialized and are leaked to user space inside the netlink message.

This is the same bug, and the same open-coded pattern, that commit
aedd02af1f8b ("net: psample: fix info leak in PSAMPLE_ATTR_DATA") fixed
in psample by reserving only nla_attr_size() and zeroing the pad with
skb_put_zero(nla_padlen()).

KMSAN confirms the leak for the software path when the packet payload
length is not 4-byte aligned:

  BUG: KMSAN: kernel-infoleak in _copy_to_iter
   _copy_to_iter
   __skb_datagram_iter
   skb_copy_datagram_iter
   netlink_recvmsg
   sock_recvmsg
   __sys_recvfrom
  Uninit was created at:
   kmem_cache_alloc_node_noprof
   __alloc_skb
   net_dm_packet_work
  Bytes 173-175 of 176 are uninitialized

Zero the attribute padding in both the software and hardware drop report
paths, mirroring the psample fix.

Fixes: ca30707dee2b ("drop_monitor: Add packet alert mode")
Fixes: 5e58109b1ea4 ("drop_monitor: Add support for packet alert mode for hardware drops")
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
---
 net/core/drop_monitor.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 2bf3cab5e557..6a5bcaf21b57 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -671,12 +671,14 @@ static int net_dm_packet_report_fill(struct sk_buff *msg, struct sk_buff *skb,
 	if (nla_put_u16(msg, NET_DM_ATTR_PROTO, be16_to_cpu(skb->protocol)))
 		goto nla_put_failure;
 
-	attr = skb_put(msg, nla_total_size(payload_len));
+	attr = skb_put(msg, nla_attr_size(payload_len));
 	attr->nla_type = NET_DM_ATTR_PAYLOAD;
 	attr->nla_len = nla_attr_size(payload_len);
 	if (skb_copy_bits(skb, 0, nla_data(attr), payload_len))
 		goto nla_put_failure;
 
+	skb_put_zero(msg, nla_padlen(payload_len));
+
 out:
 	genlmsg_end(msg, hdr);
 
@@ -831,12 +833,14 @@ static int net_dm_hw_packet_report_fill(struct sk_buff *msg,
 	if (nla_put_u16(msg, NET_DM_ATTR_PROTO, be16_to_cpu(skb->protocol)))
 		goto nla_put_failure;
 
-	attr = skb_put(msg, nla_total_size(payload_len));
+	attr = skb_put(msg, nla_attr_size(payload_len));
 	attr->nla_type = NET_DM_ATTR_PAYLOAD;
 	attr->nla_len = nla_attr_size(payload_len);
 	if (skb_copy_bits(skb, 0, nla_data(attr), payload_len))
 		goto nla_put_failure;
 
+	skb_put_zero(msg, nla_padlen(payload_len));
+
 out:
 	genlmsg_end(msg, hdr);
 
-- 
2.43.0
Re: [PATCH net] net: drop_monitor: fix info leak in NET_DM_ATTR_PAYLOAD
Posted by Eric Dumazet 2 days, 11 hours ago
On Wed, Jul 22, 2026 at 12:44 PM Yehyeong Lee <yhlee@isslab.korea.ac.kr> wrote:
>
> net_dm_packet_report_fill() and net_dm_hw_packet_report_fill() open code
> the NET_DM_ATTR_PAYLOAD attribute to avoid zeroing the packet payload
> before overwriting it with skb_copy_bits():
>
>         attr = skb_put(msg, nla_total_size(payload_len));
>         attr->nla_type = NET_DM_ATTR_PAYLOAD;
>         attr->nla_len = nla_attr_size(payload_len);
>         if (skb_copy_bits(skb, 0, nla_data(attr), payload_len))
>                 goto nla_put_failure;
>
> skb_put() reserves nla_total_size(payload_len), i.e. the header plus the
> NLA_ALIGN() padding, but only payload_len bytes are copied in. When
> payload_len is not a multiple of 4 the 1-3 padding bytes are never
> initialized and are leaked to user space inside the netlink message.
>
> This is the same bug, and the same open-coded pattern, that commit
> aedd02af1f8b ("net: psample: fix info leak in PSAMPLE_ATTR_DATA") fixed
> in psample by reserving only nla_attr_size() and zeroing the pad with
> skb_put_zero(nla_padlen()).
>
> KMSAN confirms the leak for the software path when the packet payload
> length is not 4-byte aligned:
>
>   BUG: KMSAN: kernel-infoleak in _copy_to_iter
>    _copy_to_iter
>    __skb_datagram_iter
>    skb_copy_datagram_iter
>    netlink_recvmsg
>    sock_recvmsg
>    __sys_recvfrom
>   Uninit was created at:
>    kmem_cache_alloc_node_noprof
>    __alloc_skb
>    net_dm_packet_work
>   Bytes 173-175 of 176 are uninitialized
>
> Zero the attribute padding in both the software and hardware drop report
> paths, mirroring the psample fix.
>
> Fixes: ca30707dee2b ("drop_monitor: Add packet alert mode")
> Fixes: 5e58109b1ea4 ("drop_monitor: Add support for packet alert mode for hardware drops")
> Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>

What about using __nla_reserve() instead, and get rid of open-coding ?

Thanks.

 net/core/drop_monitor.c |    8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 2bf3cab5e557a15dd3fa7197098d6b0abcc01fab..b4d1ff2829b6182b86d13a0432b978de8b72325c
100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -671,9 +671,7 @@ static int net_dm_packet_report_fill(struct
sk_buff *msg, struct sk_buff *skb,
        if (nla_put_u16(msg, NET_DM_ATTR_PROTO, be16_to_cpu(skb->protocol)))
                goto nla_put_failure;

-       attr = skb_put(msg, nla_total_size(payload_len));
-       attr->nla_type = NET_DM_ATTR_PAYLOAD;
-       attr->nla_len = nla_attr_size(payload_len);
+       attr = __nla_reserve(msg, NET_DM_ATTR_PAYLOAD, payload_len);
        if (skb_copy_bits(skb, 0, nla_data(attr), payload_len))
                goto nla_put_failure;

@@ -831,9 +829,7 @@ static int net_dm_hw_packet_report_fill(struct sk_buff *msg,
        if (nla_put_u16(msg, NET_DM_ATTR_PROTO, be16_to_cpu(skb->protocol)))
                goto nla_put_failure;

-       attr = skb_put(msg, nla_total_size(payload_len));
-       attr->nla_type = NET_DM_ATTR_PAYLOAD;
-       attr->nla_len = nla_attr_size(payload_len);
+       attr = __nla_reserve(msg, NET_DM_ATTR_PAYLOAD, payload_len);
        if (skb_copy_bits(skb, 0, nla_data(attr), payload_len))
                goto nla_put_failure;



--
pw-bot: cr