sch_sfq: add sanity check for the packet length
Subsystems (3)
PATCH 1/1 sch_sfq: add sanity check for the packet length
The packet length should be checked before the packet data is dereferenced.
Signed-off-by Changli Gao <[email protected]>
--- net/sched/sch_sfq.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-)
net/sched/sch_sfq.c +22 -9
@@ -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_may_pull (skb,skb_network_offset (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)) &&
@@ -131,25 +135,34 @@ 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_may_pull (skb,skb_network_offset (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_may_pull (skb,skb_network_offset (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_may_pull (skb,skb_network_offset (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; }