我以普通用户的身份创建一个文件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 可以删除文件,但不能写入。
这是自4.19 版以来 Linux 内核上提供的一种新行为,用于防止使用
/tmp/
技巧的攻击。该选项的默认值可能已在以后启用,或者根据分布而有所不同。这是为了保护用户(包括通常始终具有足够权限的 root 用户)写入目录中的预先存在的文件,
/tmp
或者/var/tmp
当它打算自己创建它时。它通过此
sysctl
切换启用:fs.protected_regular
。可以通过以下方式恢复以前的行为:但这可能会降低整体安全性,同时使像 OP 案例这样的一些奇怪的“错误”消失。
至于为什么root仍然可以删除该文件,那是因为仅在打开文件进行写入而不是取消链接时触发了附加安全功能:
truncate -s ...
确实打开文件进行写入,rm
不(它使用unlink
或unlinkat
)。