Linux
當使用 cgroups 阻止對 tty 的訪問時,Bash 如何仍然寫入終端?
環境:
- 作業系統:CentOS 8(generic/centos8 Vagrant box)
- 虛擬化:VMware-Workstation 16.1.0 build-17198959
重現步驟:
- 創建設備新策略
cd /sys/fs/cgroup/devices mkdir custom_poc
- 驗證哪個設備被用作 tty(多種方法):
- 使用 tty:
root@centos8# tty /dev/pts/0
- 獲取過程標準輸入:
ls -l /proc/$$/fd/{0,1,2} lrwx------. 1 root root 64 Mar 5 11:25 /proc/2446/fd/0 -> /dev/pts/0 lrwx------. 1 root root 64 Mar 5 11:25 /proc/2446/fd/1 -> /dev/pts/0 lrwx------. 1 root root 64 Mar 5 11:25 /proc/2446/fd/2 -> /dev/pts/0
- 將 tty 設備添加到
devices.deny
:
- 檢查設備主要和次要編號:
ls -l /dev/pts/0 crw--w----. 1 vagrant tty 136, 0 Mar 5 11:28 /dev/pts/0
- 拒絕訪問:
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
- 但是,即使在刪除對 STDIN 設備的訪問之後,我的 Bash 終端也能正常工作。這是一個簡單的 whoami 的輸出:
root@centos8# whoami root
從核心文件:
實現一個 cgroup 來跟踪和強制對設備文件的open和 mknod 限制。
這些限制僅適用於打開設備文件。這與大多數其他訪問控制權限(例如標準 Unix 權限)相同。
以讀寫模式打開文件後,您可以對其進行讀寫。沒有對每個
read()
and應用訪問控制write()
,這會增加太多成本,並且可能會在應用程序中導致非常令人驚訝的行為。mmap
例如,當文件在記憶體中是 ped()時,也很難強制執行。在您的情況下,在您應用限制之前,
/dev/pts/0
已打開(可能由其父級之一,可能是終端仿真器,可能getty
,可能sshd
…,並且 shell 繼承了文件描述符)。類似地,在派生一個要執行的程序時
whoami
,子程序繼承 fds,並且這些 fds 在執行時被保留,whoami
並且whoami
只是在write(1, "root\n", 5)
不打開設備文件的情況下執行。但是
echo a > /dev/pts/0
,shell 確實會嘗試打開文件以執行該重定向,並且在此時被阻止這樣做。