为什么 linux 进程的所有允许功能并非一直有效?

hum*_*ace 5 security capabilities

man 7 capabilities linux 机器上的进程的能力被记录为三个掩码的文档:

  • 允许
  • 有效的
  • 可继承的

我知道可继承掩码在多大程度上发挥作用,但我不清楚为什么似乎需要/用例将允许的功能与有效的功能分开?

是否存在某些允许的功能无效的情况?哪个可以为这个问题的答案增添趣味?

奖金回合

考虑到某些能力无效但仍被允许的情况,是什么阻止了流程使它们有效?至少在我看来,流氓进程会毫不犹豫地将所有允许的内容设置为有效,并且通常甚至试图进一步提升特权?

Ste*_*ris 6

有效/允许的能力之间的差异类似于 setuid 程序中真实/有效 UID 之间的差异。这个想法并不是要阻止流氓应用程序升级权限(您首先不会授予它们权限,就像您不会设置它们一样),而是允许程序以最小的权限运行,并且仅在必要时升级。这有助于最大限度地减少错误的影响

一个非常人为的例子:我想要一个程序,它可以让我向用户拥有的进程发送 SIGHUP ,或者允许上帝用户向init.

该程序在文件上设置了 CAP_KILL 功能。

伪代码可能类似于:

drop_effective CAP_KILL
repeat forever:
  get_process_id_from user
  if process_id==1 and user_is_God:
    set_effective CAP_KILL
    kill(-1,1)
    drop_effective CAP_KILL
 else:
   kill(-1,process_id)
Run Code Online (Sandbox Code Playgroud)

这里明显的错误是,我没有首先检查是否允许用户发送信号。因为我已经删除了有效的 CAP_KILL 权限,所以我不会允许用户终止除他们自己的进程之外的进程。

非常做作,当然!但其想法是尽可能以“最小权限”运行,并且仅在必要时启用权限。

现在,这不一定能防止缓冲区溢出攻击,因为注入的代码可以启用允许的权限,因此功能感知代码也应该在不再需要时删除允许的权限;例如,网络服务器在绑定到端口 80 后可能会删除 CAP_NET_BIND_SERVICE。您无法启用不在允许范围内的内容!


der*_*ert 4

快速假设它可能有用:您希望用户能够复制(读取)系统上的任何文件,但不能更改(写入)它们。您可以有一个程序CAP_DAC_OVERRIDE(忽略权限检查),其工作方式类似于cp. 但为了确保不允许备份用户覆盖任意文件,它可以CAP_DAC_OVERRIDE在打开每个输出文件之前从有效集中删除。

至于你的额外问题:如果可以运行任意代码,没有什么可以阻止它们恢复有效。但它在发生其他妥协的情况下可能很有用(例如,您说服程序尝试通过符号链接攻击覆盖任意文件)。