NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: lib/58041: strptime("%s") bug: undefined behaviour in 64-bit; accepts invalid values in 32-bit
The following reply was made to PR lib/58041; it has been noted by GNATS.
From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: Emanuele Torre <torreemanuele6%gmail.com@localhost>
Cc: gnats-bugs%NetBSD.org@localhost, netbsd-bugs%NetBSD.org@localhost
Subject: Re: lib/58041: strptime("%s") bug: undefined behaviour in 64-bit; accepts invalid values in 32-bit
Date: Sat, 16 Mar 2024 00:19:30 +0000
Thanks for the report!
> This makes the code, if the check is not optimised out, trigger a signed
> integer overflow (undefined behaviour in standard C) for inputs to %s
> that start with a sequence of characters between "922337203685477581"
> and "999999999999999999" (inclusive, 64-bit time_t).
Yep, that looks like undefined behaviour. I added some automatic
tests to exercise this case -- although you can't verify from the
outside if it's wrong or not, because even if strptime parses it
correctly, the time is outside the range that can be represented by
struct tm, so strptime needs to fail either way.
> Additionally, in builds where there is `#define TIME_MAX INT32_MAX', and
> `time_t' is `int32_t', if we assume that signed integer overflow works
> like unsigned integer overflow, this makes %s accept, for example,
> "9999999999" as a valid timestamp equivalent to
> "1410065398" (Sat 20 Nov 17:46:39 UTC) instead of rejecting it.
> This is thanks to the fact that UINT32_MAX and INT32_MAX (unlike their
> 64-bit counterparts) have the same number of digits in decimal, so
> `rulim /= 10' can't reject the overflow in time.
In NetBSD, this is not an issue because time_t is always 64-bit and
has been since netbsd-6. (We've been working on getting ready for
Y2.038k for many years now!)
However, to make it more portable and easier to understand, I've
rewritten the logic in a way that uses a simpler idiom to reliably
avoid overflow no matter what integer type time_t is. (Porting to
systems with floating-point time_t left as an exercise for the
reader!)
Home |
Main Index |
Thread Index |
Old Index