mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
ipmr, ip6mr: validate packets injected into the register vif on xmit
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:14fb64e1f4("[IPV6] MROUTE: Support PIM-SM (SSM).") Fixes:1da177e4c3("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reported-by: Sashiko <netdev-bot+sashiko@kernel.org> Closes:0545f0c83f.1792476357.git.zhilinz%40nebusec.ai Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Link: https://patch.msgid.link/20261025071729.34967-3-idosch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
134351edc2
commit
aa1799e93f
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user