fq_codel: reject silly quantum parameters
syzbot found that forcing a big quantum attribute would crash hosts fast,
essentially using this:
tc qd replace dev eth0 root fq_codel quantum 4294967295
This is because fq_codel_dequeue() would have to loop
~2^31 times in :
if (flow->deficit <= 0) {
flow->deficit += q->quantum;
list_move_tail(&flow->flowchain, &q->old_flows);
goto begin;
}
SFQ max quantum is 2^19 (half a megabyte)
Lets adopt a max quantum of one megabyte for FQ_CODEL.
Fixes: 4b549a2ef4
("fq_codel: Fair Queue Codel AQM")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
10905b4a68
Коммит
c7c5e6ff53
|
@ -827,6 +827,8 @@ struct tc_codel_xstats {
|
|||
|
||||
/* FQ_CODEL */
|
||||
|
||||
#define FQ_CODEL_QUANTUM_MAX (1 << 20)
|
||||
|
||||
enum {
|
||||
TCA_FQ_CODEL_UNSPEC,
|
||||
TCA_FQ_CODEL_TARGET,
|
||||
|
|
|
@ -369,6 +369,7 @@ static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt,
|
|||
{
|
||||
struct fq_codel_sched_data *q = qdisc_priv(sch);
|
||||
struct nlattr *tb[TCA_FQ_CODEL_MAX + 1];
|
||||
u32 quantum = 0;
|
||||
int err;
|
||||
|
||||
if (!opt)
|
||||
|
@ -386,6 +387,13 @@ static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt,
|
|||
q->flows_cnt > 65536)
|
||||
return -EINVAL;
|
||||
}
|
||||
if (tb[TCA_FQ_CODEL_QUANTUM]) {
|
||||
quantum = max(256U, nla_get_u32(tb[TCA_FQ_CODEL_QUANTUM]));
|
||||
if (quantum > FQ_CODEL_QUANTUM_MAX) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid quantum");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
sch_tree_lock(sch);
|
||||
|
||||
if (tb[TCA_FQ_CODEL_TARGET]) {
|
||||
|
@ -412,8 +420,8 @@ static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt,
|
|||
if (tb[TCA_FQ_CODEL_ECN])
|
||||
q->cparams.ecn = !!nla_get_u32(tb[TCA_FQ_CODEL_ECN]);
|
||||
|
||||
if (tb[TCA_FQ_CODEL_QUANTUM])
|
||||
q->quantum = max(256U, nla_get_u32(tb[TCA_FQ_CODEL_QUANTUM]));
|
||||
if (quantum)
|
||||
q->quantum = quantum;
|
||||
|
||||
if (tb[TCA_FQ_CODEL_DROP_BATCH_SIZE])
|
||||
q->drop_batch_size = max(1U, nla_get_u32(tb[TCA_FQ_CODEL_DROP_BATCH_SIZE]));
|
||||
|
|
Загрузка…
Ссылка в новой задаче