[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220913140354.324932928@linuxfoundation.org>
Date: Tue, 13 Sep 2022 16:05:48 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org,
Toke Høiland-Jørgensen <toke@...e.dk>,
Jakub Kicinski <kuba@...nel.org>,
Sasha Levin <sashal@...nel.org>, zdi-disclosures@...ndmicro.com
Subject: [PATCH 5.4 017/108] sch_cake: Return __NET_XMIT_STOLEN when consuming enqueued skb
From: Toke Høiland-Jørgensen <toke@...e.dk>
[ Upstream commit 90fabae8a2c225c4e4936723c38857887edde5cc ]
When the GSO splitting feature of sch_cake is enabled, GSO superpackets
will be broken up and the resulting segments enqueued in place of the
original skb. In this case, CAKE calls consume_skb() on the original skb,
but still returns NET_XMIT_SUCCESS. This can confuse parent qdiscs into
assuming the original skb still exists, when it really has been freed. Fix
this by adding the __NET_XMIT_STOLEN flag to the return value in this case.
Fixes: 0c850344d388 ("sch_cake: Conditionally split GSO segments")
Signed-off-by: Toke Høiland-Jørgensen <toke@...e.dk>
Reported-by: zdi-disclosures@...ndmicro.com # ZDI-CAN-18231
Link: https://lore.kernel.org/r/20220831092103.442868-1-toke@toke.dk
Signed-off-by: Jakub Kicinski <kuba@...nel.org>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---
net/sched/sch_cake.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c
index 0eb4d4a568f77..737368c701c53 100644
--- a/net/sched/sch_cake.c
+++ b/net/sched/sch_cake.c
@@ -1677,6 +1677,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
}
idx--;
flow = &b->flows[idx];
+ ret = NET_XMIT_SUCCESS;
/* ensure shaper state isn't stale */
if (!b->tin_backlog) {
@@ -1737,6 +1738,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
qdisc_tree_reduce_backlog(sch, 1-numsegs, len-slen);
consume_skb(skb);
+ ret |= __NET_XMIT_STOLEN;
} else {
/* not splitting */
cobalt_set_enqueue_time(skb, now);
@@ -1870,7 +1872,7 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch,
}
b->drop_overlimit += dropped;
}
- return NET_XMIT_SUCCESS;
+ return ret;
}
static struct sk_buff *cake_dequeue_one(struct Qdisc *sch)
--
2.35.1
Powered by blists - more mailing lists