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 <jian...@mellanox.com>
Reported-by: Zahari Doychev <zahari.doyc...@intel.com>
---
 net/sched/cls_flower.c | 48 ++++++++++++++++++++++++++----------------------
 1 file changed, 26 insertions(+), 22 deletions(-)

diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 8fda5fa..6712e44 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -590,20 +590,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;
@@ -1288,14 +1290,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) ||
-- 
2.9.5

Reply via email to