Fix an undefined behaviour in os/rand.c#2050
Conversation
|
You missed the cast on I do wonder if it would be better to declare |
|
Verified the change with a quick test main function: This allows us to compile locally and get the warning: I switched to using long multi/add variables, and removed all the now unnecessary casts from that function (which were there in the original version too). |
|
I can't reproduce the md5.c I claimed above. I obviously saw it in one of my CI tests, but it's gone now anyway. For future investigation, my test harness was: (Verified it's not using openssl code.) It's irrelevant to this PR anyway, but we can shelve the md5.c possible issue until we come across it again, if ever. (It's been years without problem so far.) |
|
Looks tidier, but i think you should keep the casts to |
This is really picky and I almost didn't bother given this is just code lifted from FreeBSD which hasn't changed it in 32 years. https://github.com/lattera/freebsd/blame/401a161083850a9a4ce916f37520c084cff1543b/lib/libc/gen/_rand48.c#L32-L49 However undefined behaviour sanitizer whinges about signed overflows. This happens because the promotion of unsigned short in arithmetic expressions is to signed int, and then multiplying signed ints can overflow from signed to unsigned. Eg: (gdb) p (unsigned short)50000 * (unsigned short)45000 $1 = -2044967296 (gdb) p (unsigned int)50000 * (unsigned int)45000 $2 = 2250000000 Due to 2s complement this makes no difference and casting both to unsigned int before the multiplcation gives you the same bit pattern. It's just the resulting type that differs, as we change that in the assignment anyway. (Note there are similar undefined behaviour issues with md5.c, which I didn't fix.) Signed-off-by: James Bonfield <jkb@sanger.ac.uk>
Added them back then. (Also bah humbug on annoying spammy warnings! Although even -Wextra doesn't complain.) |
This is really picky and I almost didn't bother given this is just code lifted from FreeBSD which hasn't changed it in 32 years.
https://github.com/lattera/freebsd/blame/401a161083850a9a4ce916f37520c084cff1543b/lib/libc/gen/_rand48.c#L32-L49
However undefined behaviour sanitizer whinges about signed overflows. This happens because the promotion of unsigned short in arithmetic expressions is to signed int, and then multiplying signed ints can overflow from signed to unsigned.
Eg:
Due to 2s complement this makes no difference and casting both to unsigned int before the multiplcation gives you the same bit pattern. It's just the resulting type that differs, as we change that in the assignment anyway.
(Note there are similar undefined behaviour issues with md5.c, which I didn't fix.)