Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net sched: fix encoding to use real length

Encoding of the metadata was using the padded length as opposed to
the real length of the data which is a bug per specification.
This has not been an issue todate because all metadatum specified
so far has been 32 bit where aligned and data length are the same width.
This also includes a bug fix for validating the length of a u16 field.
But since there is no metadata of size u16 yes we are fine to include it
here.

While at it get rid of magic numbers.

Fixes: ef6980b6becb ("net sched: introduce IFE action")
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jamal Hadi Salim and committed by
David S. Miller
28a10c42 4870e704

+10 -8
+10 -8
net/sched/act_ife.c
··· 53 53 u32 *tlv = (u32 *)(skbdata); 54 54 u16 totlen = nla_total_size(dlen); /*alignment + hdr */ 55 55 char *dptr = (char *)tlv + NLA_HDRLEN; 56 - u32 htlv = attrtype << 16 | totlen; 56 + u32 htlv = attrtype << 16 | dlen; 57 57 58 58 *tlv = htonl(htlv); 59 59 memset(dptr, 0, totlen - NLA_HDRLEN); ··· 135 135 136 136 int ife_validate_meta_u32(void *val, int len) 137 137 { 138 - if (len == 4) 138 + if (len == sizeof(u32)) 139 139 return 0; 140 140 141 141 return -EINVAL; ··· 144 144 145 145 int ife_validate_meta_u16(void *val, int len) 146 146 { 147 - /* length will include padding */ 148 - if (len == NLA_ALIGN(2)) 147 + /* length will not include padding */ 148 + if (len == sizeof(u16)) 149 149 return 0; 150 150 151 151 return -EINVAL; ··· 652 652 u8 *tlvdata = (u8 *)tlv; 653 653 u16 mtype = tlv->type; 654 654 u16 mlen = tlv->len; 655 + u16 alen; 655 656 656 657 mtype = ntohs(mtype); 657 658 mlen = ntohs(mlen); 659 + alen = NLA_ALIGN(mlen); 658 660 659 - if (find_decode_metaid(skb, ife, mtype, (mlen - 4), 660 - (void *)(tlvdata + 4))) { 661 + if (find_decode_metaid(skb, ife, mtype, (mlen - NLA_HDRLEN), 662 + (void *)(tlvdata + NLA_HDRLEN))) { 661 663 /* abuse overlimits to count when we receive metadata 662 664 * but dont have an ops for it 663 665 */ ··· 668 666 ife->tcf_qstats.overlimits++; 669 667 } 670 668 671 - tlvdata += mlen; 672 - ifehdrln -= mlen; 669 + tlvdata += alen; 670 + ifehdrln -= alen; 673 671 tlv = (struct meta_tlvhdr *)tlvdata; 674 672 } 675 673