关注了就能看到更多这么棒的文章哦~
KRSI — the other BPF security module
By Jonathan Corbet
December 27, 2019
BPF virtual machine最开始的应用场景,除了网络领域之外,也针对seccomp()系统调用来实现访问控制策略。不过在那之后,BPF在security领域就没有太多其他贡献了,尽管kernel里面,BPF本身已经从seccomp()所使用的class BPF演变成了extended BPF。其实这个期间有很多security相关的BPF工作在做,3年前LWN就介绍过Landlock security module,还有在9月份的时候LWN也介绍了kernel runtime security instrumentation (KRSI) patch set。KP Singh最近发出了最新版本的KRSI patch set,因此我们可以再来仔细谈一下这个话题了。
KRSI作为Linux security module来实现的,可以进行access-control决策,不过access control其实并不是KRSI的核心目标。KRSI其实是用来对系统整体的行为进行监测来检测是否有攻击在进行。所以某种意义上来说,KRSI可以看做是kernel里的audit机制的一个扩展,利用BPF来扩大audio子系统的可配置性。
KRSI逻辑本身非常好理解:它会允许拥有合适权限的用户来在Linux security module子系统里面的几百处hook位置加载BPF program。为了让这个操作更加便捷,KRSI在/sys/kernel/security/bpf下面提供了一系列文件系统接口,针对每个hook都有一个文件节点。可以使用bpf()系统调用来把BPF program(属于新增的BPF_PROG_TYPE_LSM类型)挂载到上述hook的位置。对任何一个hook,都可以挂载多个BPF program。每当某个security hook被触发的时候,所有挂载在这里的BPF program都会被依次调用。只要任意一个BPF program返回了error status,都会拒绝这次请求。
许多读者可能都会认为这个机制看起来非常像Landlock。确实基本概念很类似,都是在security-module hook的位置挂载BPF program,不过深层次来说目标是不一样的,因此导致实现方式也很不相同。KRSI是一个供系统管理员使用的工具,供他们来监测系统的整体行为,在加载BPF program的时候需要CAP_SYS_ADMIN权限。而Landlock则是为了让普通用户(非特权用户)把他们运行的程序放到sandbox里面,所以在Landlock里面加载BPF program的时候不需要特别权限。
这里的区别也就会影响这些module如何执行。举例来说,如果user space发起了一个mprotect()操作,那么kernel会调用如下函数:
int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
unsigned long prot);
KRSI会把这里的3个参数都直接传递给所有挂载上来的BPF program,这些program都可以利用vma指针来获取到那些受影响的memory区域。他们也可以利用vma->vm_mm来获取到本进程的top-level memory-management data (即mm_struct结构)。总之,很多信息都会被这些BPF program看到。
Landlock则不同,因为landlock的hook都在普通权限用户控制之下,因此不可以允许它们查看kernel里的那些数据结构。所以Landlock针对mprotect()的hook会得到这么一个结构:
struct landlock_ctx_mem_prot {
__u64 address;
__u64 length;
__u8 protections_current;
__u8 protections_requested;
};
换句话说,传入这个hook的信息包含的都是user space早已知道的信息,不会额外泄露信息。这样针对它的目标应用场景来说,会非常安全,但是对于系统整体监测的目标来说还是太受限了。
在speculative-execution漏洞为人们所知之后,以及其他一些相关因素,导致人们慢慢的开始怀疑是否真的可能实现让普通用户在kernel里执行BPF代码。BPF开发者自己基本倾向于不可能安全,已经在调整他们原定的让普通用户执行BPF的计划了。实际上,哪怕Landlock的作者Mickaël Salaün现在也觉得“把eBPF暴露给恶意进程之后很难保证安全性”。他还说:“我在开发一版不依赖eBPF的Landlock,还要能依然具备此前设计的特点:要能让普通用户使用而不违背安全性,模块化,可以动态更新。很快我会发出来给大家看。”
所以,虽然人们很希望看到KRSI和Landlock能互相竞争,不过可惜并不是这么回事。
KRSI目前其实没有太多的原则性的反对意见。Casey Schaufler提过一个问题,是采用这种方式无法避免的一个问题:“这个方案会把LSM hook暴露出来成为external API。也就是说我们今后不能再修改或删除这些hook了。”围绕BPF经常会有API变动问题,尤其是在tracing这一领域。因此提出这个问题,并不出乎大家的意料。Singh回答说:“我们不打算把LSM hook暴露成为stable API,会要求eBPF program来自己针对变化后的API来自己修改、适应。”。不过,人们已经多次强调,这种对eBPF program开发者的要求,并不会凌驾于kernel stable API的规则之上。鉴于KRSI hook所具有的强大能力,很可能会有更多开发者来利用它。如果有些不相关的改动导致BPF program无法使用了,很有可能这个patch会被revert掉。
此外,人们可能会认为这类API变动导致的问题在KRSI里面可能比tracepoint里更严重。tracepoint加入kernel的一个主要目的就是暴露特定信息给user space,而security-module hook则是用在kernel内部使用的。他们会采用kernel内部的一些结构、格式来暴露许多信息,这些信息甚至连特权用户都不应该看到。这个特点会导致这些接口在kernel内部数据结构变动的时候都会随着变动,导致BPF program出错。security hook本身并不经常修改,不过还是会有这种情况出现的。开发者对于这种今后再也不能变动的东西,通常都处理不太好。
ABI问题可能会成为合入KRSI的最大障碍,尽管在tracing领域目前还没有因为这类问题而阻碍合入。随着这个功能扩散开来,我们很期待看到会发生什么。KRSI肯定是有用的,不过长期来说他会带来什么问题,目前还看不清楚。
全文完
LWN文章遵循CC BY-SA 4.0许可协议。
欢迎分享、转载及基于现有协议再创作~
长按下面二维码关注,关注LWN深度文章以及开源社区的各种新近言论~