我以普通用户身份创建一个文件testuser
:
$ cat > /tmp/zz
该文件由该用户拥有(如预期):
$ ls -lA /tmp/zz
-rw------- 1 testuser testuser 0 Feb 20 15:32 zz
现在,当我尝试将其截断为 时root
,我的权限被拒绝:
# truncate --size=0 /tmp/zz
truncate: cannot open '/tmp/zz' for writing: Permission denied
当我尝试使用 时strace
,我看到以下内容:
openat(AT_FDCWD, "/tmp/zz", O_WRONLY|O_CREAT|O_NONBLOCK, 0666) = -1 EACCES (Permission denied)
write(2, "truncate: ", 10truncate: ) = 10
write(2, "cannot open '/tmp/zz' for writin"..., 33cannot open '/tmp/zz' for writing) = 33
...
write(2, ": Permission denied", 19: Permission denied) = 19
write(2, "\n", 1
为什么 root 无权写入该文件? root 可以删除该文件,但不能写入。
答案1
这是 Linux 内核上可用的新行为4.19版本使用技巧来防止攻击/tmp/
。该选项的默认值可能稍后启用或根据发行版的不同而有所不同。
(特色)避免无意写入攻击者控制的 FIFO 或常规文件:禁止在全局可写粘性目录中打开不属于用户的 FIFO 或常规文件,除非所有者与目录或文件的所有者相同或打开的文件没有
O_CREAT
旗帜。目的是使数据欺骗攻击变得更加困难。可以通过 sysctl 分别为 FIFO (protected_fifos
) 和常规文件 ( )打开和关闭此保护protected_regular
,就像符号链接/硬链接保护一样犯罪
这是为了保护用户(包括通常具有足够权限的 root)写入某个目录中预先存在的文件,例如/tmp
或/var/tmp
当它打算自己创建该文件时。
它是通过此sysctl
切换启用的:fs.protected_regular
。人们可以通过以下方式恢复到以前的行为:
sysctl -w fs.protected_regular=0
但这可能会降低整体安全性,同时使一些奇怪的“错误”(例如OP的情况)消失。
至于为什么 root 仍然可以删除该文件,那是因为附加安全功能仅在打开文件进行写入时触发,而不是在取消链接时触发:truncate -s ...
打开文件进行写入,rm
不打开文件进行写入(它使用unlink
或unlinkat
)。