mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-05 19:31:57 -04:00
net/sched: sch_qfq: Fix null-deref in agg_dequeue
commit dd831ac8221e691e9e918585b1003c7071df0379 upstream. To prevent a potential crash in agg_dequeue (net/sched/sch_qfq.c) when cl->qdisc->ops->peek(cl->qdisc) returns NULL, we check the return value before using it, similar to the existing approach in sch_hfsc.c. To avoid code duplication, the following changes are made: 1. Changed qdisc_warn_nonwc(include/net/pkt_sched.h) into a static inline function. 2. Moved qdisc_peek_len from net/sched/sch_hfsc.c to include/net/pkt_sched.h so that sch_qfq can reuse it. 3. Applied qdisc_peek_len in agg_dequeue to avoid crashing. Signed-off-by: Xiang Mei <xmei5@asu.edu> Reviewed-by: Cong Wang <xiyou.wangcong@gmail.com> Link: https://patch.msgid.link/20250705212143.3982664-1-xmei5@asu.edu Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
2e58fc1413
commit
71d84658a6
4 changed files with 25 additions and 28 deletions
|
|
@ -109,7 +109,6 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
|
|||
struct netlink_ext_ack *extack);
|
||||
void qdisc_put_rtab(struct qdisc_rate_table *tab);
|
||||
void qdisc_put_stab(struct qdisc_size_table *tab);
|
||||
void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc);
|
||||
bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
|
||||
struct net_device *dev, struct netdev_queue *txq,
|
||||
spinlock_t *root_lock, bool validate);
|
||||
|
|
@ -176,4 +175,28 @@ struct tc_taprio_qopt_offload *taprio_offload_get(struct tc_taprio_qopt_offload
|
|||
*offload);
|
||||
void taprio_offload_free(struct tc_taprio_qopt_offload *offload);
|
||||
|
||||
static inline void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc)
|
||||
{
|
||||
if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
|
||||
pr_warn("%s: %s qdisc %X: is non-work-conserving?\n",
|
||||
txt, qdisc->ops->id, qdisc->handle >> 16);
|
||||
qdisc->flags |= TCQ_F_WARN_NONWC;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned int qdisc_peek_len(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
unsigned int len;
|
||||
|
||||
skb = sch->ops->peek(sch);
|
||||
if (unlikely(skb == NULL)) {
|
||||
qdisc_warn_nonwc("qdisc_peek_len", sch);
|
||||
return 0;
|
||||
}
|
||||
len = qdisc_pkt_len(skb);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -592,16 +592,6 @@ out:
|
|||
qdisc_skb_cb(skb)->pkt_len = pkt_len;
|
||||
}
|
||||
|
||||
void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc)
|
||||
{
|
||||
if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
|
||||
pr_warn("%s: %s qdisc %X: is non-work-conserving?\n",
|
||||
txt, qdisc->ops->id, qdisc->handle >> 16);
|
||||
qdisc->flags |= TCQ_F_WARN_NONWC;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(qdisc_warn_nonwc);
|
||||
|
||||
static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
|
||||
{
|
||||
struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog,
|
||||
|
|
|
|||
|
|
@ -836,22 +836,6 @@ update_vf(struct hfsc_class *cl, unsigned int len, u64 cur_time)
|
|||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
qdisc_peek_len(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
unsigned int len;
|
||||
|
||||
skb = sch->ops->peek(sch);
|
||||
if (unlikely(skb == NULL)) {
|
||||
qdisc_warn_nonwc("qdisc_peek_len", sch);
|
||||
return 0;
|
||||
}
|
||||
len = qdisc_pkt_len(skb);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void
|
||||
hfsc_adjust_levels(struct hfsc_class *cl)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1003,7 +1003,7 @@ static struct sk_buff *agg_dequeue(struct qfq_aggregate *agg,
|
|||
|
||||
if (cl->qdisc->q.qlen == 0) /* no more packets, remove from list */
|
||||
list_del_init(&cl->alist);
|
||||
else if (cl->deficit < qdisc_pkt_len(cl->qdisc->ops->peek(cl->qdisc))) {
|
||||
else if (cl->deficit < qdisc_peek_len(cl->qdisc)) {
|
||||
cl->deficit += agg->lmax;
|
||||
list_move_tail(&cl->alist, &agg->active);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue