net/sched: flower: Ensure both minimum and maximum ports are specified
authorIdo Schimmel <idosch@nvidia.com>
Tue, 11 Jul 2023 07:08:09 +0000 (10:08 +0300)
committerDavid S. Miller <davem@davemloft.net>
Wed, 12 Jul 2023 09:33:06 +0000 (10:33 +0100)
The kernel does not currently validate that both the minimum and maximum
ports of a port range are specified. This can lead user space to think
that a filter matching on a port range was successfully added, when in
fact it was not. For example, with a patched (buggy) iproute2 that only
sends the minimum port, the following commands do not return an error:

 # tc filter add dev swp1 ingress pref 1 proto ip flower ip_proto udp src_port 100-200 action pass

 # tc filter add dev swp1 ingress pref 1 proto ip flower ip_proto udp dst_port 100-200 action pass

 # tc filter show dev swp1 ingress
 filter protocol ip pref 1 flower chain 0
 filter protocol ip pref 1 flower chain 0 handle 0x1
   eth_type ipv4
   ip_proto udp
   not_in_hw
         action order 1: gact action pass
          random type none pass val 0
          index 1 ref 1 bind 1

 filter protocol ip pref 1 flower chain 0 handle 0x2
   eth_type ipv4
   ip_proto udp
   not_in_hw
         action order 1: gact action pass
          random type none pass val 0
          index 2 ref 1 bind 1

Fix by returning an error unless both ports are specified:

 # tc filter add dev swp1 ingress pref 1 proto ip flower ip_proto udp src_port 100-200 action pass
 Error: Both min and max source ports must be specified.
 We have an error talking to the kernel

 # tc filter add dev swp1 ingress pref 1 proto ip flower ip_proto udp dst_port 100-200 action pass
 Error: Both min and max destination ports must be specified.
 We have an error talking to the kernel

Fixes: 5c72299fba9d ("net: sched: cls_flower: Classify packets using port ranges")
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/sched/cls_flower.c

index 56065cc5a6614e1fb9c0aa84be2d295d9bf5975b..f2b0bc4142fe3b5bfc8c2947897c413c52390ed4 100644 (file)
@@ -812,6 +812,16 @@ static int fl_set_key_port_range(struct nlattr **tb, struct fl_flow_key *key,
                       TCA_FLOWER_KEY_PORT_SRC_MAX, &mask->tp_range.tp_max.src,
                       TCA_FLOWER_UNSPEC, sizeof(key->tp_range.tp_max.src));
 
+       if (mask->tp_range.tp_min.dst != mask->tp_range.tp_max.dst) {
+               NL_SET_ERR_MSG(extack,
+                              "Both min and max destination ports must be specified");
+               return -EINVAL;
+       }
+       if (mask->tp_range.tp_min.src != mask->tp_range.tp_max.src) {
+               NL_SET_ERR_MSG(extack,
+                              "Both min and max source ports must be specified");
+               return -EINVAL;
+       }
        if (mask->tp_range.tp_min.dst && mask->tp_range.tp_max.dst &&
            ntohs(key->tp_range.tp_max.dst) <=
            ntohs(key->tp_range.tp_min.dst)) {