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はこのルート所有ファイルを取得し、ユーザー所有ファイルに変更しました!

これは、ユーザーがディレクトリを所有している場合にのみ機能するようです-しかし、それは不可能であるべきだと感じています。誰もこれがどのように行われるか説明できますか?

回答:


51

あなたglenは、ディレクトリの所有者です(.リストのファイルを参照)。ディレクトリは単なるファイルのリストであり、このリストを変更する権限があります(たとえば、ファイルの追加、ファイルの削除、所有権の変更による所有権の変更など)。ファイルの内容を直接変更できない場合がありますが、ファイル全体を読み取ってリンク解除(削除)し、後で新しいファイルを追加できます。1前後を確認するだけで、ファイルが変更されたよう見える場合があります。

Vimはスワップファイルを使用し、水中でファイルを移動するため、シェルで行うのと同じファイルに書き込むように見える理由が説明されますが、同じものではありません。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実行しません。ファイルのiノード番号は変更されないためです(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私の場合)。これが、iノード番号が変わらない理由を説明していると思います。


3
FWIWこれが実行されていることを確認するにはls -il、... tempのiノード番号が変更された場合、同じ名前の別のファイルであることがわかります。
役に立たない

3
rmが実際にファイルを削除するのではなく、ファイルへのリンクを削除するだけで、リンクの数が0に減少する前にファイルが削除されないことを追加できます。rmはディレクトリ内のファイルへのエントリを削除するだけです。ルートに別のディレクトリのファイルへの別のリンク(ハードリンク)がある場合、ユーザーはファイルを削除できません。
gerrit

1
@Uselessを試してみましたが、所有者とタイムスタンプは変更されましたが、番号は変更されませんでした!
アミシン

1
@amyassinそうですね!私はそれを説明する抜粋で答えを更新しました。
gertvdijk

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が実際に元のファイルを削除したことがわかります(コンテンツを変更することはできませんが、ファイルを削除する権限があるため)、独自の新しいファイルを作成しました(所有者が「root」ではなくなっていることを確認してください)。

また、vimで元のファイルを編集しているときに、読み取り専用ファイルを変更していることを警告しています。したがって、コマンドを入力する:wq!(操作を強制する)場合、vimでできることは、既存のファイルを削除して、同じ名前の新しいファイルを作成することだけです。

お役に立てば幸いです。


1

-iオプションを使用してls、ファイルまたは他のオブジェクトの一意の識別子(ファイルシステム内)であるiノード番号を表示します。

ファイルが別のオブジェクトに置き換えられたことがわかります。iノード番号が変更される可能性があります。

同じiノード番号を見ることは何の証拠でもありません。iノード番号はリサイクルできます。ファイルへの最後のリンクを削除してから新しいファイルを作成すると、同じiノード番号のリンクが取得される場合があります。しかし、新しいファイルが作成された後に古いファイルが削除された場合、それは起こりえません。例えばmv file file.tmp; touch file; rm file.tmp。vimは実際にこれに似た何かをするのではないかと思いecho new_content > tmpfile; mv tmpfile fileます。mv操作はに変換されますrename、システムコールので、inode番号の割り当てはどのようにファイルシステムが実装先のリンクを解除名前の変更に依存します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.