sch_cake: Make sure we can write the IP header before changing DSCP bits
authorToke Høiland-Jørgensen <toke@redhat.com>
Thu, 4 Apr 2019 13:01:33 +0000 (15:01 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 4 Apr 2019 17:55:59 +0000 (10:55 -0700)
There is not actually any guarantee that the IP headers are valid before we
access the DSCP bits of the packets. Fix this using the same approach taken
in sch_dsmark.

Reported-by: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/sched/sch_cake.c

index a3b55e1..259d97b 100644 (file)
@@ -1517,16 +1517,27 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free)
 
 static u8 cake_handle_diffserv(struct sk_buff *skb, u16 wash)
 {
+       int wlen = skb_network_offset(skb);
        u8 dscp;
 
        switch (tc_skb_protocol(skb)) {
        case htons(ETH_P_IP):
+               wlen += sizeof(struct iphdr);
+               if (!pskb_may_pull(skb, wlen) ||
+                   skb_try_make_writable(skb, wlen))
+                       return 0;
+
                dscp = ipv4_get_dsfield(ip_hdr(skb)) >> 2;
                if (wash && dscp)
                        ipv4_change_dsfield(ip_hdr(skb), INET_ECN_MASK, 0);
                return dscp;
 
        case htons(ETH_P_IPV6):
+               wlen += sizeof(struct ipv6hdr);
+               if (!pskb_may_pull(skb, wlen) ||
+                   skb_try_make_writable(skb, wlen))
+                       return 0;
+
                dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> 2;
                if (wash && dscp)
                        ipv6_change_dsfield(ipv6_hdr(skb), INET_ECN_MASK, 0);