|
Message-Id: <b1a510c14f340b855a5900178e0191891751c8fa.1684932960.git.Jens.Gustedt@inria.fr> Date: Fri, 26 May 2023 11:25:43 +0200 From: Jens Gustedt <Jens.Gustedt@...ia.fr> To: musl@...ts.openwall.com Subject: [C23 string conversion 1/3] C23: add the new memset_explicit function 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. --- 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 <string.h> +#include <stdlib.h> +#include <atomic.h> + +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
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.