Is this patch correct? http://netbsd.org/~kamil/patch-00168-kern_rndq.c-avoid-overflow.txt This code will map the corner case into defined semantics, treating delta INT32_MIN as INT32_MIN+1. This panic was already triggered 7 times on syzbot. On 23.09.2019 10:56, Kamil Rytarowski wrote: > Truncating and resending to tech-kern@ as this message was dropped, as > too long. > > On 23.09.2019 10:19, Kamil Rytarowski wrote: >> kern_rndq.c has a special corner case triggered by the fuzzer (1 hit in >> 2**32 attempts?). >> >> 393 /* >> 394 * Delta estimator for 32 or bit values. "Wrap" isn't. >> 395 */ >> 396 static inline uint32_t >> 397 rnd_dv_estimate(krndsource_t *rs, uint32_t v) >> 398 { >> 399 int32_t delta; >> 400 uint32_t ret; >> 401 rnd_delta_t *d = &rs->value_delta; >> 402 >> 403 delta = d->x - v; >> 404 >> >> delta can be here INT32_MIN. >> >> >> 405 if (delta < 0) { >> 406 delta = -delta; >> >> -INT32_MIN is UB and returns -INT32_MIN on currently supported CPUs. >> >> But this behavior is unspecified and should be avoided. This triggered >> the kUBSan panic on the bot.... however: >> >> 407 } >> 408 ret = rnd_delta_estimate(d, v, (uint32_t)delta); >> >> d->dx is assigned (uint32_t)delta to INT32_MAX+1 >> >> 409 >> 410 KASSERT(d->x == v); >> 411 KASSERT(d->dx == delta); >> >> d->dx is INT32_MAX (0x80000000) and as far as I can see we would trigger >> a panic for this corner-case anyway as this KASSERT(9) will fire for >> comparing 0x80000000 with 0xffffffff80000000 (promotion rules). >> >> https://nxr.netbsd.org/xref/src/sys/kern/kern_rndq.c#397 >> >> There is a similar code in rnd_dt_estimate() that probably should be >> handled, at least for paranoid reasons. >> >> 359 /* >> 360 * Delta estimator for 32-bit timeestamps. Must handle wrap. >> 361 */ >> 362 static inline uint32_t >> 363 rnd_dt_estimate(krndsource_t *rs, uint32_t t) >> 364 { >> 365 int32_t delta; >> 366 uint32_t ret; >> 367 rnd_delta_t *d = &rs->time_delta; >> 368 >> 369 if (t < d->x) { >> 370 delta = UINT32_MAX - d->x + t; >> 371 } else { >> 372 delta = d->x - t; >> 373 } >> 374 >> 375 if (delta < 0) { >> 376 delta = -delta; >> 377 } >> 378 >> 379 ret = rnd_delta_estimate(d, t, delta); >> 380 >> 381 KASSERT(d->x == t); >> 382 KASSERT(d->dx == delta); >> >> https://nxr.netbsd.org/xref/src/sys/kern/kern_rndq.c#363 >> >> >> On 22.09.2019 07:14, syzbot wrote: >>> Hello, >>> >>> syzbot found the following crash on: >>> >>> HEAD commit: 147eb8ed improve description >>> git tree: netbsd >>> console output: https://syzkaller.appspot.com/x/log.txt?x=17c2b555600000 >>> kernel config: https://syzkaller.appspot.com/x/.config?x=824b23e1f4b6c76b >>> dashboard link: >>> https://syzkaller.appspot.com/bug?extid=68c37d09c833f8ec1341 >>> >>> Unfortunately, I don't have any reproducer for this crash yet. >>> >>> IMPORTANT: if you fix the bug, please add the following tag to the commit: >>> Reported-by: syzbot+68c37d09c833f8ec1341%syzkaller.appspotmail.com@localhost >>> >>> [ 64.2934242] panic: UBSan: Undefined Behavior in >>> /syzkaller/managers/netbsd-kubsan/kernel/sys/kern/kern_rndq.c:406:9, >>> negation of -2147483648 cannot be represented in type 'int' >>> >>> [ 64.3096778] cpu0: Begin traceback... >>> [ 64.3234784] vpanic() at netbsd:vpanic+0x258 sys/kern/subr_prf.c:336 >>> [ 64.3535415] isAlreadyReported() at netbsd:isAlreadyReported >>> [ 64.3836129] HandleNegateOverflow() at >>> netbsd:HandleNegateOverflow+0xff sys/../common/lib/libc/misc/ubsan.c:372 >>> [ 64.4136750] _rnd_add_uint32() at netbsd:_rnd_add_uint32+0x5a5 >>> rnd_dv_estimate sys/kern/kern_rndq.c:406 [inline] >>> [ 64.4136750] _rnd_add_uint32() at netbsd:_rnd_add_uint32+0x5a5 >>> rnd_estimate sys/kern/kern_rndq.c:836 [inline] >>> [ 64.4136750] _rnd_add_uint32() at netbsd:_rnd_add_uint32+0x5a5 >>> sys/kern/kern_rndq.c:873 >>> [ 64.4437455] uvm_fault_internal() at netbsd:uvm_fault_internal+0x154f >>> rnd_add_uint32 sys/sys/rndsource.h:103 [inline] >>> [ 64.4437455] uvm_fault_internal() at netbsd:uvm_fault_internal+0x154f >>> sys/uvm/uvm_fault.c:848 >>> [ 64.4637869] trap() at netbsd:trap+0xbf9 sys/arch/amd64/amd64/trap.c:538 >>> [ 64.4738073] --- trap (number 6) --- >>> [ 64.4838301] 7c382e9914c1: >>> [ 64.4838301] cpu0: End traceback... >>> [ 64.4838301] fatal breakpoint trap in supervisor mode >>> [ 64.4952445] trap type 1 code 0 rip 0xffffffff8021ddad cs 0x8 rflags >>> 0x282 cr2 0x7c382f73a018 ilevel 0 rsp 0xffff8180acb38690 >>> [ 64.5082606] curlwp 0xffffd6820e6eb300 pid 1909.1 lowest kstack >>> 0xffff8180acb352c0 >>> Stopped in pid 1909.1 (sh) at netbsd:breakpoint+0x5: leave > > > >
Attachment:
signature.asc
Description: OpenPGP digital signature