敏感的variables使用后明确清除/清零?

我注意到一些程序在使用后显式地清零敏感的内存分配。 例如,OpenSSL有一个方法来清除RSA密钥占用的内存:

“释放RSA结构rsa。应该总是使用这个函数来释放RSA结构,因为它也通过首先清除内存来安全地释放子字段。

http://www.rsa.com/products/bsafe/documentation/sslc251html/group__COMMON__RSA__KEY__FUNCS.html#aRSA_free

如果任何(C / C ++)程序包含这样的敏感variables,是否应该像上面那样显式调零内存? (或者,记忆是一种偏执狂行为还是一种保护)?

另外,程序结束时,任何分配的内存最终都会分配给另一个程序。 在Linux系统上,在分配给另一个程序之前,内存是否被清理或消毒? 或者,第二个程序可以读取第一个程序的一些旧的内存内容吗?

在Linux系统上,在分配给另一个程序之前,内存是否被清理或消毒?

是的,在任何可敬的桌面操作系统上,内存在从一个进程传递到另一个进程时都会被消毒。 您观察到的清理步骤是为了防止其他攻击,从在相同地址空间中执行的代码或获取特权,以便从目标进程的内存空间读取内存。

如果任何(C / C ++)程序包含这样的敏感变量,是否应该像上面那样显式调零内存?

一旦不再需要这些敏感数据,这是一个非常明智的保障。

当像GPG和OpenSSL这样具有敏感密码数据的程序/库显式地将内存归零时,与内存将被“重新分配”给其他可以读取数据的程序无关。 由于多进程/多用户操作系统的工作方式,这基本上是不可能的。

调零数据的原因有两方面:

  1. 如果代码是一个库,你想防止通话程序不小心的信息泄露。 即使包含敏感信息的内存不能被重新分配给另一个进程,只要仍然运行相同的程序映像(即只要没有调用exec* ),释放的内存就可以在同一进程中重用。 一个有问题的程序可能会调用malloc然后将缓冲区写入磁盘,而不先填充整个分配的对象,在这种情况下,旧的潜在敏感信息可能会泄露到磁盘。 像Microsoft Office这样的主要现实世界的产品中存在这种问题(尽管它们现在可能已经被修复了)。

  2. 即使代码不是一个库,而是一个独立的程序,你也可以将内存中的敏感数据清零,然后将其释放出来用于偏执狂目的。 如果联邦调查局把你的门关上,把你的电脑拿走,他们可以随时检查交换分区上发生的任何事情。 如果他们小心地将其移除,他们甚至可以检查公羊的内容。 如果您对物理攻击偏执,则要确保使用密码短语等不存在于RAM或磁盘中的任何地方。 许多加密程序甚至希望拥有root访问权限,所以他们可以mlockall内存以防止任何事情被交换到磁盘上(尽管在我看来这是愚蠢的 – 由于软件中的错误而导致严重的根本危害, )。

如果您不担心物理攻击,或者如果您充分接触现实,意识到物理攻击者可能比交换分区取证有更好的方法来获取密码,那么理由2可能大部分是假的,但大多数软件地址无论如何,只是为了保持坚果类的快乐。 🙂

从安全的角度来看,你的内存可能包含你不想徘徊的数据。 如果进程崩溃,核心文件将有完整的内存转储。 有可能挖掘到这些核心文件和我的数据。 对于支持电话,如果您必须发送该核心文件,如果使用后对内存进行了消毒,则会感到更安全。 当我在VMS上工作时,一些敏感的客户甚至不会给我们转储文件(这使得调试非常困难)。

在Linux系统上,在分配给另一个程序之前,内存是否被清理或消毒?

这取决于,细节可以在mmap手册页找到:

MAP_UNINITIALIZED(从Linux 2.6.33开始)

  Don't clear anonymous pages. This flag is intended to improve performance on embedded devices. This flag is only honored if the kernel was configured with the CONFIG_MMAP_ALLOW_UNINITIALIZED option. Because of the security implications, that option is normally enabled only on embedded devices (ie, devices where one has complete control of the contents of user memory). 

在将内存返回到操作系统之前对内存进行清零最好是,如果你的进程在有机会之前被一个信号所杀,会发生什么? 配置内核为您执行清理。