Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 72287490 authored by Alexey Kuznetsov's avatar Alexey Kuznetsov Committed by David S. Miller
Browse files

[IPV4] ipmr: ip multicast route bug fix.



IP multicast route code was reusing an skb which causes use after free
and double free.

From: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>

Note, it is real skb_clone(), not alloc_skb(). Equeued skb contains
the whole half-prepared netlink message plus room for the rest.
It could be also skb_copy(), if we want to be puristic about mangling
cloned data, but original copy is really not going to be used.  

Acked-by: default avatarStephen Hemminger <shemminger@osdl.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b6e77a53
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -1578,6 +1578,7 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
	cache = ipmr_cache_find(rt->rt_src, rt->rt_dst);

	if (cache==NULL) {
		struct sk_buff *skb2;
		struct net_device *dev;
		int vif;

@@ -1591,12 +1592,18 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait)
			read_unlock(&mrt_lock);
			return -ENODEV;
		}
		skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
		skb->nh.iph->ihl = sizeof(struct iphdr)>>2;
		skb->nh.iph->saddr = rt->rt_src;
		skb->nh.iph->daddr = rt->rt_dst;
		skb->nh.iph->version = 0;
		err = ipmr_cache_unresolved(vif, skb);
		skb2 = skb_clone(skb, GFP_ATOMIC);
		if (!skb2) {
			read_unlock(&mrt_lock);
			return -ENOMEM;
		}

		skb2->nh.raw = skb_push(skb2, sizeof(struct iphdr));
		skb2->nh.iph->ihl = sizeof(struct iphdr)>>2;
		skb2->nh.iph->saddr = rt->rt_src;
		skb2->nh.iph->daddr = rt->rt_dst;
		skb2->nh.iph->version = 0;
		err = ipmr_cache_unresolved(vif, skb2);
		read_unlock(&mrt_lock);
		return err;
	}