LWN:kernel的沙盒模式!

关注了就能看到更多这么棒的文章哦~

A sandbox mode for the kernel

By Jonathan Corbet
February 29, 2024
ChatGLM translation
https://lwn.net/Articles/963734/

Linux 内核遵循 monolithic 设计,这带来了一个众所周知的问题:内核中的所有代码都能访问内核整个地址空间。因此,内核中的一个 bug(例如一个不起眼的驱动程序)可能会被利用来对内核核心数据结构造成破坏。多年来,人们已经尝试了各种方法来增加内核内部的隔离程度。这些尝试中最新的一次是 Petr Tesařík 提出的"沙盒模式",它使得内核能够以安全的方式运行一些受限代码,但这个方案遇到了一些冷遇。

沙盒模式

这种新模式的目的是让内核能够以一种方式运行函数,使其不能影响内核的其他部分。在最简单的情况下,沙盒模式是通过定义一个要以这种隔离方式运行的函数来使用的:

#include <linux/sbm.h>

static SBM_DEFINE_FUNC(untrusted_func, void *input_data, void *output_data);

然后,可以使用如下序列来调用该函数:

struct sbm sbm;

sbm_init(&sbm);
result = sbm_call(&sbm, untrusted_func, SBM_COPY_IN(&sbm, input_buffer, in_size),
                            SBM_COPY_OUT(&sbm, output_buffer, out_size));

这段代码将导致调用 untrusted_func() 。在调用该函数之前,输入和输出缓冲区将先分配好,并将输入数据复制过来。成功返回后,输出数据将被复制回来, sbm_call() 将返回 untrusted_func() 的返回值。

在没有架构特定支持的情况下,沙盒模式所能做的就是这些;相关的文档正确地将这描述为“弱隔离”。它可能足以捕获输入或输出缓冲区的一个简单溢出,但它仍然不能保护内核免受来自更远范围的自由访问。

在另一系列文章中,Tesařík 提供了一组针对 x86-64 架构的钩子,用来增强沙盒,提供更强的隔离。具体来说:

  • 沙盒中的函数将使用一套独立的页表运行,限制其地址空间到相关代码、输入缓冲区(映射为只读)和输出缓冲区。因此,该函数将无法访问系统中其他地方的任何内存内容。这一变化带来了一些深远的影响;例如,如果中断到来,必须将其撤销,以便中断处理程序可以在内核地址空间内运行。

  • CPU 置于用户模式,因此它无法执行任何特权指令;该函数就像是一个用户空间进程一样运行。

  • 分配了一个单独的内核堆栈,并在该堆栈上调用函数,这样它就无法访问正常的内核堆栈。在沙盒模式生效期间,还使用了一个单独的异常堆栈。

  • 任何 CPU 故障都会立即终止沙盒并返回错误给调用者。

根据文档,沙盒模式现在提供了“强隔离”,应该足以防止沙盒中的函数访问内核的其他部分。

寻找用户

出于什么目的创建了这种模式呢?文档中说,沙盒模式是为了“解析来自不可信来源的数据,尤其是如果解析动作无法合理地由用户模式的 helper 来完成的话”,但补丁系列中没有包含实际的用户,因此无法了解预期的用户是什么样的。这自然引发了疑问。Andrew Morton评论称 API 似乎过于受限,并想知道如何才能真正完成工作;他要求提供一个例子来澄清,Greg Kroah-Hartman附和.

Tesařík 回答说,这个框架目前的实现确实“相当有限”,但他打算随着时间的推移加以扩展。稍后,他发布了一个PGP密钥解析器,作为沙盒模式内的一个示例用户,但这并没有在很大程度上提高这项工作的接受度。Dave Hansen指出,内核当前并不包含 PGP 密钥解析器,因此新的系列文章只是提出了为什么需要添加这个问题。 Hansen 说,最好是将一些现有的内核功能移入沙盒,以展示它是如何被安全地使用的。

对这个请求的回应是另一系列文章,将 AppArmor 配置文件的解析移动到沙盒中。支持这个用例需要对沙盒模式本身进行一系列更改,包括一个新的“修复”机制,旨在使从沙盒内调用特定内核函数成为可能。例如,如果沙盒内的代码需要分配内存,它可以调用 kmalloc() 。这个调用将导致一个故障,进而执行了一个代理版本的 kmalloc() ,它在调用期间将恢复内核的全地址空间。

Hansen 回应称“修复”机制看起来像是一个维护问题:“建立和维护这个代理列表将是痛苦的。人们会更改代码以调用新东西,并不断破坏这个*东西*。”他总结说,沙盒模式似乎并不是一个好主意:“我看不出有任何可行的前进方向”。他甚至没有评论在沙盒模式中添加特殊“__nosbm”标记所有可能落在一个与标记为从沙盒内调用的函数相同的页上的函数,因为这是一个似乎注定会出问题的步骤。

显而易见的结论是,沙盒模式不太可能以其当前形式进入主线。但如果有办法使内核代码隔离,那么就应该有可行的解决方案。一个可能性是使用 BPF,它旨在提供隔离;尽管 non-trivial 的 BPF 程序在验证器的验证阶段会有些棘手,但它们是从用户空间加载的,这可能使一些关注安全的人感到不安。

另一个可能性是用户模式blob特性,该特性在 4.18 内核中合并了近六年。它旨在用于类似的目的——为基于 BPF 的“bpfilter”子系统解析防火墙规则——但在主线内核中从未使用过。针对一项查询关于使用这个特性而不是新的沙盒模式,Roberto Sassu表示,安全人员对使用它并不很自信。主要担忧似乎在于,由于用户模式 blob 在单独的用户空间进程中运行,它们可能会受到用户空间的操纵;而沙盒模式完全包含在内核中,应该会更加安全。

如果完全隔离用户空间也是这项工作的要求,那么目前可能没有可行的 Linux 解决方案。对内核进行加固是一个值得追求的目标,但在创建一个既实用又可在现实世界中维护的内核时,它只是众多需要权衡的目标之一。在缺乏更好实现的情况下,沙盒模式似乎并不能提供足够的好处来证明其所需的权衡是合理的。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

0c081bde665b20af319f557765be5a6a.jpeg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值