我只是想知道是否可以告诉 Linux/Ubuntu 在让下一个应用程序分配释放的内存之前用零覆盖它?
如果不能,那为什么这不可能呢?我知道安全关键程序在释放内存之前(可能)会自行覆盖内存,但我的猜测是,如果您有足够的可用 RAM,它甚至不会减慢系统速度。至少只要 free() 调用没有被阻止。
有什么想法吗?
答案1
当进程调用 free() 时,它不会立即将内存归还给系统,而是将其归还给该进程拥有的堆。堆要么使用匿名内存映射来映射大块内存,要么使用 sbrk() 来缩小或增大堆。当内存被取消映射或使用 sbrk() 缩小堆时,堆中的内存将归还给系统。此时,其他进程可以重新使用页面,当重新使用页面时,它们在进程访问之前始终会被清零。[1]
由于性能问题,malloc 等内存分配在释放回堆时不会将内存清零。通常,敏感数据的最佳做法是在释放之前将其清零。但是,我猜您想对进程生命周期内释放的所有内存强制执行此策略。glibc 2.4 及更高版本有一个 MALLOC_PERTURB_ 环境选项,当将其设置为非零值时,将在分配内存和使用 free() 释放内存时将内存初始化为该值的补码。这样做的缺点是,它可能会触发代码中的错误,错误地依赖于在分配时将内存正常初始化为零。
要使用 MALLOC_PERTURB_,例如将其设置为随机值..
export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
并运行您的代码。
[1] 差不多。使用 MAP_UNINITIALIZED 的 mmap() 和配置了 CONFIG_MMAP_ALLOW_UNINITIALIZED 的内核允许内存非零化,但这在 Ubuntu 上是绝对不允许的。