Memset memory that will not be optimized away

458 Views Asked by At

This is related to this question: is there is a way to memset a buffer after finished using it (for security for example) without it being optimized out?

Trying to cast the pointer to volatile pointer getting warning about sending volatile pointer to function that not expects volatile.

2

There are 2 best solutions below

1
Ian Abbott On BEST ANSWER

The memset_explicit() function from the C23 draft standard does what you want, but might not be implemented in current versions of the C standard library. The GNU Gnulib (GNU Portability Library) includes a version of memset_explicit() that can be incorporated in a project's sources under the terms of the GNU Lesser General Public License. The initial import into a project assumes that the project uses Autoconf, so that could be a problem for projects that do not use Autoconf.

The Gnulib implementation of memset_explicit() uses conditional compilation to implement the function in various ways, such as calling memset_s() (if available), adding a memory barrier after a call to memset(), or if none of those can be used, calling memset() via a volatile function pointer. The use of a volatile function pointer involves defining and initializing a function pointer volatile_memset like this:

    void * (* const volatile volatile_memset) (void *, int, size_t) = memset;

Calls to memset() through the volatile_memset pointer will not be optimized away.

4
Lundin On

A fully portable version from C90 to C23 is to use a struct wrapper and then declare a volatile struct object:

typedef struct
{
  uint8_t buf [n];
} buf_t;


volatile buf_t buf = {0}; 
// equivalent to memset(buf, 0, sizeof buf) but can't be optimized out
...
static const buf_t final_settings = { ... }; 
// some values you wish the buffer to have in the end
...
buf = final_settings; 
// equivalent to memset/memcpy but can't be optimized out

This also dodges the quirk/flaw in C regarding "access of volatile object" vs "volatile lvalue access" (also fixed in C23).