tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: panic: UBSan: Undefined Behavior in /syzkaller/managers/netbsd-kubsan/kernel/sys/kern/kern_rndq.c:LINE, negation of -ADD



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



Home | Main Index | Thread Index | Old Index