Message ID | 1233910824.21135.6.camel@localhost.localdomain |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
From: Jesper Dangaard Brouer <jdb@comx.dk> Date: Fri, 06 Feb 2009 10:00:24 +0100 > On Thu, 2009-02-05 at 15:06 -0800, David Miller wrote: > > 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. > > > > Excellent work! > > Thanks :-) > > I'm wondering if the ip_hdr() pointer can be changed by the > pskb_may_pull(), but I assume it cannot as it should already be in the > linear area... right? > > Well the patch below, shows what I mean... It has the same potential problem, but in this case you'd only see corruption if the old skb->data buffer were reallocated by another user and written into very quickly (or poison'd by SLAB debugging). Please respin this patch of your's with proper commit message and signoffs, thanks! BTW, ipv6 udp gets all of this right :-) -- 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
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index cc3a0a0..7390af6 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1232,20 +1232,23 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable, { struct sock *sk; struct udphdr *uh; unsigned short ulen; struct rtable *rt = (struct rtable*)skb->dst; - __be32 saddr = ip_hdr(skb)->saddr; - __be32 daddr = ip_hdr(skb)->daddr; + __be32 saddr; + __be32 daddr; struct net *net = dev_net(skb->dev); /* * Validate the packet. */ if (!pskb_may_pull(skb, sizeof(struct udphdr))) goto drop; /* No space for header. */ + saddr = ip_hdr(skb)->saddr; + daddr = ip_hdr(skb)->daddr; + uh = udp_hdr(skb); ulen = ntohs(uh->len); if (ulen > skb->len) goto short_packet;