Scroll to navigation

PATH_RESOLUTION(7) Руководство программиста Linux PATH_RESOLUTION(7)

ИМЯ

path_resolution - как путь преобразуется в файл

ОПИСАНИЕ

У некоторых системных вызовов UNIX/Linux есть параметр для указания одного или нескольких имён файлов. Имя файла (или путь) преобразуется (resolved) следующим образом.

Шаг 1: запуск процесса преобразования

If the pathname starts with the '/' character, the starting lookup directory is the root directory of the calling process. A process inherits its root directory from its parent. Usually this will be the root directory of the file hierarchy. A process may get a different root directory by use of the chroot(2) system call, or may temporarily use a different root directory by using openat2(2) with the RESOLVE_IN_ROOT flag set.

A process may get an entirely private mount namespace in case it—or one of its ancestors—was started by an invocation of the clone(2) system call that had the CLONE_NEWNS flag set. This handles the '/' part of the pathname.

If the pathname does not start with the '/' character, the starting lookup directory of the resolution process is the current working directory of the process — or in the case of openat(2)-style system calls, the dfd argument (or the current working directory if AT_FDCWD is passed as the dfd argument). The current working directory is inherited from the parent, and can be changed by use of the chdir(2) system call.)

Пути, начинающиеся с символа «/», называются абсолютными путями. Пути, не начинающиеся с символа «/», называются относительными путями.

Шаг 2: обход пути

Назначаем текущим каталогом поиска начальный каталог поиска. Теперь для каждого не конечного компонента пути (подстрока, разделённая символами «/») будет производиться поиск в текущем каталоге поиска.

Если у процесса нет права поиска в текущем каталоге просмотра, будет возвращена ошибка EACCES («Доступ запрещён»).

Если компонент не найдет, будет возвращена ошибка ENOENT («Нет такого файла или каталога»).

Если компонент найден, но не является ни каталогом, ни символической ссылкой, будет возвращена ошибка ENOTDIR («Не является каталогом»).

Если компонент найден и является каталогом, значением текущего каталога поиска устанавливается этот каталог, после чего осуществляется переход к следующему компоненту.

If the component is found and is a symbolic link (symlink), we first resolve this symbolic link (with the current lookup directory as starting lookup directory). Upon error, that error is returned. If the result is not a directory, an ENOTDIR error is returned. If the resolution of the symbolic link is successful and returns a directory, we set the current lookup directory to that directory, and go to the next component. Note that the resolution process here can involve recursion if the prefix ('dirname') component of a pathname contains a filename that is a symbolic link that resolves to a directory (where the prefix component of that directory may contain a symbolic link, and so on). In order to protect the kernel against stack overflow, and also to protect against denial of service, there are limits on the maximum recursion depth, and on the maximum number of symbolic links followed. An ELOOP error is returned when the maximum is exceeded ("Too many levels of symbolic links").

В текущей реализации Linux максимальное количество допустимых переходов по символическим ссылкам при преобразовании пути равно 40. В ядрах до версии 2.6.18 ограничение глубины рекурсии было равно 5. Начиная с Linux 2.6.18, это ограничение увеличилось до 8. В Linux 4.2 код ядра разрешения пути был переработан и возникновение рекурсии больше не происходит, поэтому осталось только ограничение на 40 разрешений для всего пути.

The resolution of symbolic links during this stage can be blocked by using openat2(2), with the RESOLVE_NO_SYMLINKS flag set.

Шаг 3: поиск последнего элемента

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

. и ..

По соглашению, в каждом каталоге есть записи «.» и «..», которые ссылаются на сам каталог и на его родительских каталог, соответственно.

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

One cannot walk up past the root: "/.." is the same as "/".

Точки монтирования

После команды «mount устройство путь» путь указывает на корень иерархии файловой системы устройства, и больше не указывает на то, что было раньше.

Можно выйти за пределы смонтированной файловой системы: «путь/..» указывает на родительский каталог «пути», лежащий вне иерархии файловой системы устройства.

Traversal of mount points can be blocked by using openat2(2), with the RESOLVE_NO_XDEV flag set (though note that this also restricts bind mount traversal).

Конечные символы косой черты

Если путь заканчивается на «/», то это приводит к обработке предыдущего компонента согласно шагу 2: он существует и преобразуется в каталог. В противном случае конечный «/» будет проигнорирован (или, что тоже самое, путь с конечной косой чертой «/» будет равен пути, полученному добавлением к его концу «.»).

Символьная ссылка в конце

Если последний компонент пути является символической ссылкой, то это зависит от системного вызова, будет ли файл указывать на саму символическую ссылку или на её содержимое. Например, системный вызов lstat(2) будет работать с символической ссылкой, а stat(2) работает с файлом, на который указывает символическая ссылка.

Ограничение длины

Существует максимально допустимая длина пути. Если путь (или какой-нибудь промежуточный путь, полученный при разрешении символических ссылок) очень длинный, то возвращается ENAMETOOLONG («Имя файла очень длинное»).

Пустой путь

В оригинальном UNIX, пустой путь считался текущим каталогом. В наши дни в POSIX указано, что пустой путь не должен быть преобразован без ошибки. В Linux в этом случае возвращается ENOENT.

Права доступа

Биты прав файла делятся на три группы по три бита; смотрите chmod(1) и stat(2). Первая группа используется тогда, когда эффективный идентификатор пользователя вызывающего процесса равен идентификатору владельца файла. Вторая группа используется, если идентификатор группы файла равен эффективному идентификатору группы вызывающего процесса или одному из дополнительных групп вызывающего процесса (установленных setgroups(2)). В остальных случаях используется третья группа.

Три бита используются следующим образом: первым битом задаётся доступ на чтение, вторым на запись, а последним, в случае обычных файлов — разрешение на выполнение, в в случае каталогов разрешение на поиск.

Для проверки доступа в Linux используется fsuid вместо эффективного идентификатора пользователя. Обычно, fsuid равен эффективному идентификатору пользователя, fsuid может быть изменён системным вызовом setfsuid(2).

(Здесь «fsuid» сокращение от «пользовательский идентификатор в файловой системе, filesystem user ID». Это требовалось для реализации сервера NFS в пользовательском пространстве во времена, когда процессы могли посылать сигнал процессу с тем же эффективным идентификатором пользователя. Сейчас это устарело. Никто не должен использовать setfsuid(2).)

Схожим образом в Linux используется fsgid ("filesystem group ID") вместо идентификатора эффективной группы. Смотрите setfsgid(2).

Пропуск проверки прав доступа: суперпользователь и мандаты

В традиционных системах UNIX суперпользователю (root, идентификатор пользователя 0) доступно всё и при доступе к файлам никаких проверок ограничений не производится.

В Linux права суперпользователя делятся мандатами (смотрите capabilities(7)). Два мандата относятся к проверка доступа к файлам: CAP_DAC_OVERRIDE и CAP_DAC_READ_SEARCH (процесс имеет эти мандаты, если его fsuid равен 0).

Мандат CAP_DAC_OVERRIDE заменяет всех проверки прав, но позволяет право выполнения только, когда установлен хотя бы один из трёх битов выполнения файла.

Мандат CAP_DAC_READ_SEARCH разрешает чтение и поиск в по каталогу, а также чтение обычных файлов.

СМ. ТАКЖЕ

readlink(2), capabilities(7), credentials(7), symlink(7)

ЗАМЕЧАНИЯ

Эта страница является частью проекта Linux man-pages версии 5.10. Описание проекта, информацию об ошибках и последнюю версию этой страницы можно найти по адресу https://www.kernel.org/doc/man-pages/.

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан Alexey, Azamat Hackimov <azamat.hackimov@gmail.com>, kogamatranslator49 <r.podarov@yandex.ru>, Kogan, Max Is <ismax799@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.

11 апреля 2020 г. Linux