Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
memset如何提供比bzero或explicit_bzero更高的安全性?_C - Fatal编程技术网

memset如何提供比bzero或explicit_bzero更高的安全性?

memset如何提供比bzero或explicit_bzero更高的安全性?,c,C,bzero的手册页指出,出于各种安全原因,它已被弃用,应改用memset。他们主要提到的问题是,bzero或explicit\u bzero无法找到给定数据的所有副本(尤其是小到足以放入寄存器的数据)而且可能不会像预期的那样完全擦除或覆盖。但是memset只接收指针地址。memset如何才能找到所有副本来关闭这种缺乏安全性的情况?我认为您误读了手册页。假设您正在谈论Linux手册页,它(正确地)声称explicit\u bzero和memset\u explicit和memset\u s比mem

bzero
的手册页指出,出于各种安全原因,它已被弃用,应改用
memset

他们主要提到的问题是,
bzero
explicit\u bzero
无法找到给定数据的所有副本(尤其是小到足以放入寄存器的数据)而且可能不会像预期的那样完全擦除或覆盖。
但是
memset
只接收指针地址。
memset
如何才能找到所有副本来关闭这种缺乏安全性的情况?

我认为您误读了手册页。假设您正在谈论Linux手册页,它(正确地)声称
explicit\u bzero
memset\u explicit
memset\u s
memset
bzero
更安全(出于某些目的)。它没有声明
memset
bzero
之间有任何安全差异。不推荐使用
bzero
的原因是它是
memset
的一个微不足道的包装器,而且所有的imk C实现都有
memset
,因此程序员最好使用
memset

memset
/
bzero
显式
/
变体之间的区别在于编译器被禁止优化显式变体。这使得显式变体适合清除机密数据。例如,考虑下面的程序片段:

bzero(password, password_length);
free(password);
通过使用
bzero
memset
,许多现代编译器可以看到“哦,您正在写入内存,然后将其释放。无法读回刚刚写入的内容,因此调用
bzero
相当于什么都不做。什么都不做比调用
bzero
快,因此我不会为
bzero
调用生成代码。”

编译器推理中的缺陷在于,将内存归零的原因不是程序的已定义行为,而是后续未定义或未指定行为的情况。从C编译器的角度来看,未定义的行为意味着任何事情都可能发生。从安全工程师的角度来看,这到底是什么关于未定义行为(如缓冲区溢出或释放后使用)的PPEN非常重要。同样,从未初始化内存中读回的内容尚未明确,但对安全工程师来说很重要。安全工程师试图减少此类未定义或未明确行为的安全影响

因此,对于安全工程师来说,
memset
的优化是不幸的。安全工程师希望确保在内存被释放时,
explicit\u bzero
:编译器被指示在该函数返回时将目标内存的内容视为可观察的,因此不允许优化调用在语义上,
explicit\u bzero(缓冲区,长度)
相当于

bzero(buffer, length);
for (size_t i = 0; i < length; i++) __observe__(buffer[i]);
bzero(缓冲区,长度);
对于(size_t i=0;i
其中,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

显式归零有其局限性。手册页强调它不会清除寄存器中变量的副本,但这通常不是一个大问题,因为缓冲区溢出或从未初始化内存读取导致寄存器值泄漏的情况很少见。实际上最大的局限性是
realloc
。当动态使用分配的内存,
realloc
可能会移动它,并且无法清除旧值。因此,如果缓冲区的内容是敏感的,则不能对其使用
realloc

显式归零的另一个限制是,它仅适用于程序级别,而不适用于系统级别。数据的副本可能保留在缓存、交换等中。程序内存归零的目标是防止程序内部出现安全漏洞。它不能防止更大的系统危害

请注意,编写自己的
explicit_bzero
是非常困难的。您所能做的最好的事情是让它与有限编译器集的有限版本一起工作,而不保证下一个版本不会有一个更出色的优化器来看穿您的尝试。这就是为什么C11将其作为标准函数添加到了


差不多。技术上独立的实现不一定要有
memset
,但它是一个非常简单和有用的函数,大多数都有,而且它通常是由编译器提供的,所以即使在构建时没有通常的C运行时,它也是可用的。

请参阅@WeatherVane我已经看到了这个问题,但答案不是g到安全性问题。手册页基本上说,由于缺乏安全性,它已被弃用。但我不认为
memset
应该如何提供它。^^大多数优化器将memset视为内在的,在适用的情况下用一些快速mov替换它。我怀疑出现安全性问题是因为bzero()在许多旧式网络代码中使用。当编译器在内联代码方面变得聪明时失败,因此需要显式的\u bzero()解决方案。但是显式的\u bzero()仍然存在类似的安全问题。当memset不是此和bzero()的解决方案时因为在旧的网络代码中使用了它而被弃用,他们现在用什么来擦除网络代码中的数据?