summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-11-24 02:59:07 +0100
committerAdrian Bunk <bunk@stusta.de>2006-11-24 02:59:07 +0100
commita43a6210ce28978607dbbe09979ebd1b2baadb32 (patch)
tree64934ffa54dd4596e8b790fb55d8c34b7358cf63 /net
parent20e121b94529b4880c2ce0bd0b56d1d0c001db63 (diff)
downloadlwn-a43a6210ce28978607dbbe09979ebd1b2baadb32.tar.gz
lwn-a43a6210ce28978607dbbe09979ebd1b2baadb32.zip
[IPX]: Another nonlinear receive fix
Need to check some more cases in IPX receive. If the skb is purely fragments, the IPX header needs to be extracted. The function pskb_may_pull() may in theory invalidate all the pointers in the skb, so references to ipx header must be refreshed. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Adrian Bunk <bunk@stusta.de>
Diffstat (limited to 'net')
-rw-r--r--net/ipx/af_ipx.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 30eaeb2b33a4..fb815541fa21 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1643,14 +1643,17 @@ static int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
goto out;
- ipx = ipx_hdr(skb);
- ipx_pktsize = ntohs(ipx->ipx_pktsize);
+ if (!pskb_may_pull(skb, sizeof(struct ipxhdr)))
+ goto drop;
+
+ ipx_pktsize = ntohs(ipxhdr(skb)->ipx_pktsize);
/* Too small or invalid header? */
if (ipx_pktsize < sizeof(struct ipxhdr) ||
!pskb_may_pull(skb, ipx_pktsize))
goto drop;
+ ipx = ipx_hdr(skb);
if (ipx->ipx_checksum != IPX_NO_CHECKSUM &&
ipx->ipx_checksum != ipx_cksum(ipx, ipx_pktsize))
goto drop;