diff --git a/sys/net/altq/altq_rmclass.c b/sys/net/altq/altq_rmclass.c --- a/sys/net/altq/altq_rmclass.c +++ b/sys/net/altq/altq_rmclass.c @@ -234,6 +234,16 @@ cl->leaf_ = 1; cl->ifdat_ = ifd; cl->pri_ = pri; + /* + * DF-0441: nsecPerByte == 0 would divide-by-zero below. The value + * arrives unchecked from a user-supplied struct pf_altq via + * cbq_opts.ns_per_byte (altq_cbq.c:374). pfctl computes it from + * bandwidth ratios and never yields 0, but a malicious root can + * issue DIOCADDALTQ directly with ns_per_byte = 0 and panic the + * kernel. Clamp to 1 ns/byte (the slowest non-zero rate) instead. + */ + if (nsecPerByte == 0) + nsecPerByte = 1; cl->allotment_ = RM_NS_PER_SEC / nsecPerByte; /* Bytes per sec */ cl->depth_ = 0; cl->qthresh_ = 0; @@ -347,6 +357,13 @@ old_allotment = cl->allotment_; crit_enter(); + /* + * DF-0441: same divide-by-zero guard as rmc_newclass(); see the + * comment there. rmc_modclass() takes the same unchecked user + * nsecPerByte through cbq_modify_queue(). + */ + if (nsecPerByte == 0) + nsecPerByte = 1; cl->allotment_ = RM_NS_PER_SEC / nsecPerByte; /* Bytes per sec */ cl->qthresh_ = 0; cl->ns_per_byte_ = nsecPerByte;