summaryrefslogtreecommitdiffstats
path: root/net/sched/cls_flower.c
diff options
context:
space:
mode:
authorJianbo Liu2018-07-09 04:26:20 +0200
committerDavid S. Miller2018-07-12 07:48:13 +0200
commit5e9a0fe492f89ff1c7583ee6ea89dc37b8c2e5c2 (patch)
tree83330d5b0d83102a537bbbff24a825748dcf5c5a /net/sched/cls_flower.c
parentselftests: forwarding: mirror_lib: Tighten up VLAN capture (diff)
downloadkernel-qcow2-linux-5e9a0fe492f89ff1c7583ee6ea89dc37b8c2e5c2.tar.gz
kernel-qcow2-linux-5e9a0fe492f89ff1c7583ee6ea89dc37b8c2e5c2.tar.xz
kernel-qcow2-linux-5e9a0fe492f89ff1c7583ee6ea89dc37b8c2e5c2.zip
net/sched: flower: Fix null pointer dereference when run tc vlan command
Zahari issued tc vlan command without setting vlan_ethtype, which will crash kernel. To avoid this, we must check tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE] is not null before use it. Also we don't need to dump vlan_ethtype or cvlan_ethtype in this case. Fixes: d64efd0926ba ('net/sched: flower: Add supprt for matching on QinQ vlan headers') Signed-off-by: Jianbo Liu <jianbol@mellanox.com> Reported-by: Zahari Doychev <zahari.doychev@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/cls_flower.c')
-rw-r--r--net/sched/cls_flower.c48
1 files changed, 26 insertions, 22 deletions
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 487a152a852c..8b2474293db1 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -605,20 +605,22 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
TCA_FLOWER_KEY_VLAN_PRIO, &key->vlan,
&mask->vlan);
- ethertype = nla_get_be16(tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]);
- if (eth_type_vlan(ethertype)) {
- fl_set_key_vlan(tb, ethertype,
- TCA_FLOWER_KEY_CVLAN_ID,
- TCA_FLOWER_KEY_CVLAN_PRIO,
- &key->cvlan, &mask->cvlan);
- fl_set_key_val(tb, &key->basic.n_proto,
- TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
- &mask->basic.n_proto,
- TCA_FLOWER_UNSPEC,
- sizeof(key->basic.n_proto));
- } else {
- key->basic.n_proto = ethertype;
- mask->basic.n_proto = cpu_to_be16(~0);
+ if (tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]) {
+ ethertype = nla_get_be16(tb[TCA_FLOWER_KEY_VLAN_ETH_TYPE]);
+ if (eth_type_vlan(ethertype)) {
+ fl_set_key_vlan(tb, ethertype,
+ TCA_FLOWER_KEY_CVLAN_ID,
+ TCA_FLOWER_KEY_CVLAN_PRIO,
+ &key->cvlan, &mask->cvlan);
+ fl_set_key_val(tb, &key->basic.n_proto,
+ TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
+ &mask->basic.n_proto,
+ TCA_FLOWER_UNSPEC,
+ sizeof(key->basic.n_proto));
+ } else {
+ key->basic.n_proto = ethertype;
+ mask->basic.n_proto = cpu_to_be16(~0);
+ }
}
} else {
key->basic.n_proto = ethertype;
@@ -1344,14 +1346,16 @@ static int fl_dump(struct net *net, struct tcf_proto *tp, void *fh,
key->cvlan.vlan_tpid)))
goto nla_put_failure;
- if (mask->cvlan.vlan_tpid) {
- if (nla_put_be16(skb, TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
- key->basic.n_proto))
- goto nla_put_failure;
- } else if (mask->vlan.vlan_tpid) {
- if (nla_put_be16(skb, TCA_FLOWER_KEY_VLAN_ETH_TYPE,
- key->basic.n_proto))
- goto nla_put_failure;
+ if (mask->basic.n_proto) {
+ if (mask->cvlan.vlan_tpid) {
+ if (nla_put_be16(skb, TCA_FLOWER_KEY_CVLAN_ETH_TYPE,
+ key->basic.n_proto))
+ goto nla_put_failure;
+ } else if (mask->vlan.vlan_tpid) {
+ if (nla_put_be16(skb, TCA_FLOWER_KEY_VLAN_ETH_TYPE,
+ key->basic.n_proto))
+ goto nla_put_failure;
+ }
}
if ((key->basic.n_proto == htons(ETH_P_IP) ||