Fix two bugs in IPv4 multicast routing: 1. In reg_vif_xmit() (net/ipv4/ipmr.c), verify that the skb contains a full IPv4 header with ihl >= 5 before reading ip_hdr(skb) and passing the encapsulated PIM register packet to ipmr_cache_report(). 2. In ipmr_get_route() and inet_rtm_getroute() (net/ipv4/route.c), zero- initialize the synthetic IPv4 header pushed onto the RTM_GETROUTE probe skb so uninitialized slab bytes in iph->ihl / iph->tos / iph->frag_off do not corrupt fib_multipath_hash() or ipmr_cache_alloc(). Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Assisted-by: LLM Signed-off-by: Hui Peng --- diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index b9c544d48c45..8242ab62d1b3 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -545,6 +545,13 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) return err; } + if (!pskb_may_pull(skb, sizeof(struct iphdr))) { + DEV_STATS_INC(dev, tx_dropped); + rcu_read_unlock(); + kfree_skb(skb); + return NETDEV_TX_OK; + } + DEV_STATS_ADD(dev, tx_bytes, skb->len); DEV_STATS_INC(dev, tx_packets); @@ -2492,6 +2499,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; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 37674d76f90f..1cba70e38507 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -3087,8 +3087,10 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, r, portid); if (err <= 0) { - if (err == 0) + if (err == 0) { + nlmsg_end(skb, nlh); return 0; + } goto nla_put_failure; } } else