* [PATCH net 1/2] ipmr: fully initialize the synthetic IP header in ipmr_get_route() [not found] <20261025071729.34967-1-idosch@nvidia.com> @ 2026-10-25 7:17 ` Ido Schimmel 2026-10-25 10:50 ` Eric Dumazet 2026-10-25 7:17 ` [PATCH net 2/2] ipmr, ip6mr: validate packets injected into the register vif on xmit Ido Schimmel 1 sibling, 1 reply; 5+ messages in thread From: Ido Schimmel @ 2026-10-25 7:17 UTC (permalink / raw) To: netdev Cc: davem, kuba, pabeni, edumazet, dsahern, horms, yoshfuji, Ido Schimmel, stable For an unresolved multicast route query, ipmr_get_route() builds a synthetic IP header in the headroom obtained from skb_realloc_headroom(), which does not zero the memory it allocates. Only a few fields are initialized, leaving others as stale heap contents. ipmr_cache_report() copies this header into the IGMPMSG_NOCACHE report that is queued to the mroute socket, so a recvmsg() on that socket leaks the uninitialized bytes to user space: the 'tos' field [1] and the 'id' and 'frag_off' fields [2]. Fix by zeroing the IP header before filling in the few fields that are used, so that the entire header is initialized, as in ip6mr_get_route(). [1] BUG: KMSAN: kernel-infoleak in _copy_to_iter raw_recvmsg Uninit was stored to memory at: ipmr_cache_report ipmr_cache_unresolved ipmr_get_route Uninit was created at: pskb_expand_head skb_realloc_headroom ipmr_get_route Byte 1 of 28 is uninitialized [2] BUG: KMSAN: kernel-infoleak in _copy_to_iter raw_recvmsg Uninit was stored to memory at: ipmr_cache_report ipmr_cache_unresolved ipmr_get_route Uninit was created at: pskb_expand_head skb_realloc_headroom ipmr_get_route Bytes 4-7 of 28 are uninitialized Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reported-by: Sashiko <netdev-bot+sashiko@kernel.org> Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/0545f0c83f5ee2f6696210f87268e811ef655715.1792476357.git.zhilinz%40nebusec.ai Assisted-by: LLM Signed-off-by: Ido Schimmel <idosch@nvidia.com> --- net/ipv4/ipmr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index acacaae05cc4..eac23f251bfd 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -2506,6 +2506,7 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb, skb_push(skb2, sizeof(struct iphdr)); skb_reset_network_header(skb2); iph = ip_hdr(skb2); + memset(iph, 0, sizeof(*iph)); iph->ihl = sizeof(struct iphdr) >> 2; iph->saddr = saddr; iph->daddr = daddr; -- 2.56.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net 1/2] ipmr: fully initialize the synthetic IP header in ipmr_get_route() 2026-10-25 7:17 ` [PATCH net 1/2] ipmr: fully initialize the synthetic IP header in ipmr_get_route() Ido Schimmel @ 2026-10-25 10:50 ` Eric Dumazet 0 siblings, 0 replies; 5+ messages in thread From: Eric Dumazet @ 2026-10-25 10:50 UTC (permalink / raw) To: Ido Schimmel Cc: netdev, davem, kuba, pabeni, dsahern, horms, yoshfuji, stable Le dim. 25 oct. 2026 à 08:18, Ido Schimmel <idosch@nvidia.com> a écrit : > > For an unresolved multicast route query, ipmr_get_route() builds a > synthetic IP header in the headroom obtained from > skb_realloc_headroom(), which does not zero the memory it allocates. > Only a few fields are initialized, leaving others as stale heap > contents. > > ipmr_cache_report() copies this header into the IGMPMSG_NOCACHE report > that is queued to the mroute socket, so a recvmsg() on that socket leaks > the uninitialized bytes to user space: the 'tos' field [1] and the 'id' > and 'frag_off' fields [2]. > > Fix by zeroing the IP header before filling in the few fields that are > used, so that the entire header is initialized, as in ip6mr_get_route(). > > [1] > BUG: KMSAN: kernel-infoleak in _copy_to_iter > raw_recvmsg > > Uninit was stored to memory at: > ipmr_cache_report > ipmr_cache_unresolved > ipmr_get_route > > Uninit was created at: > pskb_expand_head > skb_realloc_headroom > ipmr_get_route > > Byte 1 of 28 is uninitialized > > [2] > BUG: KMSAN: kernel-infoleak in _copy_to_iter > raw_recvmsg > > Uninit was stored to memory at: > ipmr_cache_report > ipmr_cache_unresolved > ipmr_get_route > > Uninit was created at: > pskb_expand_head > skb_realloc_headroom > ipmr_get_route > > Bytes 4-7 of 28 are uninitialized > > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") > Cc: stable@vger.kernel.org > Reported-by: Sashiko <netdev-bot+sashiko@kernel.org> > Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/0545f0c83f5ee2f6696210f87268e811ef655715.1792476357.git.zhilinz%40nebusec.ai > Assisted-by: LLM > Signed-off-by: Ido Schimmel <idosch@nvidia.com> > --- > net/ipv4/ipmr.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c > index acacaae05cc4..eac23f251bfd 100644 > --- a/net/ipv4/ipmr.c > +++ b/net/ipv4/ipmr.c > @@ -2506,6 +2506,7 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb, > skb_push(skb2, sizeof(struct iphdr)); > skb_reset_network_header(skb2); > iph = ip_hdr(skb2); > + memset(iph, 0, sizeof(*iph)); > iph->ihl = sizeof(struct iphdr) >> 2; > iph->saddr = saddr; > iph->daddr = daddr; Reviewed-by: Eric Dumazet <edumazet@kernel.org> SGTM, I will send this follow up as a separate patch. diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index acacaae05cc49dc15910f23f7539865432518587..8b84142fd7754d95aa1f2facf68ac554916efd27 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -550,6 +550,11 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) DEV_STATS_ADD(dev, tx_bytes, skb->len); DEV_STATS_INC(dev, tx_packets); + /* skb->cb[] holds qdisc/tc state at this point, not IPCB. + * ipmr_cache_report() reads it as IPCB to build IP_PKTINFO. + */ + memset(IPCB(skb), 0, sizeof(*IPCB(skb))); + /* Pairs with WRITE_ONCE() in vif_add() and vif_delete() */ ipmr_cache_report(mrt, skb, READ_ONCE(mrt->mroute_reg_vif_num), IGMPMSG_WHOLEPKT); ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net 2/2] ipmr, ip6mr: validate packets injected into the register vif on xmit [not found] <20261025071729.34967-1-idosch@nvidia.com> 2026-10-25 7:17 ` [PATCH net 1/2] ipmr: fully initialize the synthetic IP header in ipmr_get_route() Ido Schimmel @ 2026-10-25 7:17 ` Ido Schimmel 2026-10-25 10:52 ` Eric Dumazet 2026-10-26 23:39 ` Jakub Kicinski 1 sibling, 2 replies; 5+ messages in thread From: Ido Schimmel @ 2026-10-25 7:17 UTC (permalink / raw) To: netdev Cc: davem, kuba, pabeni, edumazet, dsahern, horms, yoshfuji, Ido Schimmel, stable reg_vif_xmit() passes the packet to ipmr_cache_report() which copies its IP header into the IGMPMSG_WHOLEPKT report that is queued to the mroute socket. Nothing guarantees that the packet contains a full IP header, so when a short packet is injected on the register device (e.g., using AF_PACKET), the copy reads past the end of the packet and a recvmsg() on the mroute socket leaks the uninitialized bytes to user space [1]. IPv6 has the same problem [2]. Its reg_vif_xmit() does call pskb_inet_may_pull(), but the helper keys off skb->protocol and does not pull anything when the protocol is neither IPv4 nor IPv6. Fix by dropping packets whose protocol does not match the address family of the register device or that do not contain a full network header. [1] BUG: KMSAN: kernel-infoleak in _copy_to_iter raw_recvmsg Uninit was stored to memory at: ipmr_cache_report reg_vif_xmit packet_sendmsg Uninit was created at: __alloc_skb sock_alloc_send_pskb packet_sendmsg Bytes 1-3 of 21 are uninitialized [2] BUG: KMSAN: kernel-infoleak in _copy_to_iter rawv6_recvmsg Uninit was stored to memory at: ip6mr_cache_report reg_vif_xmit packet_sendmsg Uninit was created at: __alloc_skb sock_alloc_send_pskb packet_sendmsg Bytes 8-23 of 41 are uninitialized Fixes: 14fb64e1f449 ("[IPV6] MROUTE: Support PIM-SM (SSM).") Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reported-by: Sashiko <netdev-bot+sashiko@kernel.org> Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/0545f0c83f5ee2f6696210f87268e811ef655715.1792476357.git.zhilinz%40nebusec.ai Assisted-by: LLM Signed-off-by: Ido Schimmel <idosch@nvidia.com> --- net/ipv4/ipmr.c | 6 ++++++ net/ipv6/ip6mr.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index eac23f251bfd..d6691c917af4 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -539,6 +539,12 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) }; int err; + if (skb->protocol != htons(ETH_P_IP) || !pskb_inet_may_pull(skb)) { + DEV_STATS_INC(dev, tx_errors); + kfree_skb(skb); + return NETDEV_TX_OK; + } + rcu_read_lock(); err = ipmr_fib_lookup(net, &fl4, &mrt); if (err < 0) { diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 3a551be30f15..a628acf50b0d 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -642,7 +642,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, .flowi6_mark = skb->mark, }; - if (!pskb_inet_may_pull(skb)) + if (skb->protocol != htons(ETH_P_IPV6) || !pskb_inet_may_pull(skb)) goto tx_err; rcu_read_lock(); -- 2.56.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net 2/2] ipmr, ip6mr: validate packets injected into the register vif on xmit 2026-10-25 7:17 ` [PATCH net 2/2] ipmr, ip6mr: validate packets injected into the register vif on xmit Ido Schimmel @ 2026-10-25 10:52 ` Eric Dumazet 2026-10-26 23:39 ` Jakub Kicinski 1 sibling, 0 replies; 5+ messages in thread From: Eric Dumazet @ 2026-10-25 10:52 UTC (permalink / raw) To: Ido Schimmel Cc: netdev, davem, kuba, pabeni, dsahern, horms, yoshfuji, stable Le dim. 25 oct. 2026 à 08:18, Ido Schimmel <idosch@nvidia.com> a écrit : > > reg_vif_xmit() passes the packet to ipmr_cache_report() which copies its > IP header into the IGMPMSG_WHOLEPKT report that is queued to the mroute > socket. Nothing guarantees that the packet contains a full IP header, so > when a short packet is injected on the register device (e.g., using > AF_PACKET), the copy reads past the end of the packet and a recvmsg() on > the mroute socket leaks the uninitialized bytes to user space [1]. > > IPv6 has the same problem [2]. Its reg_vif_xmit() does call > pskb_inet_may_pull(), but the helper keys off skb->protocol and does not > pull anything when the protocol is neither IPv4 nor IPv6. > > Fix by dropping packets whose protocol does not match the address family > of the register device or that do not contain a full network header. > Reviewed-by: Eric Dumazet <edumazet@kernel.org> ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net 2/2] ipmr, ip6mr: validate packets injected into the register vif on xmit 2026-10-25 7:17 ` [PATCH net 2/2] ipmr, ip6mr: validate packets injected into the register vif on xmit Ido Schimmel 2026-10-25 10:52 ` Eric Dumazet @ 2026-10-26 23:39 ` Jakub Kicinski 1 sibling, 0 replies; 5+ messages in thread From: Jakub Kicinski @ 2026-10-26 23:39 UTC (permalink / raw) To: Ido Schimmel Cc: netdev, davem, pabeni, edumazet, dsahern, horms, yoshfuji, stable On Sun, 25 Oct 2026 09:17:29 +0200 Ido Schimmel wrote: > Assisted-by: LLM Hi Ido! FWIW these are no longer necessary. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-10-26 23:39 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20261025071729.34967-1-idosch@nvidia.com>
2026-10-25 7:17 ` [PATCH net 1/2] ipmr: fully initialize the synthetic IP header in ipmr_get_route() Ido Schimmel
2026-10-25 10:50 ` Eric Dumazet
2026-10-25 7:17 ` [PATCH net 2/2] ipmr, ip6mr: validate packets injected into the register vif on xmit Ido Schimmel
2026-10-25 10:52 ` Eric Dumazet
2026-10-26 23:39 ` Jakub Kicinski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox