diff mbox series

[net,v3,2/2] net/sched: act_mirred: don't override retval if we already lost the skb

Message ID 20240215143346.1715054-2-kuba@kernel.org (mailing list archive)
State Accepted
Commit 166c2c8a6a4dc2e4ceba9e10cfe81c3e469e3210
Delegated to: Netdev Maintainers
Headers show
Series [net,v3,1/2] net/sched: act_mirred: use the backlog for mirred ingress | 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/ynl success Generated files up to date; no warnings/errors; no diff in generated;
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: 976 this patch: 976
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 7 of 7 maintainers
netdev/build_clang success Errors and warnings before: 993 this patch: 993
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: 993 this patch: 993
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 43 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-02-16--06-00 (tests: 1443)

Commit Message

Jakub Kicinski Feb. 15, 2024, 2:33 p.m. UTC
If we're redirecting the skb, and haven't called tcf_mirred_forward(),
yet, we need to tell the core to drop the skb by setting the retcode
to SHOT. If we have called tcf_mirred_forward(), however, the skb
is out of our hands and returning SHOT will lead to UaF.

Move the retval override to the error path which actually need it.

Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Fixes: e5cf1baf92cb ("act_mirred: use TC_ACT_REINSERT when possible")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
CC: jhs@mojatatu.com
CC: xiyou.wangcong@gmail.com
CC: jiri@resnulli.us
---
 net/sched/act_mirred.c | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

Comments

Jamal Hadi Salim Feb. 15, 2024, 5:33 p.m. UTC | #1
On Thu, Feb 15, 2024 at 9:33 AM Jakub Kicinski <kuba@kernel.org> wrote:
>
> If we're redirecting the skb, and haven't called tcf_mirred_forward(),
> yet, we need to tell the core to drop the skb by setting the retcode
> to SHOT. If we have called tcf_mirred_forward(), however, the skb
> is out of our hands and returning SHOT will lead to UaF.
>
> Move the retval override to the error path which actually need it.
>
> Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
> Fixes: e5cf1baf92cb ("act_mirred: use TC_ACT_REINSERT when possible")
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>


cheers,
jamal

> ---
> CC: jhs@mojatatu.com
> CC: xiyou.wangcong@gmail.com
> CC: jiri@resnulli.us
> ---
>  net/sched/act_mirred.c | 22 ++++++++++------------
>  1 file changed, 10 insertions(+), 12 deletions(-)
>
> diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
> index 291d47c9eb69..6faa7d00da09 100644
> --- a/net/sched/act_mirred.c
> +++ b/net/sched/act_mirred.c
> @@ -266,8 +266,7 @@ static int tcf_mirred_to_dev(struct sk_buff *skb, struct tcf_mirred *m,
>         if (unlikely(!(dev->flags & IFF_UP)) || !netif_carrier_ok(dev)) {
>                 net_notice_ratelimited("tc mirred to Houston: device %s is down\n",
>                                        dev->name);
> -               err = -ENODEV;
> -               goto out;
> +               goto err_cant_do;
>         }
>
>         /* we could easily avoid the clone only if called by ingress and clsact;
> @@ -279,10 +278,8 @@ static int tcf_mirred_to_dev(struct sk_buff *skb, struct tcf_mirred *m,
>                 tcf_mirred_can_reinsert(retval);
>         if (!dont_clone) {
>                 skb_to_send = skb_clone(skb, GFP_ATOMIC);
> -               if (!skb_to_send) {
> -                       err =  -ENOMEM;
> -                       goto out;
> -               }
> +               if (!skb_to_send)
> +                       goto err_cant_do;
>         }
>
>         want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
> @@ -319,15 +316,16 @@ static int tcf_mirred_to_dev(struct sk_buff *skb, struct tcf_mirred *m,
>         } else {
>                 err = tcf_mirred_forward(at_ingress, want_ingress, skb_to_send);
>         }
> -
> -       if (err) {
> -out:
> +       if (err)
>                 tcf_action_inc_overlimit_qstats(&m->common);
> -               if (is_redirect)
> -                       retval = TC_ACT_SHOT;
> -       }
>
>         return retval;
> +
> +err_cant_do:
> +       if (is_redirect)
> +               retval = TC_ACT_SHOT;
> +       tcf_action_inc_overlimit_qstats(&m->common);
> +       return retval;
>  }
>
>  static int tcf_blockcast_redir(struct sk_buff *skb, struct tcf_mirred *m,
> --
> 2.43.0
>
diff mbox series

Patch

diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index 291d47c9eb69..6faa7d00da09 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -266,8 +266,7 @@  static int tcf_mirred_to_dev(struct sk_buff *skb, struct tcf_mirred *m,
 	if (unlikely(!(dev->flags & IFF_UP)) || !netif_carrier_ok(dev)) {
 		net_notice_ratelimited("tc mirred to Houston: device %s is down\n",
 				       dev->name);
-		err = -ENODEV;
-		goto out;
+		goto err_cant_do;
 	}
 
 	/* we could easily avoid the clone only if called by ingress and clsact;
@@ -279,10 +278,8 @@  static int tcf_mirred_to_dev(struct sk_buff *skb, struct tcf_mirred *m,
 		tcf_mirred_can_reinsert(retval);
 	if (!dont_clone) {
 		skb_to_send = skb_clone(skb, GFP_ATOMIC);
-		if (!skb_to_send) {
-			err =  -ENOMEM;
-			goto out;
-		}
+		if (!skb_to_send)
+			goto err_cant_do;
 	}
 
 	want_ingress = tcf_mirred_act_wants_ingress(m_eaction);
@@ -319,15 +316,16 @@  static int tcf_mirred_to_dev(struct sk_buff *skb, struct tcf_mirred *m,
 	} else {
 		err = tcf_mirred_forward(at_ingress, want_ingress, skb_to_send);
 	}
-
-	if (err) {
-out:
+	if (err)
 		tcf_action_inc_overlimit_qstats(&m->common);
-		if (is_redirect)
-			retval = TC_ACT_SHOT;
-	}
 
 	return retval;
+
+err_cant_do:
+	if (is_redirect)
+		retval = TC_ACT_SHOT;
+	tcf_action_inc_overlimit_qstats(&m->common);
+	return retval;
 }
 
 static int tcf_blockcast_redir(struct sk_buff *skb, struct tcf_mirred *m,