Memset memory that will not be optimized away.

huangapple go评论52阅读模式
英文:

Memset memory that will not be optimized away

问题

这与此问题相关:是否有一种方法可以在使用完缓冲区后(例如出于安全考虑)对其进行memset,而不会被优化掉?

尝试将指针强制转换为volatile指针,但会收到有关将volatile指针发送给不期望volatile的函数的警告。

英文:

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.

答案1

得分: 5

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.

英文:

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.

答案2

得分: 0

一种完全可移植的方法,从C90到C23,是使用一个结构体包装器,然后声明一个volatile结构体对象:

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

volatile buf_t buf = {0}; 
// 等同于memset(buf, 0, sizeof buf) 但不能被优化掉
...
static const buf_t final_settings = { ... }; 
// 一些你希望缓冲区最终具有的值
...
buf = final_settings; 
// 等同于memset/memcpy 但不能被优化掉

这也规避了C中关于“访问volatile对象”与“volatile左值访问”的怪异/缺陷(在C23中也已修复)。

英文:

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).

huangapple
  • 本文由 发表于 2023年4月4日 17:42:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75927860.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定