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 должен иметь доступ с правами на запись, а все остальные должны иметь только чтение. Отредактируйте файл, попробуйте сохранить - вы не можете. Круто, работает как задумано. Однако, если вы сохраните с помощью :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 и почему он не основан на файле системные права, как я и ожидал, и какой механизм использует vim для редактирования файла, который другие редакторы (gedit, nano) не могут использовать?

РЕДАКТИРОВАТЬ: компьютер, на котором я попробовал это, использует ядро ​​Linux 3.15.5-2-ARCH. Номер версии Vim - 7.4.373-1, и он установлен pacman- я не собирал его с нуля с какими-либо специальными опциями.

zrneely
источник
Кажется, я не могу воспроизвести проблему, если не предпринять некоторые уловки, как описано здесь
Давыжу
Я просто попробовал это снова, используя команды в вопросе, и это произошло так же. Я отредактирую вопрос, чтобы добавить подробности о моем компьютере, хотя, похоже, это может зависеть от платформы.
zrneely
Моя первая догадка - вам разрешено менять владельца файлов в каталоге, к которому у вас есть права на запись. Но, похоже , дело не в этом . CAP_CHOWNтребуется позвонить chown(2). Кстати, я могу воспроизвести на Debian, с vim 7.4.
Боб

Ответы:

10

Я вижу, что ваш текущий путь - ~домашний каталог вашего пользователя. У вас должны быть разрешения на запись в этот каталог.

Подумайте об этом по-другому - если у вас есть права на чтение и запись для каталога, что мешает вам скопировать файл, удалить старый и переименовать новый с другими разрешениями?

Это именно то, что делает Vim!


Если вы запускаете vim под strace, например:

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 Проверьте текущий идентификатор пользователя, чтобы увидеть, соответствуют ли они владельцу файла
  4. unlink Удалить файл (это разрешено, потому что разрешение на запись в каталог)
  5. open Создайте новый файл с тем же именем
  6. write Содержимое файла (читай раньше, я набрал немного тарабарщины)
  7. fsync Записать файл на диск (не очень важно)
  8. close
  9. chmod Измените права доступа к новому файлу так, чтобы он выглядел как старый - у него просто появился новый владелец.
боб
источник
Хорошо, спасибо. Я рад, что понял это. Поэтому, если у меня нет прав на запись в каталог, я не смогу использовать :w!, что имеет смысл.
zrneely
Кроме того, информация о strace действительно удобна - теперь у меня есть еще один инструмент для моих собственных расследований в будущем.
zrneely
1
@zrneely Подсказка для strace: используйте -oопцию для записи вывода в файл; в противном случае это вступает в vimпротиворечие с выходом России. Что касается прав на запись, я не вижу , что проверка разрешений каталогов , statно делает попытку создать файл ( с именем 4913, кажется случайным) в текущем каталоге , а затем удалить его.
Боб
Похоже, на 4913самом деле это просто первое имя, которое он пытается, и его цель - проверить, достаточно ли у него разрешений для этого. См .: bugzilla.redhat.com/show_bug.cgi?id=427711#c6 and groups.google.com/forum/#!topic/vim_dev/sppdpElxY44
Боб,