Vimはファイルのアクセス許可を壊すことができますか?


8

先日、いつものようにVimを使用していて、何か奇妙なことに気づきました。これが私がしたことです:

~$ touch testfile
~$ ls -l | grep testfile
-rw-r--r-- 1 username groupname 0 Jul 23 10:00 testfile
~$ vim testfile

次に、変更を加え、保存してで終了しました:wq。かなり普通。その後、ただし:

~$ sudo chown root:root testfile
~$ sudo chmod 644 testfile
~$ sudo -k
~$ ls -l | grep testfile
-rw-r--r-- root root 0 Jul 23 10:02 testfile
~$ vim testfile

したがって、rootはr / wアクセスを持ち、他のすべてのユーザーは読み取りのみを行う必要があります。ファイルを編集して保存してください-できません。すばらしい。意図したとおりに機能している。ただし、で保存した場合:w!、vimは何らかの形でファイルの所有権をusername:usergroupに戻し、ファイルが保存されます。あなたがこれをしたとしても:

~$ sudo chmod 444 testfile
~$ sudo -k
~$ ls -l | grep testfile
-r--r--r-- 1 root root 0 Jul 23 10:06 testfile
~$ vim testfile

引き続き:w!!で上書きできます。何が起こっている?このようにして、vimはファイルの所有権と許可の法則をどのように破ることができますか?私はvimでヘルプページを見て、:help :wこれを見つけました:

:w[rite]! [++opt]    Like ":write", but forcefully write when 'readonly' is set or there is another reason why writing was refused.
                     Note: This may change the permission and ownership of the file and break (symbolic) links. Add the 'W' flage to 'cpoptions' to avoid this.

以前はすべきでないときにvimでファイルに書き込むことができなかったので、私の質問の真の核心は、どうすればvimでファイルを編集不可にできるのか、そしてなぜファイルに基づいていないのかということです。私が期待するようなシステム権限、および他のエディター(gedit、nano)が使用できないファイルを編集するためにvimが使用しているメカニズムは何ですか?

編集:私がこれを試したコンピュータは、Linuxカーネル3.15.5-2-ARCHを使用しています。Vimのバージョン番号は7.4.373-1で、それはによってインストールされたものですpacman-私は特別なオプションを使用して最初からコンパイルしていません。



問題のコマンドを使用してもう一度試したところ、同じように発生しました。これはプラットフォームに依存している可能性があるため、質問を編集して自分のコンピューターの詳細を追加します。
zrneely 2014

私の最初の直感は、書き込みアクセス権があるディレクトリ内のファイルの所有権を変更できることです。しかし、そうではないようです。CAP_CHOWNを呼び出すにはが必要ですchown(2)。ちなみに、私はvim 7.4でDebianを再現できます。
ボブ

回答:


10

現在のパスは~、ユーザーのホームディレクトリです。そのディレクトリへの書き込み権限が必要です。

別の方法で考えてみてください。ディレクトリに対する読み取りと書き込みのアクセス許可がある場合、ファイルのコピー、古いファイルの削除、新しいアクセス権の変更を別のアクセス許可で行うのはなぜですか。

これはまさにvimが行うことです!


たとえば、straceでvimを実行すると、次のようになります。

open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = -1 EACCES (Permission denied)
lstat("testfile", {st_mode=S_IFREG|0644, st_size=10, ...}) = 0
getuid()                                = 1000
unlink("testfile")                      = 0
open("testfile", O_WRONLY|O_CREAT|O_TRUNC, 0644) = 3
write(3, "ffjidfjds\n", 10)             = 10
fsync(3)                                = 0
close(3)                                = 0
chmod("testfile", 0644)                 = 0

このログに基づいて、次のプロセスを推測できます。

以前のいくつかの権限チェック(およびchown試行など)は、簡潔にするために省略されています。

  1. open 書き込み用にファイルを開こうとしました(失敗:権限が拒否されました)
  2. lstat ファイルの所有者を確認してください
  3. getuuid 現在のユーザーIDをチェックして、ファイル所有者と一致するかどうかを確認します
  4. unlink ファイルを削除します(これは、ディレクトリに対する書き込み権限があるため許可されます)
  5. open 同じ名前で新しいファイルを作成する
  6. write ファイルの内容(以前に読んだ、意味不明なものを入力した)
  7. fsync ファイルをディスクにフラッシュします(それほど重要ではありません)
  8. close
  9. chmod 新しいファイルの権限を古いファイルのように変更します-たまたま新しい所有者がいるだけです。

わかりました。これを理解できてよかった。そのため、ディレクトリに対する書き込み権限がない場合:w!、を使用できません。これは理にかなっています。
zrneely 2014

また、strace情報は非常に便利です。現在、私は将来自分自身の調査のための別のツールを持っています。
zrneely 2014

1
@zrneelyのヒントstrace-o出力をファイルに書き込むオプションを使用します。そうしないと、vimの出力と衝突します。書き込み権限に関しては、私はそれをして、ディレクトリのパーミッションを確認する表示されていないstatが、それはないファイルを作成しようとする(という名前の4913カレントディレクトリに、ランダムなようだ)し、それを削除します。
ボブ14

のように見えるの4913は、実際には最初に試した名前だけで、その目的、そのための十分な権限があるかどうかを確認することです。参照:bugzilla.redhat.com/show_bug.cgi ?id
Bob
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.