Skip to content

Commit e38cf36

Browse files
committed
Merge branch 'qdisc-null-deref'
Zhengchao Shao says: ==================== net: fix null pointer access issue in qdisc These three patches fix the same type of problem. Set the default qdisc, and then construct an init failure scenario when the dev qdisc is configured on mqprio to trigger the reset process. NULL pointer access may occur during the reset process. --- v2: for fq_codel, revert the patch --- ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 7b55c2e + 2a3fc78 commit e38cf36

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

net/sched/sch_cake.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,8 +2224,12 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch)
22242224

22252225
static void cake_reset(struct Qdisc *sch)
22262226
{
2227+
struct cake_sched_data *q = qdisc_priv(sch);
22272228
u32 c;
22282229

2230+
if (!q->tins)
2231+
return;
2232+
22292233
for (c = 0; c < CAKE_MAX_TINS; c++)
22302234
cake_clear_tin(sch, c);
22312235
}

net/sched/sch_fq_codel.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -478,24 +478,26 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt,
478478
if (opt) {
479479
err = fq_codel_change(sch, opt, extack);
480480
if (err)
481-
return err;
481+
goto init_failure;
482482
}
483483

484484
err = tcf_block_get(&q->block, &q->filter_list, sch, extack);
485485
if (err)
486-
return err;
486+
goto init_failure;
487487

488488
if (!q->flows) {
489489
q->flows = kvcalloc(q->flows_cnt,
490490
sizeof(struct fq_codel_flow),
491491
GFP_KERNEL);
492-
if (!q->flows)
493-
return -ENOMEM;
494-
492+
if (!q->flows) {
493+
err = -ENOMEM;
494+
goto init_failure;
495+
}
495496
q->backlogs = kvcalloc(q->flows_cnt, sizeof(u32), GFP_KERNEL);
496-
if (!q->backlogs)
497-
return -ENOMEM;
498-
497+
if (!q->backlogs) {
498+
err = -ENOMEM;
499+
goto alloc_failure;
500+
}
499501
for (i = 0; i < q->flows_cnt; i++) {
500502
struct fq_codel_flow *flow = q->flows + i;
501503

@@ -508,6 +510,13 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt,
508510
else
509511
sch->flags &= ~TCQ_F_CAN_BYPASS;
510512
return 0;
513+
514+
alloc_failure:
515+
kvfree(q->flows);
516+
q->flows = NULL;
517+
init_failure:
518+
q->flows_cnt = 0;
519+
return err;
511520
}
512521

513522
static int fq_codel_dump(struct Qdisc *sch, struct sk_buff *skb)

net/sched/sch_sfb.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,8 @@ static void sfb_reset(struct Qdisc *sch)
455455
{
456456
struct sfb_sched_data *q = qdisc_priv(sch);
457457

458-
qdisc_reset(q->qdisc);
458+
if (likely(q->qdisc))
459+
qdisc_reset(q->qdisc);
459460
q->slot = 0;
460461
q->double_buffering = false;
461462
sfb_zero_all_buckets(q);

0 commit comments

Comments
 (0)