Deutsch English Français Italiano |
<20240321092738.111@kylheku.com> View for Bookmarking (what is this?) Look up another Usenet article |
Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Kaz Kylheku <433-929-6894@kylheku.com> Newsgroups: comp.lang.c Subject: Re: A Famous Security Bug Date: Thu, 21 Mar 2024 17:41:32 -0000 (UTC) Organization: A noiseless patient Spider Lines: 91 Message-ID: <20240321092738.111@kylheku.com> References: <bug-20240320191736@ram.dialup.fu-berlin.de> <20240320114218.151@kylheku.com> <uthirj$29aoc$1@dont-email.me> Injection-Date: Thu, 21 Mar 2024 17:41:32 -0000 (UTC) Injection-Info: dont-email.me; posting-host="8a88f4f3d1bb162453330ac9f4d394b5"; logging-data="2473520"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+ePqATicfSp4PLNHnpQuKNEWQhZXxXDy4=" User-Agent: slrn/pre1.0.4-9 (Linux) Cancel-Lock: sha1:nawoCiL1BtF+SvWsiWxOTEPrz/I= Bytes: 4855 On 2024-03-21, David Brown <david.brown@hesbynett.no> wrote: > On 20/03/2024 19:54, Kaz Kylheku wrote: >> On 2024-03-20, Stefan Ram <ram@zedat.fu-berlin.de> wrote: >>> A "famous security bug": >>> >>> void f( void ) >>> { char buffer[ MAX ]; >>> /* . . . */ >>> memset( buffer, 0, sizeof( buffer )); } >>> >>> . Can you see what the bug is? >> >> I don't know about "the bug", but conditions can be identified under >> which that would have a problem executing, like MAX being in excess >> of available automatic storage. >> >> If the /*...*/ comment represents the elision of some security sensitive >> code, where the memset is intended to obliterate secret information, >> of course, that obliteration is not required to work. >> >> After the memset, the buffer has no next use, so the all the assignments >> performed by memset to the bytes of buffer are dead assignments that can >> be elided. >> >> To securely clear memory, you have to use a function for that purpose >> that is not susceptible to optimization. >> >> If you're not doing anything stupid, like link time optimization, an >> external function in another translation unit (a function that the >> compiler doesn't recognize as being an alias or wrapper for memset) >> ought to suffice. > > Using LTO is not "stupid". Relying on people /not/ using LTO, or not > using other valid optimisations, is "stupid". LTO is a nonconforming optimization. It destroys the concept that when a translation unit is translated, the semantic analysis is complete, such that the only remaining activity is resolution of external references (linkage), and that the semantic analysis of one translation unit deos not use information about another translation unit. This has not yet changed in last April's N3096 draft, where translation phases 7 and 8 are: 7. White-space characters separating tokens are no longer significant. Each preprocessing token is converted into a token. The resulting tokens are syntactically and semantically analyzed and translated as a translation unit. 8. All external object and function references are resolved. Library components are linked to satisfy external references to functions and objects not defined in the current translation. All such translator output is collected into a program image which contains information needed for execution in its execution environment. and before that, the Program Structure section says: The separate translation units of a program communicate by (for example) calls to functions whose identifiers have external linkage, manipulation of objects whose identifiers have external linkage, or manipulation of data files. Translation units may be separately translated and then later linked to produce an executable program. LTO deviates from the the model that translation units are separate, and the conceptual steps of phases 7 and 8. The translation unit that is prepared for LTO is not fully cooked. You have no idea what its code will turn into when the interrupted compilation is resumed during linkage, under the influence of other tranlation units it is combined with. So in fact, the language allows us to take it for granted that, given my_memset(array, 0, sizeof(array)); } at the end of a function, and my_memset is an external definition provided by another translation unit, the call may not be elided. The one who may be acting recklessly is he who turns on nonconforming optimizations that are not documented as supported by the code base. Another example would be something like gcc's -ffast-math. You wouldn't unleash that on numerical code written by experts, and expect the same correct results. -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal Mastodon: @Kazinator@mstdn.ca