![新 Linux 中系统调用调用约定发生变化的理由是什么?](https://linux22.com/image/231253/%E6%96%B0%20Linux%20%E4%B8%AD%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E8%B0%83%E7%94%A8%E7%BA%A6%E5%AE%9A%E5%8F%91%E7%94%9F%E5%8F%98%E5%8C%96%E7%9A%84%E7%90%86%E7%94%B1%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F.png)
引用自https://www.kernel.org/doc/Documentation/process/adding-syscalls.rst:
至少在 64 位 x86 上,从 v4.17 开始,不调用内核中的系统调用函数将成为硬性要求。它对系统调用使用不同的调用约定,
struct pt_regs
在系统调用包装器中即时解码,然后将处理交给实际的系统调用函数。这意味着在系统调用入口期间仅传递特定系统调用实际需要的参数,而不是始终用随机用户空间内容填充六个 CPU 寄存器(这可能会导致调用链出现严重问题)。
什么调用链中存在严重问题最后一个括号子句指的是?
对我来说,不将六个寄存器加载到系统调用的通用引导中似乎很愚蠢。强制每个系统调用包装器执行此操作会使它们变得更大,并且系统调用函数成为一种新的特殊情况,所以我想知道在未使用的参数寄存器中存在无意的用户内容的“严重问题”是什么。
答案1
问题之一并不是任意的登记值,但它们被复制到内核堆栈。因此,未使用的寄存器可用于将任意调用者控制的值写入堆栈,而无需检查。
堆栈上的这些值可能会用于更复杂的攻击。这就是为什么消除这种可能性似乎是个好主意。
Kees Cook 的 4.17 总结还提到了这些寄存器值对推测执行的可能影响。