Защищены ли от удаления непустые подкаталоги другого пользователя в моем каталоге?

Защищены ли от удаления непустые подкаталоги другого пользователя в моем каталоге?

В следующей ситуацииls -alh

total 0
drwxrwx--- 1 user http  20 Nov 30 08:08 .
drwxrws--- 1 user http 310 Nov 30 08:07 ..
drwx------ 1 http http  10 Nov 30 08:08 empty-subdir
drwx------ 1 http http  12 Nov 30 08:08 non-empty-subdir

где существуют два подкаталога (не принадлежащие мне), которые я перечисляю как:

sudo ls empty-subdir -alh
total 0
drwx------ 1 http http 10 Nov 30 08:08 .
drwxrwx--- 1 user http 20 Nov 30 08:08 ..

sudo ls non-empty-subdir -alh
total 0
drwx------ 1 http http 12 Nov 30 08:08 .
drwxrwx--- 1 user http 20 Nov 30 08:08 ..
drwx------ 1 http http  0 Nov 30 08:08 subdir

Разница между двумя подкаталогами в том, что непустой non-empty-subdirсодержит папку.

Мой вопрос в том, намеренно ли так получается, что при попытке rm -rfудалить подкаталоги я получаю следующие результаты:

$ rm empty-subdir -rf
$ rm non-empty-subdir -rf
rm: cannot remove 'non-empty-subdir': Permission denied
$ ls -alh
total 0
drwxrwx---+ 1 user http  10 Nov 30 08:14 .
drwxrws---+ 1 user http 310 Nov 30 08:07 ..
drwx------+ 1 http http  12 Nov 30 08:08 non-empty-subdir

Похоже, что пользователю с правами записи в каталог разрешено удалять запись для файла или пустого подкаталога другого пользователя, но ненепустойподкаталог.

Идеальным ответом на этот вопрос была бы такая информация:

  • подтверждение того, что описанное поведение воспроизводится на других машинах (а не просто причуды моей испорченной коробки)
  • обоснование, объясняющее такое поведение (например, есть ли варианты использования?)
  • обзор, есть ли различия между системами (BSD, Linux....)

Обновлять: Что касается комментария Ipor Sircer, я перепроверил сценарий без каких-либо функций ACL, и результат тот же. Поэтому я изменил вопрос, удалив es +из списков, чтобы не давать повода для мысли, что поведение может быть связано с ACL.

решение1

Удалить каталог (с помощью rmdir()системного вызова) можно только в том случае, если он пуст.

rm -r dirудаляет каталог и все файлы в нем, начиная с листьев дерева каталогов и до самого корня ( dir).

Чтобы удалить файл (как rmdir()для каталогов, так и unlink()для других типов файлов или *at()их вариантов), важны не разрешения самого файла, а разрешения каталога, из которого вы удаляете файл (будьте осторожны, часть tв разрешениях, например, для /tmp, добавляет еще больше сложностей).

Прежде всего, вы на самом деле не удаляетефайл, вы отсоединяете его от каталога (и когда это последняя ссылка, которую вы удаляете, файл в конечном итоге удаляется), то есть вы изменяете каталог, поэтому вам нужномодифицирующийразрешения (на запись) для этого каталога.

Причина, по которой вы не можете удалить, non-empty-dirзаключается в том, что вы не можете subdirсначала отсоединиться от него, так как у вас нет прав на изменение non-empty-dir. У вас будет право отсоединиться non-empty-dirот вашего домашнего каталога, так как у вас есть разрешение на запись/изменение в нем, только вы не можете удалить каталог, который не является пустым.

В вашем случае, как отметил @PeterCordes в комментариях, rmdir()системный вызов завершается с ENOTEMPTYошибкой (Directory not empty), но поскольку у вас нетчитатьразрешения на доступ к каталогу, rmне может даже узнать, какие файлы и каталоги (включая subdir) ему нужно будет удалить из него, чтобы очистить его (не то чтобы он мог удалить их, если бы знал, так как у него нет прав на запись).

Вы также можете попасть в ситуации, когдаrm могудалить каталог, если только можно узнать, какие файлы в нем находятся, как в случае с каталогом, доступным только для записи:

$ mkdir dir
$ touch dir/file
$ chmod a=,u=wx dir
$ ls -ld dir
d-wx------ 2 me me 4096 Nov 30 19:43 dir/
$ rm -rf dir
rm: cannot remove 'dir': Permission denied

Тем не менее, я могу удалить его, так как знаю, что он содержит только один fileфайл:

$ rm dir/file
$ rmdir dir
$

Также обратите внимание, что в современных Unix-системах вы можете переименовать это non-empty-dir, но в некоторых системах, таких как Linux или FreeBSD (но не Solaris),нетпереместите его в другой каталог, даже если у вас также есть разрешение на запись в этот каталог, как (я думаю, и для Linux, как предложилкомментарий к соответствующему коду) это повлечет за собой изменение non-empty-dir( ..запись в нем будет указывать на другой каталог).

Можно утверждать, что удаление вашего файла empty-dirтакже подразумевает удаление записей ..и .в нем, то есть его изменение, но все же система позволяет вам это сделать.

решение2

Игнорируя потенциальное изменение через ACL, я могу подтвердить такое поведение для моей системы (без ACL).

Наблюдаемое поведение является логическим следствием двух принципов:

1) Права на каталог определяют, кто может изменять каталог, т.е. удалять записи в каталоге. Права записей в этом каталоге не играют никакой роли.

2) Удаление файла потенциально требует удаления и очистки связанной с ним информации, например, инодов, списков распределения блоков и т. д. Вот почему вы не можете удалить непустой подкаталог, не очистив все содержащиеся в нем файлы, поскольку в противном случае содержащиеся в нем файлы станут недоступными, а связанная с ним информация не будет очищена.

Итак, вы можете удалить empty-subdir, поскольку у вас есть права на запись в каталог, в котором он находится. Вы не можете удалить non-empty-subdir, поскольку у вас нет прав на очистку файлов, содержащихся в этом подкаталоге.

На самом деле нет никакого обоснования или варианта использования для этого. Можно было бы встроить рекурсивную очистку подкаталога в ядро, но оригинальный Unix делал все простым, а рекурсивная очистка была бы слишком сложной, когда ее можно было бы осуществить с помощью утилиты пользовательского пространства.

Я не могу дать всеобъемлющий обзор различных разновидностей, но именно так было в оригинальном Unix, и я ожидаю, что так будет в каждой разновидности Unix, и я был бы удивлен, если бы существовала разновидность Unix, которая вела бы себя по-другому.

решение3

Я попытался воспроизвести то, что вы описываете, и запустил strace rm -rf ./nonempty. Это показывает следующее:

unlinkat(4, "subdir", AT_REMOVEDIR)     = -1 EACCES (Permission denied)

и согласно unlinkatруководству (которое в Linux такое же unlink(2), выделено мной):

EACCES Доступ на запись в каталог, содержащий pathname, не разрешен для эффективного UID процесса, или один из каталогов в pathname не разрешает поиск. (См. также path_resolution(7).)

Поскольку родительский каталог nonemptyне предоставляет userразрешение x (поиск), это имеет смысл, исходя из EACCESописания, которое subdirне может быть удалено.

Связанный контент