diff options
author | Eric Dumazet <edumazet@google.com> | 2013-12-11 11:10:05 -0500 |
---|---|---|
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, | |||
1909 | 1909 | ||
1910 | void udp_v4_early_demux(struct sk_buff *skb) | 1910 | void udp_v4_early_demux(struct sk_buff *skb) |
1911 | { | 1911 | { |
1912 | const struct iphdr *iph = ip_hdr(skb); | 1912 | struct net *net = dev_net(skb->dev); |
1913 | const struct udphdr *uh = udp_hdr(skb); | 1913 | const struct iphdr *iph; |
1914 | const struct udphdr *uh; | ||
1914 | struct sock *sk; | 1915 | struct sock *sk; |
1915 | struct dst_entry *dst; | 1916 | struct dst_entry *dst; |
1916 | struct net *net = dev_net(skb->dev); | ||
1917 | int dif = skb->dev->ifindex; | 1917 | int dif = skb->dev->ifindex; |
1918 | 1918 | ||
1919 | /* validate the packet */ | 1919 | /* validate the packet */ |
1920 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) | 1920 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct udphdr))) |
1921 | return; | 1921 | return; |
1922 | 1922 | ||
1923 | iph = ip_hdr(skb); | ||
1924 | uh = udp_hdr(skb); | ||
1925 | |||
1923 | if (skb->pkt_type == PACKET_BROADCAST || | 1926 | if (skb->pkt_type == PACKET_BROADCAST || |
1924 | skb->pkt_type == PACKET_MULTICAST) | 1927 | skb->pkt_type == PACKET_MULTICAST) |
1925 | sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, | 1928 | sk = __udp4_lib_mcast_demux_lookup(net, uh->dest, iph->daddr, |