我想了解为什么 sudo 在这里没有权限
touch fred.txt
/tmp$ ls -la fred.txt
-rw-rw-r-- 1 me me 0 Dec 12 15:40 fred.txt
/tmp$ sudo -i
~# cd /tmp
/tmp# echo hi >> fred.txt
-bash: fred.txt: Permission denied
/tmp# chmod 666 fred.txt
/tmp# ls -la fred.txt
-rw-rw-rw- 1 me me 0 Dec 12 15:40 fred.txt
/tmp# echo hi >> fred.txt
-bash: fred.txt: Permission denied
id
uid=0(root) gid=0(root) groups=0(root)
据我了解,权限 666 应授予所有者、组和其他人员对文件的读写权限。根据 id 命令显示,以 root 身份运行的 sudo 可以在“其他”权限下访问该文件。
我在这里误解了什么?
答案1
这与这次提交在 Linux 内核中。通常/tmp
是“全球可写的”(“全球”在这里表示“其他”)并且是“粘性的”:
$ stat /tmp/
...
Access: (1777/drwxrwxrwt) Uid: ( 0/ root) Gid: ( 0/ root)
...
chmod(2)
:
...
S_ISVTX (01000) sticky bit (restricted deletion flag, as described in unlink(2))
...
S_IWOTH (00002) write by others
...
正如提交消息中提到的,它并不完全阻止你写入受影响的文件,而是阻止你使用 打开这样的文件O_CREAT
,这是open()
通常设置为在目标尚不存在时触发文件创建。因此,您仍然可以使用未设置的标志写入受影响的文件(可以使用 完成dd
):
# ls -l /tmp/meh
-rwxrwxrwx 1 tom tom 0 Dec 12 17:33 /tmp/meh
# id
uid=0(root) gid=0(root) groups=0(root)
# echo test | dd of=/tmp/meh oflag=append conv=notrunc
dd: failed to open '/tmp/meh': Permission denied
# echo test | dd of=/tmp/meh oflag=append conv=notrunc,nocreat
0+1 records in
0+1 records out
5 bytes copied, 9.4981e-05 s, 52.6 kB/s
#
请注意,这纯粹是关于是否设置了标志,而不是是否需要创建文件,因为在关注的情况下,该文件始终存在。
另请注意,正如提交消息中提到的,该文件无法O_CREAT
使用只是因为它不属于试图打开它的用户 ( root
),而且因为它的所有者 ( ) 与目录的tom
所有者 ( ) 不同( )。如果由原先的所有者拥有,则应该是root
/tmp
/tmp/
tom
/tmp/meh
root
有能力的用 打开它O_CREAT
。
另请参阅这次提交在 systemd 中启用了采用它的发行版的“保护”:
# sysctl fs.protected_regular
fs.protected_regular = 1
请注意,相关的 sysctls也可以设置2
(或0
)。