On Fri, Oct 16, 2020 at 2:10 PM Aleksandr Nogikh <a.nog...@yandex.ru> wrote: > > From: Aleksandr Nogikh <nog...@google.com> > > Currently it is possible to craft a special netlink RTM_NEWQDISC > command that result in jitter being equal to 0x80000000. It is enough > to set 32 bit jitter to 0x02000000 (it will later be multiplied by > 2^6) or set 64 bit jitter via TCA_NETEM_JITTER64. This causes an > overflow during the generation of uniformly districuted numbers in > tabledist, which in turn leads to division by zero (sigma != 0, but > sigma * 2 is 0). > > The related fragment of code needs 32-bit division - see commit > 9b0ed89 ("netem: remove unnecessary 64 bit modulus"), so > switching to 64 bit is not an option. > > Fix the issue by preventing 32 bit integer overflows in > tabledist. Also, instead of truncating s64 integer to s32, truncate it > to u32, as negative standard deviation does not make sense anyway. > > Reported-by: syzbot+ec762a6342ad0d3c0...@syzkaller.appspotmail.com > Signed-off-by: Aleksandr Nogikh <nog...@google.com> > --- > net/sched/sch_netem.c | 15 ++++++++++++--- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c > index 84f82771cdf5..d8b0bf1b5346 100644 > --- a/net/sched/sch_netem.c > +++ b/net/sched/sch_netem.c > @@ -315,7 +315,7 @@ static bool loss_event(struct netem_sched_data *q) > * std deviation sigma. Uses table lookup to approximate the desired > * distribution, and a uniformly-distributed pseudo-random source. > */ > -static s64 tabledist(s64 mu, s32 sigma, > +static s64 tabledist(s64 mu, u32 sigma, > struct crndstate *state, > const struct disttable *dist) > { > @@ -329,8 +329,14 @@ static s64 tabledist(s64 mu, s32 sigma, > rnd = get_crandom(state); > > /* default uniform distribution */ > - if (dist == NULL) > + if (!dist) { > + /* Sigma is too big to perform 32 bit division. > + * Use the widest possible deviation. > + */ > + if ((u64)sigma * 2ULL >= U32_MAX)
Or simply if (sigma >= U32_MAX/2) > + return mu + rnd - U32_MAX / 2; Since only syzbot can possibly use these silly parameters, what about capping the parameters in control path, when netem is setup/changed, instead of adding a test in the fast path ?