Patchwork Fix UDP short packet false positive

login
register
mail settings
Submitter Jesper Dangaard Brouer
Date Feb. 5, 2009, 12:47 p.m.
Message ID <1233838027.20497.132.camel@localhost.localdomain>
Download mbox | patch
Permalink /patch/22109/
State Accepted
Delegated to: David Miller
Headers show

Comments

Jesper Dangaard Brouer - Feb. 5, 2009, 12:47 p.m.
The UDP header pointer assignment must happen after calling
pskb_may_pull().  As pskb_may_pull() can potentially alter the SKB
buffer.

This was exposted by running multicast traffic through the NIU driver,
as it won't prepull the protocol headers into the linear area on
receive.

Signed-off-by: Jesper Dangaard Brouer <hawk@comx.dk>
---

 net/ipv4/udp.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)



--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller - Feb. 5, 2009, 11:06 p.m.
From: Jesper Dangaard Brouer <jdb@comx.dk>
Date: Thu, 05 Feb 2009 13:47:07 +0100

> 
> The UDP header pointer assignment must happen after calling
> pskb_may_pull().  As pskb_may_pull() can potentially alter the SKB
> buffer.
> 
> This was exposted by running multicast traffic through the NIU driver,
> as it won't prepull the protocol headers into the linear area on
> receive.
> 
> Signed-off-by: Jesper Dangaard Brouer <hawk@comx.dk>

Excellent work!

Applied and queued up for -stable, thanks!
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 1ab180b..cc3a0a0 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1231,7 +1231,7 @@  int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 		   int proto)
 {
 	struct sock *sk;
-	struct udphdr *uh = udp_hdr(skb);
+	struct udphdr *uh;
 	unsigned short ulen;
 	struct rtable *rt = (struct rtable*)skb->dst;
 	__be32 saddr = ip_hdr(skb)->saddr;
@@ -1244,6 +1244,7 @@  int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
 	if (!pskb_may_pull(skb, sizeof(struct udphdr)))
 		goto drop;		/* No space for header. */
 
+	uh   = udp_hdr(skb);
 	ulen = ntohs(uh->len);
 	if (ulen > skb->len)
 		goto short_packet;