当使用 cgroups 阻止对 tty 的访问时,Bash 如何仍然写入终端?

ita*_*bby 7 linux cgroups

环境:

重现步骤:

  1. 创建设备新策略
cd /sys/fs/cgroup/devices
mkdir custom_poc
Run Code Online (Sandbox Code Playgroud)
  1. 验证哪个设备被用作 tty(多种方法):
  1. 将 tty 设备添加到devices.deny
  • 检查设备的主要和次要编号:

    ls -l /dev/pts/0
    crw--w----. 1 vagrant tty 136, 0 Mar  5 11:28 /dev/pts/0
    
    Run Code Online (Sandbox Code Playgroud)
  • 拒绝访问:

    root@centos8# echo 'c 136:0 w' > /sys/fs/cgroup/devices/custom_poc/devices.deny
    root@centos8# echo $$ > tasks
    root@centos8# echo 'a' > /dev/pts/0
    -bash: /dev/pts/0: Operation not permitted
    
    Run Code Online (Sandbox Code Playgroud)
  • 然而,即使在删除对 STDIN 设备的访问之后,我的 Bash 终端也能正常工作。这是一个简单的 whoami 的输出:

    root@centos8# whoami
    root
    
    Run Code Online (Sandbox Code Playgroud)

Sté*_*las 15

来自内核文档

实现一个 cgroup 来跟踪和强制对设备文件执行打开和 mknod 限制。

这些限制仅在打开设备文件时应用。这与大多数其他访问控制权限(例如标准 Unix 权限)相同。

以读+写模式打开文件后,您可以对其进行读取和写入。访问控制不会应用于每个read()write(),这会增加太多开销,并且可能会导致应用程序中非常令人惊讶的行为。mmap例如,当文件在内存中被 ped() 时,也很难强制执行。

在您的情况下,在应用限制之前/dev/pts/0,已打开(可能是由其父级之一,可能是终端仿真器,也许getty,也许sshd......,并且 shell 继承了文件描述符)。

类似地,在 fork 一个进程来执行时whoami,子进程会继承 fd,并且这些 fd 在执行时会被保留,whoami并且whoami只执行 awrite(1, "root\n", 5)而无需打开设备文件。

然而echo a > /dev/pts/0,shell 确实尝试打开文件来执行该重定向,但此时被阻止这样做。