Is an implementation that calls sleep(10); then powers off the machine conforming?
The âsensitive information stored in the objectâ has been made âinaccessible.â Mission accomplished.
But thatâs not what the standard says, as written.
The purpose of this function is to make sensitive information stored in the object inaccessible.367)
That literally doesnât mean anything. Is the destination buffer supposed to be unreadable? What does memset or memset_explicit have to do with that?
367)The intention is that the memory store is always performed (i.e. never elided), regardless of optimizations. This is in
contrast to calls to the memset function (7.26.6.1)
Thatâs the only semantically useful requirement for implementers, and the compiler barrier satisfies that. This is a useful semantic point with clear meaning to implementers.
But now we have requirements coming out of thin air based on committee discussions. Satisfying these requirements adds significant complexity to implementations, and still doesnât end up being useful to actual users of non-C abstract machines. If no implementation does these additional side-channel suggestions (as is currently the case)(because the standard didnât say they had to), then users cannot portably rely on these non-standard behaviors.
Worse, I suspect weâll get vulnerabilities reported for not implementing every trick in the book to ensure zeroing. (The man page for explicit_bzero has a funny anecdote on how explicit_bzero can actually decrease security.)
As specified, users cannot simply call memset_explicit and rely on cache clearing, memory ordering, or any of the other QoL suggestions for the blog cited earlier.
Consider the example of a library author that would like to rely on memset_explicit to provide guarantees around cache clearing (and/or memory ordering).
memset_explicit(dest, ch, count);
When their libary is linked against libc-a.so, which provides such QoL additions in their implementation of memset_explicit, everything works great. Now their library gets linked against libc-b.so perhaps on a different platform, which doesnât have such QoL additions in their implementation of memset_explicit (because the standard doesnât say so). Perhaps that results in a security vulnerability or exploit. It seems that perhaps they would have been better off with just:
memset(dest, ch, count);
asm(""::"r"(dest):"memory");
arch_specific_cache_flush_not_provided_by_libc(dest);
atomic_signal_fence(memory_order_seq_cst);
That inline asm is not ISO C, and I suspect that whatever arch_specific_cache_flush_not_provided_by_libc does MUST also be implemented using non-ISO C extensions. So as long as WG14 has strict adherence to only referencing only ISO C and the C abstract machine, I donât see how they can compel implementations to implement specific semantics for machines which are unspecified. As such, users cannot rely on semantics that WG14 members wish but did not specify/standardize functions as having, and instead must use non-standard language extensions in order to get the fine grain guarantees they desire for their target platform. As such, having such additions to the standard library is questionable.
If thatâs what you meant, then you should have put a ring on it put it in the spec.
atomic_signal_fence is standard ISO C, why was that not made explicit in the spec (for implementation of memset_explicit)(rather than in out of band blog posts)?!