VIM將文件的owner從root替換成普通用戶?


在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不是源文件的副本,只是代表了文件的變動。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM