diff mbox series

[net] net/sched: flower: Ensure both minimum and maximum ports are specified

Message ID 20230711070809.3706238-1-idosch@nvidia.com (mailing list archive)
State Accepted
Commit d3f87278bcb80bd7f9519669d928b43320363d4f
Delegated to: Netdev Maintainers
Headers show
Series [net] net/sched: flower: Ensure both minimum and maximum ports are specified | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1341 this patch: 1341
netdev/cc_maintainers success CCed 9 of 9 maintainers
netdev/build_clang success Errors and warnings before: 1364 this patch: 1364
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 1364 this patch: 1364
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 16 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Ido Schimmel July 11, 2023, 7:08 a.m. UTC
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>
---
 net/sched/cls_flower.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

Comments

Jamal Hadi Salim July 11, 2023, 9:13 p.m. UTC | #1
On Tue, Jul 11, 2023 at 3:08 AM Ido Schimmel <idosch@nvidia.com> wrote:
>
> 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>

cheers,
jamal
> ---
>  net/sched/cls_flower.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
> index 56065cc5a661..f2b0bc4142fe 100644
> --- a/net/sched/cls_flower.c
> +++ b/net/sched/cls_flower.c
> @@ -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)) {
> --
> 2.40.1
>
patchwork-bot+netdevbpf@kernel.org July 12, 2023, 9:40 a.m. UTC | #2
Hello:

This patch was applied to netdev/net.git (main)
by David S. Miller <davem@davemloft.net>:

On Tue, 11 Jul 2023 10:08:09 +0300 you wrote:
> 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
> 
> [...]

Here is the summary with links:
  - [net] net/sched: flower: Ensure both minimum and maximum ports are specified
    https://git.kernel.org/netdev/net/c/d3f87278bcb8

You are awesome, thank you!
diff mbox series

Patch

diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 56065cc5a661..f2b0bc4142fe 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -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)) {