From 134351edc28e083c61012b6c69e8e54dd7fa5bcc Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Sun, 25 Oct 2026 09:17:28 +0200 Subject: [PATCH] ipmr: fully initialize the synthetic IP header in ipmr_get_route() 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 Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/0545f0c83f5ee2f6696210f87268e811ef655715.1792476357.git.zhilinz%40nebusec.ai Signed-off-by: Ido Schimmel Reviewed-by: Hangbin Liu Reviewed-by: Eric Dumazet Link: https://patch.msgid.link/20261025071729.34967-2-idosch@nvidia.com Signed-off-by: Jakub Kicinski --- net/ipv4/ipmr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 8b84142fd775..4a22d9f23425 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -2511,6 +2511,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;