root 的组权限在 /tmp 中不起作用

mxm*_*ehl 16 arch-linux permissions mount tmpfs manjaro

我在 /tmp 目录中遇到了奇怪的行为。虽然属于一个组的用户有权限读取/写入文件,他不能这样做。

在这个例子中,我/tmp/test.txt以 user 的身份创建了一个新文件max。我给它777组的权限,使该文件所属的组root,但用户root仍无法对其进行编辑。

su max
touch /tmp/test.txt
chmod 777 /tmp/test.txt

su root
chown max:root /tmp/test.txt

# ls -l /tmp/test.txt 
-rwxrwxrwx 1 max root 0 26. Feb 12:08 test.txt

# echo "foobar" > /tmp/test.txt
bash: /tmp/test.txt: Permission denied
Run Code Online (Sandbox Code Playgroud)

当移动test.txt到不同的目录时,一切都按预期工作。

/tmp 是通过以下选项通过 fstab 挂载的 tmpfs:

tmpfs       /tmp    tmpfs   nodev,nosuid,size=5G    0 0
Run Code Online (Sandbox Code Playgroud)

运行时ls -l /,tmp 文件夹如下所示:

drwxrwxrwt  20 root root   640 26. Feb 12:01 tmp/
Run Code Online (Sandbox Code Playgroud)

我正在运行 Manjaro,它是 Arch Linux 的衍生产品。

我在安装 tmpfs 时做错了什么吗?

fra*_*san 23

你是显示的行为似乎依赖于fs.protected_regularLinux内核参数,随着推出fs.protected_fifos这次提交(在4.19版本的融合,我相信),目的是修复安全漏洞。

提交消息的摘录(强调我的):

namei:允许 FIFO 和常规文件的受限 O_CREAT

不允许在世界可写粘性目录中打开不属于用户的 FIFO 或常规文件,除非所有者与目录的所有者相同,或者在没有 O_CREAT 标志的情况下打开文件。目的是使数据欺骗攻击更加困难。...

同一提交消息还报告了相关的常见漏洞和暴露 (CVE) 编号列表。

因此,如果userXroot授予或以其他方式授予对 的写访问权限/tmp/file,并且该/tmp目录是设置了粘滞位的全局可写目录,则file只有在以下情况下它们才能打开以进行写入:

  • userX是 的所有者file;或者
  • 这两个file和目录/tmp由同一用户拥有。

在您的测试中,对root具有写权限/tmp/test.txt,但不是文件的所有者,也不具有/tmp/test.txt/tmp相同的所有者(分别为maxroot)。

该问题似乎与/tmp安装方式完全无关。

相关文档位于Documentation/sysctl/fs.txt

protected_fifos:

此保护的目的是避免无意写入攻击者控制的 FIFO,程序希望在该 FIFO 中创建常规文件。

...

protected_regular:

这种保护类似于protected_fifos,但它避免写入攻击者控制的常规文件,程序希望在该文件中创建一个。

设置为“0”时,写入常规文件不受限制。

当设置为“1”时,不允许 O_CREAT 打开我们在世界可写粘性目录中不拥有的常规文件,除非它们由目录的所有者拥有。

当设置为“2”时,它也适用于组可写粘性目录。

也就是说,可以使用以下命令禁用上述保护:

sysctl fs.protected_regular=0
Run Code Online (Sandbox Code Playgroud)

一些测试来支持我们的假设:

$ su - root
# sysctl fs.protected_regular
fs.protected_regular = 1
# cd /
# mkdir test
# chmod 1777 test
# su - otheruser
$ echo hello >/test/somefile
$ exit
logout
# cat /test/somefile
hello
# ls -lah test/somefile
-rw-r--r-- 1 otheruser otheruser 6 Feb 26 17:21 test/somefile
# echo root >>test/somefile
-bash: test/somefile: Permission denied
# sysctl fs.protected_regular=0
fs.protected_regular = 0
# echo root >>test/somefile
# cat /test/somefile
hello
root
# sysctl fs.protected_regular=1
fs.protected_regular = 1
# echo root >>test/somefile
-bash: test/somefile: Permission denied
# chmod 0777 /test/
# echo root >>test/somefile
# cat test/somefile 
hello
root
root
Run Code Online (Sandbox Code Playgroud)

fs.protected_hardlinks和不同fs.protected_symlinksfs.protected_regular并且fs.protected_fifos在内核代码中默认不启用。
启用它们是向后不兼容的更改(正如您在此评论中提供的示例所指出的那样),据我所知,systemd在版本 241 中使用了最近的 commit

致谢:感谢JdeBP指出正确的方向并对问题发表评论

  • Linus 的请求“不要破坏用户空间!”发生了什么? (2认同)
  • 用户空间在这里没有被破坏,如果用户空间设置了一个标志,后来又破坏了用户空间,那么这是用户空间的错,而不是Linux的错 (2认同)