系统调用是用户程序有意影响 Linux 内核状态的唯一方法吗?

系统调用是用户程序有意影响 Linux 内核状态的唯一方法吗?

我认为用户程序可以通过多种方式有意影响 Linux 内核的状态。

  1. 通过调用系统调用;
  2. 通过调用映射()写入已经映射到内核的内存;
  3. 通过加载内核模块插入模块

我想不出任何其他办法。不考虑硬件中断,因为它们不是由用户程序启动的。我认为两者映射()插入模块正在使用系统调用,因此用户程序可能必须依赖系统调用来影响内核的状态。我对么?

如果我是正确的,那么假设内核中存在一些漏洞,并且恶意用户程序想要利用它们来攻击内核。鉴于我们的验证总能说出真相,是否可以验证每个系统调用来防御此类攻击?

答案1

碰巧还有另外一个重要的与内核的接口:/proc/sys虚拟文件系统。虽然它们不保存常规文件,但它们的内容是通往内核的直接门户:对它们进行操作就是直接对内核分配的内存进行操作。例如,如果您想删除所有内存缓存,您可以使用...

echo 3 > /proc/sys/vm/drop_caches

...内核会立即做出反应。

现在,程序需要系统调用才能与文件系统交互:、、、open等等...但是,仍然有一种方法可以跟踪所有这些系统调用:内核提供了一种跟踪机制。更具体地说,系统调用的跟踪由 处理。该虚拟目录包含每个系统调用的两个子目录。例如,通过 open 系统调用,我们有:readwrite/sys/kernel/debug/tracing/sys/kernel/debug/tracing/events/syscalls

  • sys_enter_open
  • sys_exit_open

在这些目录中,您将找到一个名为enable.如果它包含“1”,则open正在跟踪关联的事件(进入或退出呼叫)。我通常使用该enter事件,但您可以选择更适合您需要的事件。

激活系统调用跟踪后,您将在 处找到日志/sys/kernel/debug/tracing/trace。现在,请记住打开使用系统调用很多。它是程序和文件之间的最终网关,文件可以是 Linux 系统上的任何东西。还要记住...

UNIX 的设计初衷并不是为了阻止用户做愚蠢的事情,因为这也会阻止他们做聪明的事情。 — 道格·格温

虽然您可以监视系统上发生的情况,但内核不会努力阻止用户做愚蠢的事情:这更多是系统管理员工作的一部分。

管理跟踪机制需要 下的权限/sys/kernel/debug/tracing/trace。您可能需要成为 root 才能激活和操作跟踪。完成后不要忘记禁用跟踪。

答案2

这取决于。 “验证”是什么意思?如果你只是想监视某个进程触发的系统调用,那么这是可能的......通常......但是如果你想深入挖掘,那么你就会遇到麻烦......我还没有听说过任何可以做到这一点的工具。

您可以使用 strace 来查看某个特定进程正在触发哪些系统调用。当然,您必须以 root 身份运行它...但是,您不会总是成功运行 strace,因为它可以保护应用程序不监视其活动 - ptrace 调用会被丢弃。尝试在 chromium 上进行 stracing - 你会看到的;)

如果 strace 还不够,我想您可以分解每个应用程序二进制文件并手动检查它的作用。这应该很有趣:)(或者,当然,您可以获取源代码并将所有这些算法视为人类可读的文本..但是当您可以使用 ASM 时为什么要选择更简单的方法:))

答案3

这是一个很好的初步近似。用户空间和内核之间有很强的界限,并且最多交互必须涉及系统调用。该模型有助于理解为什么strace作为故障排除工具如此强大。

大量内核漏洞可归咎于缺乏此类验证。只要您了解此类验证的成本极高即可。对于可用于直接硬件访问等的语言来说尤其如此。当使用像 C 这样的原始语言时更是如此,因为语言设计为此类验证提供的帮助比人们想要的要少得多。

一个众所周知的缓解措施是使用微内核。更少的代码允许更多的验证。通过微内核架构,可以显着地更加包含大量设备驱动程序代码。如果您有足够的 IOMMU 和 MMU,也许完全如此。

然而,这种说法并不正确。

如果您使用正确的术语进行搜索,我认为您可以找到许多作为反例的漏洞。错误可能会在尚未映射的内存范围上生成:

“Linux 内核 i386 SMP 页面错误处理程序权限升级”[安全团队]。

一般来说,您需要验证所有特定于体系结构的故障代码。这包括接收系统调用和页面错误的代码。然而,还有其他类型的错误,例如浮点异常(除以零)。

此外,硬件细节也可能会产生漏洞。当您尝试验证代码时,可能不知道具体的硬件详细信息。

https://en.wikipedia.org/wiki/Row_hammer

相关内容