Netdev List
 help / color / mirror / Atom feed
* [PATCH net 0/2] ipmr, ip6mr: Fix several info leaks
@ 2026-10-25  7:17 Ido Schimmel
  2026-10-25  7:17 ` [PATCH net 1/2] ipmr: fully initialize the synthetic IP header in ipmr_get_route() Ido Schimmel
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ 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

ip{,6}mr_cache_report() copy the IP header of a packet that triggered an
upcall to a report packet that is delivered to user space. The header
is not always fully initialized or present, resulting in info leaks
flagged by KMSAN.

Patch 1 fixes an info leak in the RTM_GETROUTE path, caused by the fact
that ipmr_get_route() does not fully initialize the IP header of the
packet that it creates. IPv6 does not suffer from this problem.

Patch 2 fixes info leaks triggered by packets injected into pim{,6}reg
devices via AF_PACKET sockets. The kernel does not validate that these
are IP packets that carry an IP header before calling
ip{,6}mr_cache_report().

Both issues were reported by Sashiko and reproduced by me. See KMSAN
traces in the commit messages.

As far as I can tell, all other callers call these functions from the IP
input / output paths and therefore provide a valid IP packet, with the
exception of ip6mr_get_route() which fully initializes the header of the
packet it creates.

Ido Schimmel (2):
  ipmr: fully initialize the synthetic IP header in ipmr_get_route()
  ipmr, ip6mr: validate packets injected into the register vif on xmit

 net/ipv4/ipmr.c  | 7 +++++++
 net/ipv6/ip6mr.c | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

-- 
2.56.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH net 1/2] ipmr: fully initialize the synthetic IP header in ipmr_get_route()
  2026-10-25  7:17 [PATCH net 0/2] ipmr, ip6mr: Fix several info leaks Ido Schimmel
@ 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
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ 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] 8+ messages in thread

* [PATCH net 2/2] ipmr, ip6mr: validate packets injected into the register vif on xmit
  2026-10-25  7:17 [PATCH net 0/2] ipmr, ip6mr: Fix several info leaks Ido Schimmel
  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
  2026-10-26  5:59 ` [PATCH net 0/2] ipmr, ip6mr: Fix several info leaks Hangbin Liu
  2026-10-26 23:50 ` patchwork-bot+netdevbpf
  3 siblings, 2 replies; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ messages in thread

* Re: [PATCH net 0/2] ipmr, ip6mr: Fix several info leaks
  2026-10-25  7:17 [PATCH net 0/2] ipmr, ip6mr: Fix several info leaks Ido Schimmel
  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 ` [PATCH net 2/2] ipmr, ip6mr: validate packets injected into the register vif on xmit Ido Schimmel
@ 2026-10-26  5:59 ` Hangbin Liu
  2026-10-26 23:50 ` patchwork-bot+netdevbpf
  3 siblings, 0 replies; 8+ messages in thread
From: Hangbin Liu @ 2026-10-26  5:59 UTC (permalink / raw)
  To: Ido Schimmel
  Cc: netdev, davem, kuba, pabeni, edumazet, dsahern, horms, yoshfuji

On Sun, Oct 25, 2026 at 09:17:27AM +0200, Ido Schimmel wrote:
> ip{,6}mr_cache_report() copy the IP header of a packet that triggered an
> upcall to a report packet that is delivered to user space. The header
> is not always fully initialized or present, resulting in info leaks
> flagged by KMSAN.
> 
> Patch 1 fixes an info leak in the RTM_GETROUTE path, caused by the fact
> that ipmr_get_route() does not fully initialize the IP header of the
> packet that it creates. IPv6 does not suffer from this problem.
> 
> Patch 2 fixes info leaks triggered by packets injected into pim{,6}reg
> devices via AF_PACKET sockets. The kernel does not validate that these
> are IP packets that carry an IP header before calling
> ip{,6}mr_cache_report().
> 
> Both issues were reported by Sashiko and reproduced by me. See KMSAN
> traces in the commit messages.
> 
> As far as I can tell, all other callers call these functions from the IP
> input / output paths and therefore provide a valid IP packet, with the
> exception of ip6mr_get_route() which fully initializes the header of the
> packet it creates.
> 
> Ido Schimmel (2):
>   ipmr: fully initialize the synthetic IP header in ipmr_get_route()
>   ipmr, ip6mr: validate packets injected into the register vif on xmit
> 
>  net/ipv4/ipmr.c  | 7 +++++++
>  net/ipv6/ip6mr.c | 2 +-
>  2 files changed, 8 insertions(+), 1 deletion(-)
> 
> -- 
> 2.56.0
> 

Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>

^ permalink raw reply	[flat|nested] 8+ 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; 8+ 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] 8+ messages in thread

* Re: [PATCH net 0/2] ipmr, ip6mr: Fix several info leaks
  2026-10-25  7:17 [PATCH net 0/2] ipmr, ip6mr: Fix several info leaks Ido Schimmel
                   ` (2 preceding siblings ...)
  2026-10-26  5:59 ` [PATCH net 0/2] ipmr, ip6mr: Fix several info leaks Hangbin Liu
@ 2026-10-26 23:50 ` patchwork-bot+netdevbpf
  3 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-10-26 23:50 UTC (permalink / raw)
  To: Ido Schimmel
  Cc: netdev, davem, kuba, pabeni, edumazet, dsahern, horms, yoshfuji

Hello:

This series was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Sun, 25 Oct 2026 09:17:27 +0200 you wrote:
> ip{,6}mr_cache_report() copy the IP header of a packet that triggered an
> upcall to a report packet that is delivered to user space. The header
> is not always fully initialized or present, resulting in info leaks
> flagged by KMSAN.
> 
> Patch 1 fixes an info leak in the RTM_GETROUTE path, caused by the fact
> that ipmr_get_route() does not fully initialize the IP header of the
> packet that it creates. IPv6 does not suffer from this problem.
> 
> [...]

Here is the summary with links:
  - [net,1/2] ipmr: fully initialize the synthetic IP header in ipmr_get_route()
    https://git.kernel.org/netdev/net/c/134351edc28e
  - [net,2/2] ipmr, ip6mr: validate packets injected into the register vif on xmit
    https://git.kernel.org/netdev/net/c/aa1799e93f5e

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-10-26 23:50 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-25  7:17 [PATCH net 0/2] ipmr, ip6mr: Fix several info leaks Ido Schimmel
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
2026-10-26  5:59 ` [PATCH net 0/2] ipmr, ip6mr: Fix several info leaks Hangbin Liu
2026-10-26 23:50 ` patchwork-bot+netdevbpf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox