ave*_*rdo 3 c linux memory linux-kernel
memfd_secret()
已合并到内核中,但我没有看到它真正的安全优势。我的意思是,这有避免旁路攻击的想法,但这就像车钥匙被锁了而没有人知道它们在哪里一样。
AFAIK,在内核模式下,提供给应用程序的页面根本没有被映射,但这不能用于隔离病毒或内核本身的任何内容。
隔离内核的一段内存范围应该如何更安全?
有人可以提供一个代码示例来说明如何保护幽灵或类似的东西吗?
更新
int main(int argc, char *argv[]) {
while(true) {
int rc = fork();
if(rc == -1) {
perror("fork error");
}
}
}
Run Code Online (Sandbox Code Playgroud)
memfd_secret()
允许用户空间进程拥有“秘密”内存区域。在这种情况下,“秘密”意味着其他进程无法访问该内存区域(甚至内核本身也不能访问,或者至少不是偶然的)。
此系统调用允许进程以更安全的方式存储机密信息(例如密码或私钥),因为恶意软件更难访问该秘密内存区域。这个系统调用还应该防止像 Spectre 这样的漏洞,因为秘密内存区域是未缓存的;并且还应该保护(虽然不完全,但至少部分)免受内核错误的影响,因为内核无法访问该内存区域。
为了使用这个系统调用(在 Linux 5.14 中可用),您首先要调用memfd_secret()
来获取文件描述符;然后调用 来ftruncate()
选择秘密内存区域的大小;最后你用它mmap()
来映射秘密内存,这样你就可以像平常一样通过指针访问它。
其他详细信息请参见此处。
memfd_secret()
编辑:不幸的是,由于担心性能问题,“未缓存”功能已被删除,该功能不易受到 Spectre 等攻击。
编辑2:关于为什么获得的秘密内存区域memfd_secret()
使程序更安全的其他细节(源代码,为了清晰起见,我稍微修改了):
针对ROP 攻击的增强保护(与所有其他内核内攻击预防系统结合)。秘密内存使得“简单”的 ROP 不足以执行渗透,这增加了攻击所需的复杂性。除了内核堆栈大小限制和地址空间布局随机化等其他保护措施(这些保护措施使得查找小工具非常困难)之外,缺乏任何用于访问秘密内存的内核原语意味着单小工具 ROP 攻击无法发挥作用。由于访问秘密内存的唯一方法是重建丢失的映射条目,因此攻击者必须恢复物理页并在内核中插入指向它的 PTE,然后检索内容。这至少需要三个小工具,这超出了大多数标准攻击的难度。
防止跨进程秘密用户空间内存暴露。一旦分配了秘密内存,用户就不会意外地将其传递到内核中以传输到某个地方。秘密内存页面无法通过直接映射访问,并且在 GUP 中是不允许的。
针对被利用的内核缺陷进行强化。为了访问秘密内存,内核端攻击需要遍历页表并创建新页表,或者生成新的特权用户空间进程以使用 ptrace 执行秘密泄露。
编辑3:只是我认为可能相关的一条注释:秘密内存区域可以由使用创建的子进程访问fork()
,因此必须谨慎。至少,使用标志O_CLOEXEC
(传递给memfd_secret()
),进程不会使秘密内存可供使用 创建的进程使用execve()
。
归档时间: |
|
查看次数: |
1913 次 |
最近记录: |