diff options
| author | Eric Dumazet <edumazet@google.com> | 2013-12-11 08:10:05 -0800 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2013-12-11 16:10:14 -0500 | 
| commit | 610438b74496b2986a9025f8e23c134cb638e338 (patch) | |
| tree | a04eec671093bb727ba8aacb8da6a289e6b77f45 | |
| parent | ce232ce01d61b184202bb185103d119820e1260c (diff) | |
udp: ipv4: fix potential use after free in udp_v4_early_demux()
pskb_may_pull() can reallocate skb->head, we need to move the
initialization of iph and uh pointers after its call.
Fixes: 421b3885bf6d ("udp: ipv4: Add udp early demux")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Shawn Bohrer <sbohrer@rgmadvisors.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/ipv4/udp.c | 9 | 
1 files changed, 6 insertions, 3 deletions
| diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 2e2aecbe22c4..16d246a51a02 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1909,17 +1909,20 @@ static struct sock *__udp4_lib_demux_lookup(struct net *net,  void udp_v4_early_demux(struct sk_buff *skb)  { -	const struct iphdr *iph = ip_hdr(skb); -	const struct udphdr *uh = udp_hdr(skb); +	struct net *net = dev_net(skb->dev); +	const struct iphdr *iph; +	const struct udphdr *uh;  	struct sock *sk;  	struct dst_entry *dst; -	struct net *net = dev_net(skb->dev);  	int dif = skb->dev->ifindex;  	/* validate the packet */  	if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr)))  		return; +	iph = ip_hdr(skb); +	uh = udp_hdr(skb); +  	if (skb->pkt_type == PACKET_BROADCAST ||  	    skb->pkt_type == PACKET_MULTICAST)  		sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, | 
