您的位置:首页 > 其它

VIM将文件的owner从root替换成普通用户?

2012-12-27 16:52 288 查看
在stackexchange上看到了一个关于vim的很有意思的问题。详情可见如下链接。

http://unix.stackexchange.com/questions/58880/how-does-vim-steal-root-owned-files?newsletter=1&nlcode=102660%7c320e

首先使用user用户新建一个目录,然后在新建目录下,sudo touch一个文件tempfile,则tempfile属于root并且具有644权限。

接下来使用vim编辑tempfile,写点东西进去,保存之后,在用ls -li来查看信息,发现该文件已经属于user了,虽然还是保持了644权限,而且inode也保持不变。

一开始回答者给出了一个vim的操作机制,vim在操作文件时,会先将tempfile拷贝到swap文件.tempfile.swp,然后所有的操作都在.tempfile.swp上进行,当user保存文件时,vim首先尝试将.tempfile.swp的内容写回tempfile,因为权限错误,vim重试,将tempfile删除,并将.tempfile.swp重命名为tempfile。

但是用ls -li查看到的tempfile的inode并未改变,所以这种解释不成立。

通过strace观察vim调用的system call,发现该现象和swap文件并没有关系,实际上是先删除文件,又新建了一次。

9267 open("tempfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = -1 EACCES (Permission denied)   //存盘时发现无权限
9267 lstat64("tempfile", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
9267 getuid32() = 1001
9267 unlink("tempfile") = 0      //user创建的vim目录,所以即使没有对文件的写权限也可以从该目录中将文件删除(可以写目录文件)。
9267 open("tempfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 4  //因为带有O_CREAT,此时vim会新建tempfile文件,并在后续将我想要的内容写入该文件。
9267 write(4, "henghenghaha\n", 13) = 13
9267 fsync(4) = 0
9267 close(4) = 0
9267 chmod("tempfile", 0644)

使用的命令序列:

zbie@ubuntu:~$ mkdir vim
zbie@ubuntu:~$ cd vim
zbie@ubuntu:~/vim$ ls
zbie@ubuntu:~/vim$ sudo touch tempfile
[sudo] password for zbie:
zbie@ubuntu:~/vim$ ls -lrti
total 0
1488045 -rw-r--r-- 1 root root 0 2012-12-27 03:14 tempfile
zbie@ubuntu:~/vim$ strace -f -o vim.strace vim tempfile
zbie@ubuntu:~/vim$ ls -lrti
total 96
1488049 -rw-r--r-- 1 zbie zbie 87727 2012-12-27 03:15 vim.strace
1488045 -rw-r--r-- 1 zbie zbie 13 2012-12-27 03:15 tempfile

P.S.关于vim swap文件的一些解释:

http://vimdoc.sourceforge.net/htmldoc/recover.html

1. The swap file					*swap-file*

Vim stores the things you changed in a swap file.  Using the original file
you started from plus the swap file you can mostly recover your work.

The swap file is updated after typing 200 characters or when you have not
typed anything for four seconds.  This only happens if the buffer was
changed, not when you only moved around.

看起来swap只是保存了delta变化,vim错误恢复的时候,可以根据源文件和swap合并生成最新的文件。


zbie@ubuntu:~/vim$ vi a
zbie@ubuntu:~/vim$ xxd a
0000000: 6161 6161 6161 6161 610a aaaaaaaaa.

zbie@ubuntu:~/vim$ ls -lrta
-rw-r--r-- 1 zbie zbie 10 2012-12-27 03:46 a

新开一个terminal,使用vi编辑,输入bbbbbb,然后等待5s,将terminal强制关闭。

zbie@ubuntu:~/vim$ ls -lrta
-rw-r--r-- 1 zbie zbie 10 2012-12-27 03:46 a
-rw-r--r-- 1 zbie zbie 12288 2012-12-27 03:46 .a.swp

zbie@ubuntu:~/vim$ xxd .a.swp |less
0000000: 6230 5649 4d20 372e 3200 0000 0010 0000 b0VIM 7.2.......
0000010: d10a dc50 d5b4 1600 f624 0000 7a62 6965 ...P.....$..zbie
0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000040: 0000 0000 7562 756e 7475 0000 0000 0000 ....ubuntu......
0000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................
0000060: 0000 0000 0000 0000 0000 0000 7e7a 6269 ............~zbi
0000070: 652f 7669 6d2f 6100 0000 0000 0000 0000 e/vim/a.........
0000080: 0000 0000 0000 0000 0000 0000 0000 0000 ................

..............

00003e0: 0000 0000 0000 0000 0075 7466 2d38 0d55 .........utf-8.U
00003f0: 3332 3130 2322 2120 1312 5500 0000 0000 3210#"! ..U.....

...............

0002fe0: 0000 0000 0000 0000 0000 0000 6262 6262 ............bbbb
0002ff0: 6262 6262 6200 6161 6161 6161 6161 6100 bbbbb.aaaaaaaaa.

根据ls和xxd的结果,显然swap不是源文件的副本,只是代表了文件的变动。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: