setfsuid(2) устанавливает идентификатор пользователя для доступа к файловой

ОБЗОР

#include <sys/fsuid.h>

int setfsuid(uid_t fsuid);

ОПИСАНИЕ

Системный вызов setfsuid() изменяет значение идентификатора пользователя файловой системы вызывающего — идентификатор пользователя, который ядро Linux использует для проверки при любом доступе к файловой системе. Обычно, значение идентификатора пользователя файловой системы равно теневому значению эффективного идентификатора пользователя. Более того, при изменении идентификатора эффективного идентификатора пользователя также изменяется и идентификатор пользователя файловой системы на новое значение идентификатора эффективного идентификатора пользователя.

Вызовы setfsuid() и setfsgid(2) обычно используются только в программах Linux типа NFS-сервера, которым требуется изменить идентификатор пользователя и группы для доступа к файлам без изменения действительного и эффективного идентификаторов пользователя и группы. Изменение обычного идентификатора пользователя для программы типа NFS-сервера --- это нарушение безопасности, приводящее к возможному получению нежелательных сигналов от других групп (но читайте далее).

Вызов setfsuid() выполняется корректно, только если он был вызван суперпользователем или, если fsuid совпадает с действительным, эффективным и сохранённым идентификатором пользователя или равен текущему значению идентификатора пользователя файловой системы вызывающего.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

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

ВЕРСИИ

Данный системный вызов доступен в Linux начиная с версии 1.2.

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

Вызов setfsuid() есть только в Linux и не должен использоваться в переносимых программах.

ЗАМЕЧАНИЯ

Если в glibc определяется, что в аргументе указан неправильный идентификатор пользователя, то возвращается -1, errno присваивается значение EINVAL, а системный вызов не выполняется.

На момент появления данного системного вызова один процесс мог послать сигнал другому процессу с тем же эффективным идентификатором пользователя. Это означает, что если привилегированный процесс изменит свой эффективный идентификатор пользователя с целью проверки доступа к файлу, то он сможет стать уязвимым к приёму сигналов, посланных (непривилегированным) процессом с тем же идентификатором пользователя. Атрибут идентификатора пользователя файловой системы был добавлен как раз для того, чтобы позволить процессу изменить свой идентификатор пользователя для проверки доступа к файлу не боясь стать уязвимым к приёму нежелаемых сигналов. Начиная с Linux 2.0, обработка прав на сигналы была изменена (смотрите kill(2)), что позволило процессу изменять свой эффективный идентификатор пользователя без боязни стать уязвимым к приёму нежелаемых сигналов от других процессов.Таким образом, сейчас системный вызов setfsuid() уже не нужен и не должен использоваться в новых приложениях (как и setfsgid(2)).

Первоначальная версия системного вызова setfsuid() в Linux поддерживала только 16-битные идентификаторы пользователя. Позднее в Linux 2.4 был добавлен вызов setfsuid32(), поддерживающий 32-битные идентификаторы. В glibc обёрточная функция setfsuid() работает одинаково вне зависимости от версий ядра.

ДЕФЕКТЫ

Вызывающему не возвращается никаких ошибок, и факт того, что успешном или неудачном выполнении возвращается одинаковое значение, делает невозможным напрямую определить как завершился вызов. Вместо этого, вызывающий должен получить значение из ещё одного вызова — setfsuid(-1) (который всегда завершается с ошибкой), чтобы определить, изменил ли предыдущий вызов setfsuid() идентификатор пользователя файловой системы. По крайней мере, должно быть получено значение EPERM, если вызов завершится с ошибкой (так как у вызывающего нет мандата CAP_SETUID).