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

ИМЯ

chroot - изменить корневой каталог

ОБЗОР

#include <unistd.h>

int chroot(const char *path);

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

chroot():

Начиная с glibc 2.2.2:
_XOPEN_SOURCE && ! (_POSIX_C_SOURCE >= 200112L)

    || /* начиная с glibc 2.20: */ _DEFAULT_SOURCE

    || /* версии glibc <= 2.19: */ _BSD_SOURCE
До glibc 2.2.2: не было

ОПИСАНИЕ

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 устанавливается в соответствующее значение.

ОШИБКИ

В зависимости от файловой системы могут также возвращаться другие ошибки. Общий набор ошибок перечислен ниже:

Поиск запрещён из-за одного из частей префикса пути (См. также path_resolution(7).)
Аргумент path указывает за пределы доступного адресного пространства.
Произошла ошибка ввода-вывода.
Во время определения path встретилось слишком много символьных ссылок.
path слишком длинен.
Файл не существует.
Недостаточное количество памяти ядра.
Компонент path не является каталогом.
У вызвавшего процесса недостаточно прав.

СООТВЕТСТВИЕ СТАНДАРТАМ

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