【问题标题】:Is explicitly clearing/zeroing sensitive variables after use sensible?使用后显式清除/归零敏感变量是否明智?
【发布时间】:2011-08-30 16:00:01
【问题描述】:

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

“释放 RSA 结构 rsa。此函数应始终用于释放 RSA 结构,因为它还通过首先清除内存来安全地释放子字段。”

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

如果任何 (C/C++) 程序包含这样的敏感变量,您是否应该像上面那样显式地将内存归零? (或者,归零记忆是一种偏执的行为还是只是一种保护措施)?

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

【问题讨论】:

  • 我不确定那句话是否声称它正在归零内存。

标签: c linux security memory-management


【解决方案1】:

从安全的角度来看,您的内存中可能包含您不希望逗留的数据。如果进程崩溃并且核心文件将具有完整的内存转储。可以挖掘那些核心文件并挖掘数据。对于支持电话,如果您必须发送该核心文件,如果在使用后对内存进行清理,您会感觉更安全。当我在 VMS 上工作时,一些敏感的客户甚至会拒绝给我们转储文件(这使得调试变得非常困难)。

【讨论】:

  • 将核心文件提供给第三方是一个非常糟糕的主意,即使您将内存释放为零。您仍然可能在内存中拥有大量仍在使用的特权信息(可能像客户姓名一样简单)。而且既然它是您无论如何都必须信任的应用程序供应商,那么如果他们说他们将内存归零,而您显然不能相信他们编写的软件足够正确而不会崩溃,您为什么还要相信他们呢??
【解决方案2】:

在 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 (i.e., devices where one has complete control
          of the contents of user memory).

在将内存返回给操作系统之前对其进行归零充其量是不确定的,如果您的进程在有机会这样做之前被信号杀死会发生什么?配置内核为您执行清理。

【讨论】:

  • 请注意,此选项还将排除新匿名页面的 COW 零页面语义,这在某些情况下可以大大提高性能,但也可能导致更多的交换,包括交换毫无价值的未初始​​化数据到磁盘...
【解决方案3】:

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

归零数据的原因有两个:

  1. 如果代码是库,您希望防止调用程序不小心泄露信息。即使包含敏感信息的内存不能重新分配给另一个进程,但释放的内存可以并且将在同一进程中重复使用只要它仍在运行相同的程序映像(即只要它没有'不叫exec*)。有缺陷的程序可能会调用malloc,然后将缓冲区写入磁盘,而无需先填充整个分配的对象,在这种情况下,旧的潜在敏感信息可能会泄漏到磁盘。此类问题存在于 Microsoft Office 等主要现实产品中(尽管它们现在可能已经修复)。

  2. 即使代码不是库而是独立程序,您也可能希望在释放内存中的敏感数据之前将其归零以进行妄想症。如果联邦调查局破门而入并拖走您的计算机,他们随后可以检查交换分区上发生的任何事情。如果他们小心地移除它,他们甚至可以检查 ram 内容。如果您对物理攻击有疑虑,您需要确保密码等在使用后不存在在内存或磁盘中的任何位置。许多加密程序甚至想要拥有 root 访问权限,这样他们就可以mlockall 他们的内存来防止任何东西被交换到磁盘上(尽管在我看来这是愚蠢的——由于软件中的错误而冒着 root 妥协的严重风险来换取关于物理攻击)。

如果您不担心物理攻击,或者如果您与现实有足够的联系,可以意识到物理攻击者可能有比交换分区取证更好的方法来获取您的密码,那么原因 #2 可能大部分是假的,但是无论如何,大多数软件都会解决这个问题,只是为了让疯子们开心。 :-)

【讨论】:

  • 多进程操作系统不会阻止将内存块重新分配给不同的进程,因为内存要求决定了。大多数操作系统会在这样做时清理内存,但在 Linux 上,此步骤是明确可选的。
  • 啊,也许您的意思是(根据您的回答)在应用程序级别(具有管理配置)而不是在管理级别。
  • 这是一个内核选项,因此它甚至是可能的,但是应用程序必须在调用 mmap 时显式请求行为(因为通常匿名页面的 mmap 必须提供零填充页)。
  • @R: 对,但你必须假设任何试图筛选记忆的人都会通过这个选项。
  • 或者你不能启用危险的内核选项。即使您明确将缓冲区归零,也有 大量 可能存在您无法控制的危险的额外信息泄漏 - 堆栈帧、标准 C 库或第三方库分配的数据等。我会毫不犹豫地说,任何启用了CONFIG_MMAP_ALLOW_UNINITIALIZED 的系统几乎肯定是易受攻击的。
【解决方案4】:

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

是的,在任何受人尊敬的桌面操作系统上,当从一个进程传递到另一个进程时,都会对内存进行清理。您观察到的清理步骤是为了防止其他攻击,防止在同一地址空间中执行的代码或获得允许它从目标进程的内存空间读取内存的权限。

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

当您不再需要这些敏感数据时,将其删除是一种非常明智的保护措施。

【讨论】:

  • @Ben Voigt 出于此答案的目的,它包含在桌面操作系统中。我并不是说它只在那里使用。但是现在我已经阅读了您的答案,我明白了您的意思。
  • 密码学也不仅仅是桌面 :)
猜你喜欢
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
  • 2020-08-22
相关资源
最近更新 更多