17 ms·
> memset_explicit Exciting to see this in the standard. Once this is in all compilers, this will probably have security effects beyond C. Fun fact: Miguel Oje
by Aissen 4y ago
> memset_explicit
Exciting to see this in the standard. Once this is in all compilers, this will probably have security effects beyond C.
Fun fact: Miguel Ojeda linked to @cperciva's article and its following HN discussion in the note (N2897) to propose this: https://news.ycombinator.com/item?id=8270136 https://news.ycombinator.com/item?id=8270136
- Sakos 4y agoI'm not familiar with C at all, but I'm wondering why they chose to add a keyword just for this specific case instead of providing a way to granularly tell the compiler not to optimize specific lines of code or what optimizations are permitted.
- Aissen 4y agoI'm guessing that this would have been either too complex, or taken too many years. The pragmatic, lower scope approach, already required quite a lot of work.
- Jensson 4y agoVolatile is exactly for this case. If you write or read a volatile variable then the compiler isn't allowed to remove the operations for any reason.
- 1ris 4y agoThat's what i thought, but apparently this is wrong. Had a disscussion about this here: https://news.ycombinator.com/item?id=27804810 https://news.ycombinator.com/item?id=27804810
- Jensson 4y agoI don't believe they are correct, or at least their arguments doesn't explain why it wouldn't work. Volatile wouldn't work with memset since memset doesn't take a pointer to volatile memory, that is true, but you could set the volatile data yourself and it shouldn't be optimized away as per the spec. The data living on a stack doesn't matter, it works perfectly fine having volatile data on the stack. I tried the following code in a few compilers, it works perfectly for overwriting buffer pointers that goes out of scope, also tested removing the volatile to ensure that the memory write was ignored and I reproduced the code vulnerability where the previous message was still there the second time I tried to read a message, and from the way I read the spec this shouldn't be optimized away by any compiler: void memset_explicit(char* p, char c, size_t n) { volatile char* vp = p; while (n--) *vp++ = c; } Casting other data types to a pointer to volatile data is within the spec, and the compiler should then treat it like any other volatile data.
- deleted 4y ago[deleted]
- aidenn0 4y agoIt's a bit more subtle than that; variables aren't volatile, objects are volatile. A volatile pointer is a hint to the compiler that the object pointed to might be volatile. If it can't disprove that "might" into "definitely not" then it treats it as volatile.
- mtlmtlmtlmtl 4y agoThis is mainly useful for implementing things like explicit_bzero(), to guarantee memory is zeroed before freeing it(free() makes no guarantees about the contents of freed memory). This is hugely important for discarding things like private keys. Up until now, safely implementing explicit_bzero() has depended on various hacks that a new compiler version might drag out from under you. This should end the "arms race".
- dataflow 4y agoI'm confused, why didn't they just mandate memset_s instead of introducing memset_explicit?
- Aissen 4y agoMy understanding, following the reading of https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2897.htm https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2897.htm is that it was simpler to "salvage" a single function from "Annex K" by renaming it, considering that "Annex K" was both optional and controversial (some called to remove it).
- loeg 4y agoBecause Annex K sucks and should be removed entirely.
- mst 4y agoFor those, like me, who weren't up to speed with why this argument is made, https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm seems to be a good summary of the problems with it. (if it isn't, hopefully somebody who knows more will post a better link)
- rurban 4y agoBecause people don't care abut security (or they just have no idea), hence they roll their own _FORTIFY_SOURCE hacks, but they still don't get memset_s right. So they rather named it what it is, protect from compiler optimizations, but not from cache side-channel attacks, which the _s variant would do. Because that is the secure variant. memset_explicit is just to overcome stubborn optimizer people who insist to optimize functions away (without warnings!), even when they have no idea about side-effects.
- dataflow 4y ago> but not from cache side-channel attacks, which the _s variant would do Wow, was that a requirement for memset_s? I'd never heard of timing being a something guaranteed by the *_s functions, regardless of security being in their name.