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

[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
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment