摘要:Linux内核中的eBPF (extended Berkeley packet filter)机制可以将用户提供的不受信任的程序安全地加载到内核中. 在eBPF机制中, 检查器负责检查并保证用户提供的程序不会导致内核崩溃或者恶意地访问内核地址空间. 近年来, eBPF机制得到了快速发展, 随着加入越来越多的新功能, 其检查器也变得愈发复杂. 观察到复杂的eBPF安全检查器存在的两个问题: 一是“假阴性”问题: 检查器复杂的安全检查逻辑中存在诸多漏洞, 而攻击者可以利用这些漏洞设计能够通过检查的恶意eBPF程序来攻击内核; 二是“假阳性”问题: 检查器采用静态检查的方式, 由于缺乏运行时信息只能进行保守检查, 可能造成原本安全的程序无法通过检查, 也只能支持很受限的语义, 为eBPF程序的开发带来了困难. 通过进一步分析, 发现eBPF检查器中的静态模拟执行检查机制代码量大, 复杂度高, 分析保守, 是引起安全漏洞和误报的主要原因. 因此, 提出使用轻量级动态检查的方式取代eBPF检查器中的静态模拟执行检查机制, eBPF检查器中原本由于模拟执行而存在的漏洞与保守检查不复存在, 从而能够消除诸多上述的“假阴性”和“假阳性”问题. 具体来说, 将eBPF程序运行在内核态沙箱中, 由沙箱对程序运行时的内存访问进行动态检查, 保证程序无法对内核内存进行非法访问; 为高效实现轻量化的内核态沙箱, 利用新型硬件特性Intel PKS (protection keys for supervisor)进行零开销的访存指令检查, 并提出高效的内核与沙箱中eBPF程序交互方法. 评测结果表明, 所提方法能够消除内核eBPF检查器中的内存安全漏洞(自2020年以来该类型漏洞在eBPF检查器的总漏洞中占比超过60%); 即使在吞吐量较高的网络包处理场景下, 轻量化内核沙箱带来的性能开销低于3%.