summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-11-02 22:53:44 +0100
committerAdrian Bunk <bunk@kernel.org>2007-11-02 22:53:44 +0100
commit4c94bf7f6f414af1ac449d3d6741522311b1fc07 (patch)
tree763a98821515ea22205a5944e816821f8bc3c7f9 /net
parent2ba6064c00a38885e8997059908f9aed5299e196 (diff)
[SNAP]: Check packet length before reading
The snap_rcv code reads 5 bytes so we should make sure that we have 5 bytes in the head before proceeding. Based on diagnosis and fix by Evgeniy Polyakov, reported by Alan J. Wylie. Patch also kills the skb->sk assignment before kfree_skb since it's redundant. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Adrian Bunk <bunk@kernel.org>
Diffstat (limited to 'net')
-rw-r--r--net/802/psnap.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/net/802/psnap.c b/net/802/psnap.c
index 34e42968b477..b920aa206666 100644
--- a/net/802/psnap.c
+++ b/net/802/psnap.c
@@ -55,6 +55,9 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
.type = __constant_htons(ETH_P_SNAP),
};
+ if (unlikely(!pskb_may_pull(skb, 5)))
+ goto drop;
+
rcu_read_lock();
proto = find_snap_client(skb->h.raw);
if (proto) {
@@ -64,14 +67,18 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
skb_pull(skb, 5);
skb_postpull_rcsum(skb, hdr, 5);
rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
- } else {
- skb->sk = NULL;
- kfree_skb(skb);
- rc = 1;
}
-
rcu_read_unlock();
+
+ if (unlikely(!proto))
+ goto drop;
+
+out:
return rc;
+
+drop:
+ kfree_skb(skb);
+ goto out;
}
/*