All of lore.kernel.org
 help / color / mirror / Atom feed
From: Cong Wang <xiyou.wangcong@gmail.com>
To: William Liu <will@willsroot.io>
Cc: netdev@vger.kernel.org, jhs@mojatatu.com, victor@mojatatu.com,
	pctammela@mojatatu.com, pabeni@redhat.com, kuba@kernel.org,
	stephen@networkplumber.org, dcaratti@redhat.com,
	savy@syst3mfailure.io, jiri@resnulli.us, davem@davemloft.net,
	edumazet@google.com, horms@kernel.org
Subject: Re: [PATCH net v4 1/2] net/sched: Restrict conditions for adding duplicating netems to qdisc tree
Date: Fri, 27 Jun 2025 17:15:08 -0700	[thread overview]
Message-ID: <aF80DNslZSX7XT3l@pop-os.localdomain> (raw)
In-Reply-To: <20250627061600.56522-1-will@willsroot.io>

On Fri, Jun 27, 2025 at 06:17:31AM +0000, William Liu wrote:
> netem_enqueue's duplication prevention logic breaks when a netem
> resides in a qdisc tree with other netems - this can lead to a
> soft lockup and OOM loop in netem_dequeue, as seen in [1].
> Ensure that a duplicating netem cannot exist in a tree with other
> netems.
>

Thanks for providing more details.

> Previous approaches suggested in discussions in chronological order:
> 
> 1) Track duplication status or ttl in the sk_buff struct. Considered
> too specific a use case to extend such a struct, though this would
> be a resilient fix and address other previous and potential future
> DOS bugs like the one described in loopy fun [2].
> 
> 2) Restrict netem_enqueue recursion depth like in act_mirred with a
> per cpu variable. However, netem_dequeue can call enqueue on its
> child, and the depth restriction could be bypassed if the child is a
> netem.
> 
> 3) Use the same approach as in 2, but add metadata in netem_skb_cb
> to handle the netem_dequeue case and track a packet's involvement
> in duplication. This is an overly complex approach, and Jamal
> notes that the skb cb can be overwritten to circumvent this
> safeguard.

This approach looks most elegant to me since it is per-skb and only
contained for netem. Since netem_skb_cb is shared among qdisc's, what
about just extending qdisc_skb_cb? Something like:

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 638948be4c50..4c5505661986 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -436,6 +436,7 @@ struct qdisc_skb_cb {
                unsigned int            pkt_len;
                u16                     slave_dev_queue_mapping;
                u16                     tc_classid;
+               u32                     reserved;
        };
 #define QDISC_CB_PRIV_LEN 20
        unsigned char           data[QDISC_CB_PRIV_LEN];


Then we just set and check it for duplicated skbs:


diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index fdd79d3ccd8c..4290f8fca0e9 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -486,7 +486,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
         * If we need to duplicate packet, then clone it before
         * original is modified.
         */
-       if (count > 1)
+       if (count > 1 && !qdisc_skb_cb(skb)->reserved)
                skb2 = skb_clone(skb, GFP_ATOMIC);

        /*
@@ -540,9 +540,8 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch,
                struct Qdisc *rootq = qdisc_root_bh(sch);
                u32 dupsave = q->duplicate; /* prevent duplicating a dup... */

-               q->duplicate = 0;
+               qdisc_skb_cb(skb2)->reserved = dupsave;
                rootq->enqueue(skb2, rootq, to_free);
-               q->duplicate = dupsave;
                skb2 = NULL;
        }


Could this work? It looks even shorter than your patch. :-)

Note, I don't even compile test it, I just show it to you for discussion.

Regards,
Cong Wang

  reply	other threads:[~2025-06-28  0:15 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-27  6:17 [PATCH net v4 1/2] net/sched: Restrict conditions for adding duplicating netems to qdisc tree William Liu
2025-06-28  0:15 ` Cong Wang [this message]
2025-06-28  4:23   ` William Liu
2025-06-28 21:25     ` Jamal Hadi Salim
2025-06-29 20:16       ` Cong Wang
2025-06-30 11:32         ` Jamal Hadi Salim
2025-06-30 22:39           ` Cong Wang
2025-07-01 13:36             ` Paolo Abeni
2025-07-01 14:15             ` Jamal Hadi Salim
2025-07-01 17:31               ` Cong Wang
2025-07-01 17:37                 ` William Liu
2025-07-01 19:08                 ` Jamal Hadi Salim
2025-06-28 15:15   ` Stephen Hemminger
2025-06-28 21:15     ` Jamal Hadi Salim
2025-07-01 18:11     ` Eric Dumazet
2025-07-01 18:46       ` William Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aF80DNslZSX7XT3l@pop-os.localdomain \
    --to=xiyou.wangcong@gmail.com \
    --cc=davem@davemloft.net \
    --cc=dcaratti@redhat.com \
    --cc=edumazet@google.com \
    --cc=horms@kernel.org \
    --cc=jhs@mojatatu.com \
    --cc=jiri@resnulli.us \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=pctammela@mojatatu.com \
    --cc=savy@syst3mfailure.io \
    --cc=stephen@networkplumber.org \
    --cc=victor@mojatatu.com \
    --cc=will@willsroot.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.