On 02/23/2016 01:49 PM, Jamal Hadi Salim wrote:
From: Jamal Hadi Salim <j...@mojatatu.com>
[...]
+static const struct nla_policy ife_policy[TCA_IFE_MAX + 1] = {
+       [TCA_IFE_PARMS] = {.len = sizeof(struct tc_ife)},
+       [TCA_IFE_DMAC] = {.type = NLA_BINARY,.len = ETH_ALEN},
+       [TCA_IFE_SMAC] = {.type = NLA_BINARY,.len = ETH_ALEN},

This is buggy btw ...

+       [TCA_IFE_TYPE] = {.type = NLA_U16},
+};

[...]

+       if (parm->flags & IFE_ENCODE) {
+               ife_type = *(u16 *) nla_data(tb[TCA_IFE_TYPE]);

( We have accessors for such things. Please also check coding style
  and white space things in your series, there's couple of things all
  over the place. )

+               if (tb[TCA_IFE_DMAC] != NULL)
+                       daddr = nla_data(tb[TCA_IFE_DMAC]);
+               if (tb[TCA_IFE_SMAC] != NULL)
+                       saddr = nla_data(tb[TCA_IFE_SMAC]);

... NLA_BINARY with len means: max length. But there's nothing
that checks a min length on this, so you potentially access out
of bounds since everything <= ETH_ALEN is allowed in your case.

+       }
+
+       spin_lock_bh(&ife->tcf_lock);

Maybe try to make this lockless in the fast path? Otherwise placing
this on ingress / egress (f.e. clsact) doesn't really scale.

+       ife->tcf_action = parm->action;
+
+       if (parm->flags & IFE_ENCODE) {
+               if (daddr)
+                       ether_addr_copy(ife->eth_dst, daddr);
+               else
+                       eth_zero_addr(ife->eth_dst);
+
+               if (saddr)
+                       ether_addr_copy(ife->eth_src, saddr);
+               else
+                       eth_zero_addr(ife->eth_src);
+
+               ife->eth_type = ife_type;
+       }

Reply via email to