vim如何窃取根目录拥有的文件?


39

见证以下内容:

sh-3.2$ mkdir testcase
sh-3.2$ cd testcase
sh-3.2$ sudo touch temp
sh-3.2$ ls -al
total 0
drwxr-xr-x   3 glen  staff  102 19 Dec 12:38 .
drwxr-xr-x  12 glen  staff  408 19 Dec 12:38 ..
-rw-r--r--   1 root  staff    0 19 Dec 12:38 temp

sh-3.2$ echo nope > temp
sh: temp: Permission denied

sh-3.2$ vim temp
# inside vim
itheivery
# press [ESC]
:wq!
# vim exits

sh-3.2$ ls -al
total 8
drwxr-xr-x   3 glen  staff  102 19 Dec 12:38 .
drwxr-xr-x  12 glen  staff  408 19 Dec 12:38 ..
-rw-r--r--   1 glen  staff    7 19 Dec 12:38 temp

vim以某种方式获取了该根目录拥有的文件,并将其更改为用户拥有的文件!

这似乎仅在用户拥有目录的情况下有效-但仍然感觉它不可能。谁能解释这是怎么做的?

Answers:


51

glen目录的所有者(请参阅.清单中的文件)。目录只是文件列表,您有权更改此列表(例如,添加文件,删除文件,更改所有权以使其再次成为您的所有权,等等)。您可能无法直接更改文件的内容,但是可以整体上读取和取消链接(删除)该文件,然后添加新文件。1仅目睹了之前和之后,这似乎是文件已被更改。

Vim使用交换文件并在水下移动文件,因此可以解释为什么似乎要像在Shell中一样写入同一文件,但这不是同一回事。2

因此,Vim的作用归结为:

cat temp > .temp.swp          # copy file by contents into a new glen-owned file
echo nope >> .temp.swp        # or other command to alter the new file
rm temp && mv .temp.swp temp  # move temporary swap file back

1 这是Windows和Unices之间在文件权限处理方面的重要区别。在Windows中,通常无法删除您没有写许可权的文件。

2更新:如注释中所述,Vim实际上不会通过这种方式更改所有权,因为temp文件上的inode编号不会更改(ls -li前后比较)。使用strace我们可以确切地看到vim它的作用。有趣的部分在这里:

open("temp", O_WRONLY|O_CREAT|O_TRUNC, 0664) = -1 EACCES (Permission denied)
unlink("temp")                               = 0
open("temp", O_WRONLY|O_CREAT|O_TRUNC, 0664) = 4
write(4, "more text bla\n", 14)              = 14
close(4)                                     = 0
chmod("temp", 0664)                          = 0

这表明它仅取消链接,但不关闭文件描述符temp。它只是覆盖其全部内容(more text bla\n以我为例)。我猜这解释了为什么inode数不改变。


3
FWIW您可以通过ls -il在...之前和之后运行来验证此情况是否发生。如果temp的inode编号已更改,则说明它是具有相同名称的另一个文件。
没用的2012年

3
可以添加rm实际上并没有删除文件,而是删除了指向文件的链接,并且在链接数减少到0之前不会删除文件。rm只是删除目录中文件的条目。如果root拥有另一个目录中文件的另一个链接(硬链接),则用户无法删除该文件。
gerrit 2012年

1
@Useless我尝试了,尽管所有者和时间戳发生了变化,但数量没有变化!
amyassin

1
@amyassin你是对的!我已经用解释的摘要摘录了我的答案。
gertvdijk 2012年

1
除了有关Windows与Unix权限的注释外,如果要在Unix中具有类似Windows的行为,则可以创建一个由root(或应该具有通用remove / rename / etc权限的其他用户)拥有的目录,并设置粘性在目录上。这样,用户将只能删除自己的文件。
马修·克鲁姆利

16

之前:

-rw-r--r-- 1 root staff 0 19 Dec 12:38 temp

后:

-rw-r--r-- 1 glen staff 7 19 Dec 12:38 temp

vim不会突破许可障碍。仔细查看一下列出的文件信息,然后您会发现vim实际上删除了原始文件(因为尽管您不能更改其内容,但您有权删除该文件),然后创建了一个自己的新文件(看到所有者不再是“根”)。

当您在vim中编辑原始文件时,它会警告您正在更改只读文件。因此,当您键入命令:wq!(强制操作)时,vim唯一能做的就是删除现有文件并创建一个具有相同名称的新文件。

希望能有所帮助。


1

使用-i选项ls来查看索引节点号,它是文件或其他对象的唯一标识符(在文件系统内)。

您将看到该文件已替换为其他对象:索引节点号可能会更改。

看到相同的inode号并不能证明:可以回收inode号。如果我们删除文件的最后一个链接,然后创建一个新文件,则可能会得到一个具有相同inode编号的文件。但是,如果在创建新文件后删除了旧文件,则不会发生这种情况。例如mv file file.tmp; touch file; rm file.tmp。我怀疑vim实际上执行了与此类似的操作echo new_content > tmpfile; mv tmpfile file。该mv操作将转换为rename系统调用,因此,索引节点号的分配取决于文件系统如何实现重命名以解除目标的链接。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.