[tz] Minor (unimportant really) technical UB bug in strftime() ?

Paul Eggert eggert at cs.ucla.edu
Tue Nov 8 23:51:08 UTC 2022


On 11/8/22 05:07, Robert Elz via tz wrote:

> It seems likely that the simple fix is to replace the struct assignment
> with 7 individual assignment statements
> 
> 	tm.tm_year = t->tm_year;
> 	tm.tm_mon = t->tm_mon;
> 	/* ... */

Thanks for reporting the problem and suggesting a fix.

Strictly speaking, the tzcode implementation of strftime doesn't violate 
the C standard here, since it implements the %s format, and the C 
standard doesn't specify the behavior of %s (which therefore can be 
undefined if you pass unset tm_yday etc.). However, the next release of 
POSIX will require support for %s, and as I recall the current draft for 
the next POSIX has messed up its spec for %s, so tzcode is on shaky 
ground here (as is the draft POSIX spec :-), and we can do better.

Worse, there's a similar problem in localtime.c's implementation of 
mktime, for which the C standard clearly says mktime should not crash 
merely because tm_yday etc. is uninitialized. Here, tzcode mktime.c 
clearly is running afoul of the C standard.

There's a subtle point here. By default tzcode's implementation of 
mktime sometimes looks at tm_gmtoff which the C standard says can be 
uninitialized and therefore has undefined behavior. On typical 
platforms, reading uninitialized data gives you arbitrary bits without 
trapping; on these platforms looking at tm_gmtoff will merely yield 
randomish bits (which tzcode mktime deals with reliably). However, on 
oddball platforms where reading uninitialized data traps or worse, 
you're supposed to compile code with -DUNINIT_TRAP so that mktime does 
not look at tm_gmtoff (and therefore has worse behavior in other ways).

As you write, these are not likely to be problems on practical hosts. 
After all, the code has done it this way since 1989 with no bugs 
reported. However, we might as well do it correctly. I installed the 
attached patch which I hope addresses these issues satisfactorily.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Port-mktime-and-strftime-to-strict-C.patch
Type: text/x-patch
Size: 2400 bytes
Desc: not available
URL: <https://mm.icann.org/pipermail/tz/attachments/20221108/b183d639/0001-Port-mktime-and-strftime-to-strict-C.patch>


More information about the tz mailing list