Skip to content

Commit

Permalink
sch_sfq: add sanity check for the packet length
Browse files Browse the repository at this point in the history
The packet length should be checked before the packet data is dereferenced.

Signed-off-by: Changli Gao <xiaosuo@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Changli Gao authored and David S. Miller committed Aug 5, 2010
1 parent 12dc96d commit f2f0098
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions net/sched/sch_sfq.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,11 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
switch (skb->protocol) {
case htons(ETH_P_IP):
{
const struct iphdr *iph = ip_hdr(skb);
const struct iphdr *iph;

if (!pskb_network_may_pull(skb, sizeof(*iph)))
goto err;
iph = ip_hdr(skb);
h = (__force u32)iph->daddr;
h2 = (__force u32)iph->saddr ^ iph->protocol;
if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
Expand All @@ -131,25 +135,32 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
iph->protocol == IPPROTO_UDPLITE ||
iph->protocol == IPPROTO_SCTP ||
iph->protocol == IPPROTO_DCCP ||
iph->protocol == IPPROTO_ESP))
iph->protocol == IPPROTO_ESP) &&
pskb_network_may_pull(skb, iph->ihl * 4 + 4))
h2 ^= *(((u32*)iph) + iph->ihl);
break;
}
case htons(ETH_P_IPV6):
{
struct ipv6hdr *iph = ipv6_hdr(skb);
struct ipv6hdr *iph;

if (!pskb_network_may_pull(skb, sizeof(*iph)))
goto err;
iph = ipv6_hdr(skb);
h = (__force u32)iph->daddr.s6_addr32[3];
h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr;
if (iph->nexthdr == IPPROTO_TCP ||
iph->nexthdr == IPPROTO_UDP ||
iph->nexthdr == IPPROTO_UDPLITE ||
iph->nexthdr == IPPROTO_SCTP ||
iph->nexthdr == IPPROTO_DCCP ||
iph->nexthdr == IPPROTO_ESP)
if ((iph->nexthdr == IPPROTO_TCP ||
iph->nexthdr == IPPROTO_UDP ||
iph->nexthdr == IPPROTO_UDPLITE ||
iph->nexthdr == IPPROTO_SCTP ||
iph->nexthdr == IPPROTO_DCCP ||
iph->nexthdr == IPPROTO_ESP) &&
pskb_network_may_pull(skb, sizeof(*iph) + 4))
h2 ^= *(u32*)&iph[1];
break;
}
default:
err:
h = (unsigned long)skb_dst(skb) ^ (__force u32)skb->protocol;
h2 = (unsigned long)skb->sk;
}
Expand Down

0 comments on commit f2f0098

Please sign in to comment.