Re: [tz] Minor (unimportant really) technical UB bug in strftime() ?
On 2022-11-11 13:53, Paul Eggert via tz wrote:
On 2022-11-10 16:11, Tom Lane wrote:
simple modifications of the strftime() case can provide pretty good examples. I'm not sure I'm following this argument, but if I understand it correctly I disagree. I very much much want implementations to reject attempts to use uninitialized data, and I don't want the C standard to prohibit such implementations. Use of uninitialized data is a serious problem in real applications - several CVEs have arisen from it - and the C standard shouldn't require implementations to sweep it under the rug.
This call is obviously buggy since it is passing an uninitialized struct tm to strftime. However, the C standard says the patched strftime's memcpy initializes strftime's local variable tm, and therefore mktime's use of tm's contents is defined and the implementation allow the program's use of uninitialized data.
Whatever the reason for this peculiarity of the C standard (and nobody seems to remember why it's there), it's counterproductive. In general C programs shouldn't use uninitialized data. If they do, it's useful to have a debugging implementation that reports any such use the instant that it happens as this will help catch real bugs. And since common debugging implementations like valgrind and UBSan are not following the C standard here, this suggests that the C standard is mistaken, not the implementations.
That leads either to strftime() knowing much more about mktime()'s innards than it ought to
It's not a problem for strftime, since strftime's has to know what's needed in the struct tm; this follows from strftime's API.
It may not know everything about the object, as there may be implementatiion extensions to deal with e.g. localization issues, and can never know everything about another function implementation, which could be changed at any time.
It might be a problem for other scenarios, such as the one you vaguely suggested though I don't know the details. However, even assuming these other scenarios exist, they don't justify this peculiarity of the C standard. The standard should not say that the ordinary meaning of "don't use uninitialized variables" is wrong and that there's some trickier interpretation that hardly any programmer knows and that was wrong even in C17 and so needed rewording (and perhaps still needs rewording) and that nevertheless must be supported - even though important debugging implementations disagree.
I think the principle is just to program carefully and generically around possible issues, when dealing with an opaque object you do not define and control, to avoid creating issues with private fields or functions which may be part of the implementation, but not in whatever documented interface you are programming to. Not all the world is...C, POSIX, or Linux, compliant. -- Take care. Thanks, Brian Inglis Calgary, Alberta, Canada La perfection est atteinte Perfection is achieved non pas lorsqu'il n'y a plus rien à ajouter not when there is no more to add mais lorsqu'il n'y a plus rien à retirer but when there is no more to cut -- Antoine de Saint-Exupéry
participants (1)
-
Brian Inglis