From: Huyen Nguyen <[EMAIL PROTECTED]>
A possible bug:
rt_fill_info() calls ipmr_get_route().
ipmr_get_route() calls ipmr_cache_unresolved()
ipmr_cache_unresolved() gets an error and does kfree_skb(skb)
ipmr_cache_unresolved() returns a -ve errno to ipmr_get_route()
ipmr_get_route() returns the errno to rt_fill_info()
rt_fill_info() diddles with the now-kfreed skb.
It may not be a bug if that kfree_skb() is only supposed to be balancing some
skb_get() which we didn't notice. I don't think so, but could someone please
check?
Here's Huyen's proposed fix. I think it goes halfway - it's clearer if the
function which takes a ref on a data structure is responsible for dropping
that ref too, rather than some two-deep callee. IMO.
If we are going to deliberately do funky stuff like this then the skb lifetime
protocol should be commented, so as to avoid confusing poor little non-net
people. IMO.
Signed-off-by: Huyen Nguyen <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
---
net/ipv4/ipmr.c | 7 ++-----
1 files changed, 2 insertions(+), 5 deletions(-)
diff -puN net/ipv4/ipmr.c~ipmr_cache_unresolved-fix net/ipv4/ipmr.c
--- devel/net/ipv4/ipmr.c~ipmr_cache_unresolved-fix 2006-03-25
00:32:27.000000000 -0800
+++ devel-akpm/net/ipv4/ipmr.c 2006-03-25 00:32:27.000000000 -0800
@@ -641,8 +641,6 @@ ipmr_cache_unresolved(vifi_t vifi, struc
if (atomic_read(&cache_resolve_queue_len)>=10 ||
(c=ipmr_cache_alloc_unres())==NULL) {
spin_unlock_bh(&mfc_unres_lock);
-
- kfree_skb(skb);
return -ENOBUFS;
}
@@ -663,7 +661,6 @@ ipmr_cache_unresolved(vifi_t vifi, struc
spin_unlock_bh(&mfc_unres_lock);
kmem_cache_free(mrt_cachep, c);
- kfree_skb(skb);
return err;
}
@@ -678,7 +675,6 @@ ipmr_cache_unresolved(vifi_t vifi, struc
* See if we can append the packet
*/
if (c->mfc_un.unres.unresolved.qlen>3) {
- kfree_skb(skb);
err = -ENOBUFS;
} else {
skb_queue_tail(&c->mfc_un.unres.unresolved,skb);
@@ -1391,7 +1387,8 @@ int ip_mr_input(struct sk_buff *skb)
if (vif >= 0) {
int err = ipmr_cache_unresolved(vif, skb);
read_unlock(&mrt_lock);
-
+ if (err < 0)
+ kfree_skb(skb);
return err;
}
read_unlock(&mrt_lock);
_
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html