CHROOT(2) | Руководство программиста Linux | CHROOT(2) |
chroot - изменить корневой каталог
#include <unistd.h>
int chroot(const char *path);
Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):
chroot():
_XOPEN_SOURCE && ! (_POSIX_C_SOURCE >= 200112L) || /* начиная с glibc 2.20: */ _DEFAULT_SOURCE || /* версии glibc <= 2.19: */ _BSD_SOURCE
chroot() изменяет корневой каталог вызывающего процесса на тот, что задан аргументом path. Этот каталог будет использоваться для имён файлов, начинающихся с /. Корневой каталог наследуется всеми потомками вызывающего процесса.
Только привилегированный процесс (Linux: с мандатом CAP_SYS_CHROOT в своём пользовательском пространстве имён) может вызвать chroot().
Этот вызов изменяет только составляющую процесса разрешения имён и больше ничего. В частности, он не предназначен для действий повышения безопасности, создания полностью изолированной среды процесса (sandbox) или ограничения системных вызовов файловой системы. В прошлом, chroot() использовался службами для ограничения их самих передачи полученных от недоверенных пользователей путей системным вызовам наподобие open(2). Однако, если каталог перемещается за пределы каталога chroot, атакующий может использовать это в своих интересах и также выйти за пределы каталога chroot. Простейший способ сделать это — выполнить chdir(2) в каталог, который будет перемещён, подождать, когда он переместится, а затем открыть путь, например ../../../etc/passwd.
Если chdir(2) не разрешён, то есть немного более хитрый вариант, работающий при определённых условиях. Если служба позволяет задать «chroot в каталог», то обычно это означает, что если вы хотите предотвратить доступ к файлам удалённых пользователей вне каталога chroot, то вы должны гарантировать, что каталоги никогда не перемещаются за его пределы.
Данный вызов не изменяет текущий рабочий каталог, поэтому после вызова '.' может оказаться вне дерева, являющегося корнем '/'. В частности, суперпользователь может выйти за пределы "тюрьмы chroot" выполнив:
mkdir foo; chroot foo; cd ..
Данный вызов не закрывает открытые файловые дескрипторы и поэтому через такие дескрипторы можно получить доступ к файлам за пределами дерева chroot.
При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.
В зависимости от файловой системы могут также возвращаться другие ошибки. Общий набор ошибок перечислен ниже:
SVr4, 4.4BSD, SUSv2 (отмечена как УСТАРЕВШАЯ). Эта функция не входит в POSIX.1-2001.
Дочерний процесс, созданный посредством fork(2), наследует корневой каталог родительского процесса. При вызове execve(2) корневой каталог остаётся неизменным.
Для определения корневого каталога процесса можно использовать магическую символическую ссылку /proc/[pid]/root; подробности в proc(5).
В FreeBSD есть более ограничивающий системный вызов jail().
chroot(1), chdir(2), pivot_root(2), path_resolution(7), switch_root(8)
2019-03-06 | Linux |