Как vim крадет файлы, принадлежащие root?


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 Это может свидетельствовать только о том, что файл был изменен только при наличии свидетельства «до» и «после» .

Вим использует файлы подкачки и перемещает файлы вокруг под водой, так что объясняет , почему он , кажется , чтобы писать в тот же файл , как вы делаете в вашей оболочке, но это не то же самое. 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файле не изменяется (сопоставление 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в моем случае). Я думаю, это объясняет, почему номер инода не меняется.


3
FWIW вы можете убедиться, что это происходит, запустив ls -ilдо и после ... если tempномер инода изменился, вы знаете, что это другой файл с тем же именем.
бесполезно

3
Можно добавить, что rm на самом деле не удаляет файл, а просто удаляет ссылку на файл, и файл не удаляется до тех пор, пока число ссылок не уменьшится до 0. rm просто удаляет запись в файле в каталоге. Если root имеет другую ссылку (жесткую ссылку) на файл в другом каталоге, пользователь не может удалить файл.
gerrit

1
@ Я все равно пытался, и номер не изменился, хотя изменились владелец и отметка времени!
amyassin

1
@amyassin Ты прав! Я обновил свой ответ пояснительной выдержкой.
gertvdijk

1
В дополнение к вашему примечанию о разрешениях Windows и Unix, если вы хотите, чтобы в Unix поведение было похоже на Windows, вы можете создать каталог, принадлежащий root (или другому пользователю, который должен иметь универсальные разрешения на удаление / переименование / 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чтобы увидеть номер индекса, который является уникальным идентификатором (в файловой системе) файла или другого объекта.

Вы увидите, что файл был заменен другим объектом: номер индекса, скорее всего, изменится.

Просмотр того же номера инода не является доказательством чего-либо: номер инода может быть переработан. Если мы удалим последнюю ссылку на файл, а затем создадим новый файл, мы можем получить ссылку с тем же номером инода. Но это не может произойти, если старый файл удаляется после создания нового. Например mv file file.tmp; touch file; rm file.tmp. Я подозреваю, что vim на самом деле делает что-то похожее на это echo new_content > tmpfile; mv tmpfile file. mvОперация переведет к renameсистемному вызову, поэтому присвоение номеров индексных дескрипторов зависит от того, как файловой системы реализует переименование который отсоединяет пункт назначения.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.