如果该文件是 root 使用以下命令创建的纯文本文件:
echo 'foo' > ./file.txt
你的ls -l
是:
-rw-r--r-- root root ./file.txt
但作为普通用户,我可以使用vim保存:w!
或使用sed命令来更改此设置,当发生这种情况时,拥有此文件的用户和组将更改为:
-rw-r--r-- user user ./file.txt
我注意到,当删除其他人的读取权限后,chmod o-r ./file.txt
我无法再进行更改,但是当恢复时,chmod o+r ./file.txt
我可以再次进行更改。
这里发生了什么?为什么“其他”读取权限使我能够更改 root 拥有的文件并更改用户和组所有权?
为什么会发生这种情况?
PS:我使用的是Debian SID。
发生这种情况是因为两件事:
vim
(至少在这种情况下)并且sed
,在进行就地编辑时,实际上删除原始文件,然后创建一个同名的新文件。删除文件的能力取决于包含该文件的目录的权限,而不是文件本身的权限。
因此,这里发生的情况是您对该目录具有写权限,这意味着您可以更改目录的内容,包括删除和创建文件。因此,当您运行
sed -i
或保存时:w!
,您将删除原始文件,然后创建一个新文件。这也是所有权发生变化的原因:这实际上是一个不同的文件。您可以通过在编辑之前和之后检查文件的索引节点来演示这一点:
在这些命令之后,我的普通用户
file
在具有写入权限的目录中拥有 root 拥有的。foo/
现在,让我们使用ls -i
检查 inode,然后进行更改sed
并再次检查:您还可以通过运行看到
vim
做同样的事情然后编辑文件并保存为
:w!
. 在您的 中strace.out
,您将看到:因此,该文件首先被删除 (
unlink("file")
),然后创建一个同名的新文件 (open("file", O_WRONLY|O_CREAT|O_TRUNC, 0644)
),并将我所做的修改写入其中 (write(4, "bar\n", 11)
)。正如您在上面看到的,inode 发生了变化:这是一个同名的新文件。因此,您实际上并没有更改您没有写访问权限的文件,您更改了您有写访问权限的目录,方法是删除该目录中的文件,然后在该目录中创建一个与该目录同名的新文件。老的。
我在这里回答了类似的问题: https: //askubuntu.com/a/815849/85695。
vim
无法修改该文件,但如果它对该文件链接到的目录具有写访问权限,并且t
未为该目录设置该位,则它可以删除该文件并用您拥有的新副本替换它。为了防止这种情况,
root
可以immutable
(chattr +i
) 或append-only
( ) 标志(然后甚至无法删除它)chattr +a
root
root
父目录具有写入权限(仅由用户拥有root
和位; ,)w
chown root:
chmod u=rwx,go=rx
root
,可能由其他人写入,但在权限中具有t
(限制删除²)位 (chmod o+t
)(因此用户只能删除/重命名他们拥有的文件)。/a/b/file
¹ 请注意,对于名为if 的文件user
具有对 的写访问权限/a
,则 then 也可以重命名/a/b
为/a/b.old
并在其中重新创建自己的/a/b
和。/a/b/file
² 您可能听说过该位的粘性位术语,但这是在应用于常规可执行文件时(并且仅在非常旧的系统上),其中指示(用于指示)系统将可执行文件的文本保留在内存中。当应用于目录时,该位具有不同的不相关含义。