有人知道为什么 rocky 不能写信吗/tmp/afile
?作为其他用户授予不稳定的权限chmod o+w
似乎也不起作用
答案1
您的期望是正确的:权限应该允许rocky
写入afile
,因为rocky
拥有文件的写入权限和所有包含目录的执行权限。然而,您在 Linux 上遇到了额外的安全强化机制。当此机制处于活动状态时,某些写入到目录中的文件粘性位被阻止。
目录上的粘滞位由 表示,t
作为列表中文件模式/权限的 10 个字符的最后一个ls -l
,并且可以使用 进行设置chmod +t
。通常,粘滞位对目录的影响是只有文件的所有者才能删除或重命名它。它不会影响写入现有文件。
然而,当fs.protected_regular
启用 sysctl 后,粘性位会带来额外的后果:用户无法打开粘性目录中的文件进行写入,除非他们拥有该文件,如果他们打开文件的方式会在文件不存在时创建它,程序通过将O_CREAT
文件传递给open
系统调用来指示这一点。请注意这里的微妙之处:正常行为仅基于文件是否存在,而强化行为基于文件不存在时是否会创建。这只会影响以可能创建文件的方式打开文件:仍然允许使用其他方式写入文件。
请注意,这不会影响没有粘滞位的目录中的文件。特别是,如果您创建一个目录/tmp/foo
并且/tmp/foo
没有粘滞位,则文件的权限将/tmp/foo
正常运行。
下表总结了在相关场景下打开文件进行写入时系统调用的行为open
(目录存在并且程序可以访问其中的文件,如果文件存在则程序对其具有写权限):
目录 | 文件 | 和O_CREAT |
没有O_CREAT |
---|---|---|---|
rwxr-xr-x (755) |
存在,可写 (666) | 好的 | 好的 |
rwxr-xr-x (755) |
不存在 | 好的 | ENOENT |
rwxrwxrwx (777) |
存在,可写 (666) | 好的 | 好的 |
rwxrwxrwx (777) |
不存在 | 好的 | ENOENT |
rwxr-xr-t (1755) |
存在,可写 (666) | 好的 | 好的 |
rwxr-xr-t (1755) |
不存在 | 好的 | ENOENT |
rwxrwxrwt 【1777】平常 |
存在,可写 (666) | 好的 | 好的 |
rwxrwxrwt 【1777】平常 |
不存在 | 好的 | ENOENT |
rwxrwxrwt (1777) 在强化 Linux 上 |
存在,可写 (666) | EACCES |
好的 |
rwxrwxrwt (1777) 在强化 Linux 上 |
不存在 | 好的 | ENOENT |
(ENOENT
是错误“没有这样的文件或目录”。EACCES
是错误“权限被拒绝”。)
sysctl fs.protected_regular=0
您可以通过(禁用)、sysctl fs.protected_regular=1
(为全局可写目录启用)或sysctl fs.protected_regular=2
(为全局可写或组可写目录启用)来控制是否启用此强化。在启动时,可以从/etc/sysctl.conf
或进行设置/etc/sysctl.d/*
。某些发行版默认启用它,而其他发行版则不启用。该protected_regular
设置适用于常规文件;有一个类似的设置命名管道。
要亲自查看这一点(如果您在 Linux 上运行并具有 root 访问权限),请以 root 身份运行以下命令:
mkdir /tmp/experiment
mkdir -m 1777 /tmp/experiment/sticky-world
mkdir -m 777 /tmp/experiment/ordinary-world
mkdir -m 1755 /tmp/experiment/sticky-user
mkdir -m 755 /tmp/experiment/ordinary-user
for d in /tmp/experiment/*; do touch $d/file; chown nobody:nogroup $d/file; chmod 666 $d/file; done
检查权限:
$ ls -l /tmp/experiment
total 16
drwxr-xr-x 2 root root 4096 Jul 3 21:10 ordinary-user
drwxrwxrwx 2 root root 4096 Jul 3 21:10 ordinary-world
drwxr-xr-t 2 root root 4096 Jul 3 21:10 sticky-user
drwxrwxrwt 2 root root 4096 Jul 3 21:10 sticky-world
$ ls -l /tmp/experiment/*/file
-rw-rw-rw- 1 nobody nogroup 0 Jul 3 21:10 /tmp/experiment/ordinary-user/file
-rw-rw-rw- 1 nobody nogroup 0 Jul 3 21:10 /tmp/experiment/ordinary-world/file
-rw-rw-rw- 1 nobody nogroup 0 Jul 3 21:10 /tmp/experiment/sticky-user/file
-rw-rw-rw- 1 nobody nogroup 0 Jul 3 21:10 /tmp/experiment/sticky-world/file
现在,作为非 root 用户nobody
,让我们运行一些代码来尝试打开文件进行写入,一次带标志O_CREAT
,一次不带标志。我使用 Perl 是因为 shell 不提供直接访问O_CREAT
(shell 写入重定向始终处于O_CREAT
启用状态,除了noclobber
启用时在某些 shell 中附加)。在强化的 Linux 上:
$ perl -w -MFcntl -e 'foreach (@ARGV) { sysopen(F, $_, O_WRONLY | O_CREAT) or warn "$_: $!\n"; close F; }' /tmp/experiment/*/file
/tmp/experiment/sticky-world/file: Permission denied
$ perl -w -MFcntl -e 'foreach (@ARGV) { sysopen(F, $_, O_WRONLY) or warn "$_: $!\n"; close F; }' /tmp/experiment/*/file
如果没有 Linux 强化,所有文件打开都会成功,因为程序有权写入文件。
如果您启用了审核,则尝试写入会/tmp/experiment/sticky-world/file
触发ANOM_CREAT
审核事件,该事件会被记录/var/log/audit/audit.log
(或这些日志位于您的发行版上的任何位置)。(这就是我发现这种 Linux 机制的方式,以前并不知道。)
答案2
由于 上的粘滞位 (+t) /tmp
。
man 1 chmod
限制删除标志或粘性位
The restricted deletion flag or sticky bit is a single bit, whose in‐ terpretation depends on the file type. For directories, it prevents unprivileged users from removing or renaming a file in the directory unless they own the file or the directory; this is called the re‐ stricted deletion flag for the directory, and is commonly found on world-writable directories like /tmp.