On Fri, 26 May 2023 11:25:43 +0200, Jens Gustedt wrote: > This function is meant to work around the fact that C compilers are > allowed to optimize calls to memset out, if they are able to detect > that the byte array will die soon, anyway. This permission for memset > may lead to data leak when non-priveledged parts of an application > would be able to reconstruct secret information from memory received > through malloc or on the stack. > > This function here is to force compilers to do the clean up operation > under all circumstances. How to do that is out of the scope of the C > standard, so there is not much help there, it only describes the > intent. > > By having a slow bytewise copy, we intent also to have predictable > timing, such that we can avoid side-channel attacks. We also do our > best to remove the meta-information, which is the pointer value from > the stack and combine that with a synchronizing operation at the end. I don't see how this is in any way useful. It's certainly not part of the standard, which only says: > 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) > --- > include/string.h | 1 + > src/string/memset_explicit.c | 14 ++++++++++++++ > 2 files changed, 15 insertions(+) > create mode 100644 src/string/memset_explicit.c > > diff --git a/include/string.h b/include/string.h > index 05019c03..78ccccbd 100644 > --- a/include/string.h > +++ b/include/string.h > @@ -27,6 +27,7 @@ extern "C" { > void *memcpy (void *__restrict, const void *__restrict, size_t); > void *memmove (void *, const void *, size_t); > void *memset (void *, int, size_t); > +void *memset_explicit(void *, int, size_t); > int memcmp (const void *, const void *, size_t); > > void *(memchr) (const void *, int, size_t); > diff --git a/src/string/memset_explicit.c b/src/string/memset_explicit.c > new file mode 100644 > index 00000000..49ced751 > --- /dev/null > +++ b/src/string/memset_explicit.c > @@ -0,0 +1,14 @@ > +#include > +#include > +#include > + > +void *memset_explicit(void *dest, register int c, register size_t n) > +{ > + register unsigned char volatile *p = dest; > + register unsigned char volatile *stop = p + n; > + for (; p < stop; ++p) > + *p = c; > + // the CAS operation serves as memory barrier, and destroys the > + // information, if it happened to be spilled on the stack > + return a_cas_p(&dest, dest, 0); > +} > -- > 2.34.1 > Musl effectively already has this function in that it has explicit_bzero. Why not simply copy it? Hell, while we're at it, implement explicit_bzero in terms of memset_explicit.