mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 13:51:44 +00:00
[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: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b6e77a5346
commit
7228749092
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user