Skip to content

Commit 52f2ba5

Browse files
committed
Merge: net/sched: Fix mirred deadlock on device recursion
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/4264 JIRA: https://issues.redhat.com/browse/RHEL-35058 CVE: CVE-2024-27010 Upstream Status: all mainline in net.git Depends: !4235 Conflicts: None Tested: boot-tested only Signed-off-by: Davide Caratti <dcaratti@redhat.com> Approved-by: Florian Westphal <fwestpha@redhat.com> Approved-by: Xin Long <lxin@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Lucas Zampieri <lzampier@redhat.com>
2 parents efb7615 + a2f7144 commit 52f2ba5

File tree

3 files changed

+9
-0
lines changed

3 files changed

+9
-0
lines changed

include/net/sch_generic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ struct Qdisc {
117117
struct qdisc_skb_head q;
118118
struct gnet_stats_basic_sync bstats;
119119
struct gnet_stats_queue qstats;
120+
int owner;
120121
unsigned long state;
121122
unsigned long state2; /* must be written under qdisc spinlock */
122123
struct Qdisc *next_sched;

net/core/dev.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3770,6 +3770,10 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
37703770
return rc;
37713771
}
37723772

3773+
if (unlikely(READ_ONCE(q->owner) == smp_processor_id())) {
3774+
kfree_skb_reason(skb, SKB_DROP_REASON_TC_RECLASSIFY_LOOP);
3775+
return NET_XMIT_DROP;
3776+
}
37733777
/*
37743778
* Heuristic to force contended enqueues to serialize on a
37753779
* separate lock before trying to get qdisc main lock.
@@ -3805,7 +3809,9 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
38053809
qdisc_run_end(q);
38063810
rc = NET_XMIT_SUCCESS;
38073811
} else {
3812+
WRITE_ONCE(q->owner, smp_processor_id());
38083813
rc = dev_qdisc_enqueue(skb, q, &to_free, txq);
3814+
WRITE_ONCE(q->owner, -1);
38093815
if (qdisc_run_begin(q)) {
38103816
if (unlikely(contended)) {
38113817
spin_unlock(&q->busylock);

net/sched/sch_generic.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,7 @@ struct Qdisc noop_qdisc = {
672672
.qlen = 0,
673673
.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.skb_bad_txq.lock),
674674
},
675+
.owner = -1,
675676
};
676677
EXPORT_SYMBOL(noop_qdisc);
677678

@@ -975,6 +976,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
975976
sch->enqueue = ops->enqueue;
976977
sch->dequeue = ops->dequeue;
977978
sch->dev_queue = dev_queue;
979+
sch->owner = -1;
978980
netdev_hold(dev, &sch->dev_tracker, GFP_KERNEL);
979981
refcount_set(&sch->refcnt, 1);
980982

0 commit comments

Comments
 (0)