ОПИСАНИЕ
Для
выполнения
проверки
прав
доступа в
обычных
реализациях
UNIX процессы
разделяют
на две
категории:
привилегированные
(ID
эффективного
пользователя
равен 0, как
у
суперпользователя
или root), и не
привилегированные
(ID
эффективного
пользователя
не равен
нулю). Для
привилегированных
процессов
все
проверки
прав в ядре
не
выполняются,
а для не
привилегированных
процессов
выполняется
полная
проверка
на основе
мандатов
процесса
(обычно,
эффективного
UID,
эффективного
GID и списка
дополнительных
групп).
В ядре Linux
начиная с
версии 2.2,
все
привилегии,
обычно
связываемые
с
суперпользователем,
разделены
на
несколько
частей,
называемых
мандатами
(capabilities), которые
можно
разрешать
и
запрещать
независимо
друг от
друга.
Мандаты
являются
атрибутом
нити.
Список
мандатов
В
следующим
списке
показаны
мандаты,
реализованные
в Linux, а также
операции
или
поведение,
которые
эти
мандаты
разрешают:
- CAP_AUDIT_CONTROL
(начиная с Linux
2.6.11)
- Позволяет
включать
или
выключать
аудит ядра;
изменять
фильтрующие
правила
аудита;
получать
состояние
аудита и
фильтрующие
правила.
- CAP_AUDIT_READ
(начиная с Linux
3.16)
- Позволяет
читать
протокол
аудита
через
многоадресный
сокет netlink.
- CAP_AUDIT_WRITE
(начиная с Linux
2.6.11)
- Позволяет
записывать
данные в
журнал
аудита
ядра.
- CAP_BLOCK_SUSPEND
(начиная с Linux
3.5)
- Позволяет
использовать
возможности,
которые
могут
приводить
к
блокированию
приостановки
системы (epoll(7)
EPOLLWAKEUP, /proc/sys/wake_lock).
- CAP_CHOWN
- Позволяет
выполнять
произвольные
изменения
файловых UID
и GID
(смотрите
chown(2)).
- CAP_DAC_OVERRIDE
- Позволяет
пропускать
проверки
доступа к
файлу на
чтение,
запись и
выполнение
(DAC (discretionary access control) —
избирательный
контроль
доступа).
- CAP_DAC_READ_SEARCH
- Позволяет
пропускать
проверки
доступа к
файлу на
чтение и
доступа к
каталогу
на чтение и
выполнение;
- Позволяет
вызывать
open_by_handle_at(2);
- Позволяет
использовать
linkat(2) с флагом
AT_EMPTY_PATH для
создания
ссылки на
файл,
заданным
файловым
дескриптором.
- CAP_FOWNER
- Позволяет
пропускать
проверки
доступа
для
операций,
которые
обычно
требуют
совпадения
UID файловой
системы
процесса и
UID файла
(например,
chmod(2), utime(2)),
исключая
операции,
охватываемые
CAP_DAC_OVERRIDE и CAP_DAC_READ_SEARCH;
- Позволяет
изменять
флаги
иноды
(смотрите
ioctl_iflags(2)) у
произвольных
файлов;
- Позволяет
устанавливать
списки
контроля
доступа (ACL)
произвольных
файлов;
- Позволяет
игнорировать
закрепляющий
бит при
удалении
файла;
- Позволяет
задавать
O_NOATIME для
произвольных
файлов в open(2)
и fcntl(2).
- CAP_FSETID
- Позволяет
не очищать
биты
режима set-user-ID и
set-group-ID при
изменении
файла;
- Позволяет
устанавливать
бит set-group-ID на
файл, у
которого GID
не
совпадает
с битом
файловой
системы
или любыми
дополнительными
GID
вызывающего
процесса.
- CAP_IPC_LOCK
- Позволяет
блокировать
память (mlock(2),
mlockall(2), mmap(2), shmctl(2)).
- CAP_IPC_OWNER
- Позволяет
не
выполнять
проверки
доступа
для
операций с
объектами
System V IPC.
- CAP_KILL
- Позволяет
не
выполнять
проверки
при
отправке
сигналов
(смотрите
kill(2)). Сюда
относится
использование
ioctl(2) с
операцией
KDSIGACCEPT.
- CAP_LEASE
(начиная с Linux
2.4)
- Позволяет
устанавливать
аренду на
произвольные
файлы
(смотрите
fcntl(2)).
- CAP_LINUX_IMMUTABLE
- Позволяет
устанавливать
флаги
иноды FS_APPEND_FL и
FS_IMMUTABLE_FL
(смотрите
ioctl_iflags(2)).
- CAP_MAC_ADMIN
(начиная с Linux
2.6.25)
- Разрешает
изменять
настройку
MAC или
состояние.
Реализован
в Smack Linux Security Module (LSM).
- CAP_MAC_OVERRIDE
(начиная с Linux
2.6.25)
- Позволяет
замещать
мандатный
контроль
доступа (MAC).
Реализован
в Smack LSM.
- CAP_MKNOD
(начиная с Linux
2.4)
- Позволяет
создавать
специальные
файлы с
помощью
mknod(2).
- CAP_NET_ADMIN
- Позволяет
выполнять
различные
сетевые
операции:
- настройку
интерфейса;
- управление
IP МЭ,
трансляцией
адресов и
ведением
учёта;
- изменять
таблицы
маршрутизации;
- привязываться
к любому
адресу для
прозрачного
проксирования;
- назначать
тип
сервиса (TOS)
- очищать
статистику
драйвера;
- включать
режим
захвата
(promiscuous);
- включать
многоадресные
рассылки
(multicasting);
- использовать
setsockopt(2) для
включения
следующих
параметров
сокета: SO_DEBUG,
SO_MARK, SO_PRIORITY (для
приоритетов
вне
диапазона 0
- 6), SO_RCVBUFFORCE и SO_SNDBUFFORCE.
- CAP_NET_BIND_SERVICE
- Позволяет
привязывать
сокет к
привилегированным
портам
домена
интернета
(номера
портов
меньше 1024).
- CAP_NET_BROADCAST
- (не
используется)
Позволяет
осуществлять
широковещание
с сокета и
прослушивание
многоадресных
рассылок.
- CAP_NET_RAW
- Позволяет
использовать
сокеты RAW и PACKET;
- позволяет
привязываться
к любому
адресу для
прозрачного
проксирования.
- CAP_SETGID
- Позволяет
выполнять
произвольные
действия с
GID процесса
и списком
дополнительных
GID;
- Позволяет
подделывать
GID при
передаче
мандатов
сокета
через
доменные
сокеты UNIX;
- Позволяет
записывать
отображение
идентификатора
группы в
пользовательское
пространство
(смотрите
user_namespaces(7)).
- CAP_SETFCAP
(начиная с Linux
2.6.24)
- Устанавливает
произвольные
мандаты на
файл.
- CAP_SETPCAP
- Если
файловые
мандаты
поддерживаются
(т. е.,
начиная с Linux
2.6.24):
позволяет
добавлять
любой
мандат из
ограничивающего
набора
вызывающей
нити в её
наследуемый
набор;
отзывать
мандаты из
ограничивающего
набора (с
помощью prctl(2)
с
операцией
PR_CAPBSET_DROP);
изменять
флаги securebits.
- Если
файловые
мандаты не
поддерживаются
(т. е., до Linux 2.6.24):
позволяет
предоставлять
и отзывать
любой
мандат в
списке
разрешённых
мандатов
вызывающего
или любого
другого
процесса
(это
свойство
CAP_SETPCAP
недоступно,
если ядро
собрано с
поддержкой
файловых
мандатов,
так как CAP_SETPCAP
имеет
полностью
другую
семантику
у таких
ядер).
- CAP_SETUID
- Позволяет
выполнять
произвольные
действия с
UID процесса
(setuid(2), setreuid(2), setresuid(2),
setfsuid(2));
- Позволяет
подделывать
UID при
передаче
мандатов
сокета
через
доменные
сокеты UNIX;
- Позволяет
записывать
отображение
идентификатора
пользователя
в
пользовательское
пространство
(смотрите
user_namespaces(7)).
- CAP_SYS_ADMIN
- Замечание:
данный
мандат
перегружен;
смотрите
Замечания
разработчикам
ядра
ниже.
- Позволяет
выполнять
следующие
задачи
управления
системой:
quotactl(2), mount(2), umount(2), swapon(2),
swapoff(2), sethostname(2) и
setdomainname(2);
- Позволяет
выполнять
привилегированные
операции
syslog(2) (начиная
с Linux 2.6.37, для
этих
операций
нужно
использовать
CAP_SYSLOG);
- Позволяет
выполнять
команду
VM86_REQUEST_IRQ vm86(2);
- Позволяет
выполнять
операции
IPC_SET и IPC_RMID над
произвольными
объектами
System V IPC;
- Позволяет
перезаписывать
ограничение
ресурса
RLIMIT_NPROC;
- Позволяет
выполнять
операции
над
расширенными
атрибутами
trusted и security
(смотрите
xattr(7));
- Позволяет
использовать
lookup_dcookie(2);
- Позволяет
использовать
ioprio_set(2) для
назначения
классов
планирования
ввода-вывода
IOPRIO_CLASS_RT и (до Linux 2.6.25)
IOPRIO_CLASS_IDLE;
- Позволяет
подделывать
PID при
передаче
мандатов
сокета
через
доменные
сокеты UNIX;
- Позволяет
превышать
/proc/sys/fs/file-max,
системное
ограничение
на
количество
открытых
файлов, в
системных
вызовах,
открывающих
файлы
(например,
accept(2), execve(2), open(2), pipe(2));
- Позволяет
задействовать
флаги CLONE_*,
которые
создают
новые
пространства
имён с
помощью clone(2)
и unshare(2))
(начиная с Linux
3.8 для
создания
пользовательских
пространств
имён
больше
никаких
мандатов
не
требуется);
- Позволяет
вызывать
perf_event_open(2);
- Позволяет
получать
доступ к
информации
о
привилегированном
событии perf;
- Позволяет
вызывать
setns(2)
(требуется
CAP_SYS_ADMIN в
пространстве
имён
назначения);
- Позволяет
вызывать
fanotify_init(2);
- Позволяет
вызывать
bpf(2);
- Позволяет
выполнять
привилегированные
операции
KEYCTL_CHOWN и KEYCTL_SETPERM в
keyctl(2);
- Позволяет
выполнять
операцию
MADV_HWPOISON в madvise(2);
- Позволяет
задействовать
TIOCSTI в ioctl(2) для
вставки
символов
во входную
очередь
терминала,
отличного
от
управляющего
терминала
вызывающего;
- Позволяет
задействовать
устаревший
системный
вызов nfsservctl(2);
- Позволяет
задействовать
устаревший
системный
вызов bdflush(2);
- Позволяет
выполнять
различные
привилегированные
операции
ioctl(2) над
блочными
устройствами;
- Позволяет
выполнять
различные
привилегированные
операции
ioctl(2) над
файловой
системой;
- Позволяет
выполнять
привилегированные
операции
ioctl(2) над
устройством
/dev/random
(смотрите
random(4));
- Позволяет
устанавливать
фильтры seccomp(2)
без
начальной
установки
атрибута
нити no_new_privs;
- Позволяет
изменять
правила
разрешения/запрета
для групп
управления
устройствами;
- Позволяет
задействовать
операцию
ptrace(2) PTRACE_SECCOMP_GET_FILTER для
получения
дампа
фильтров seccomp
трассируемого;
- Позволяет
задействовать
операцию
ptrace(2) PTRACE_SETOPTIONS для
приостановки
защиты seccomp
трассируемого
(т. е., флаг
PTRACE_O_SUSPEND_SECCOMP);
- Позволяет
выполнять
административные
операции
над
многими
драйверами
устройств.
- CAP_SYS_BOOT
- Позволяет
использовать
reboot(2) и kexec_load(2).
- CAP_SYS_CHROOT
- Позволяет
использовать
chroot(2);
- Позволяет
изменять
пространство
имён
монтирования
с помощью
setns(2).
- CAP_SYS_MODULE
- Позволяет
загружать
и
выгружать
модули
ядра
(смотрите
init_module(2) и delete_module(2));
- В ядрах до
версии 2.6.25:
позволяет
отзывать
мандаты из
системного
ограничивающего
набора
мандатов.
- CAP_SYS_NICE
- CAP_SYS_PACCT
- Позволяет
использовать
acct(2).
- CAP_SYS_PTRACE
- CAP_SYS_RAWIO
- Позволяет
выполнять
операции
ввода-вывода
из портов
(iopl(2) и ioperm(2));
- Разрешает
доступ к
/proc/kcore;
- Позволяет
задействовать
операцию
FIBMAP в ioctl(2);
- Позволяет
открывать
устройства
для
доступа к
специальным
регистрам
x86 (MSR, смотрите
msr(4));
- Позволяет
обновлять
/proc/sys/vm/mmap_min_addr;
- Позволяет
создавать
отображения
памяти по
адресам
меньше
значения,
заданного
в /proc/sys/vm/mmap_min_addr;
- Позволяет
отображать
файлы в
/proc/bus/pci;
- Позволяет
открывать
/dev/mem и /dev/kmem;
- Позволяет
выполнять
различные
команды
устройств
SCSI;
- Позволяет
выполнять
определённые
операции с
устройствами
hpsa(4) и cciss(4);
- Позволяет
выполнять
некоторые
специальные
операции с
другими
устройствами.
- CAP_SYS_RESOURCE
- Позволяет
использовать
зарезервированное
пространство
файловых
систем ext2;
- Позволяет
делать
вызовы ioctl(2),
управляющие
журналированием
ext3;
- Позволяет
превышать
ограничение
дисковой
квоты;
- Позволяет
увеличивать
ограничения
по
ресурсам
(смотрите
setrlimit(2));
- Позволяет
перезаписывать
ограничение
ресурса
RLIMIT_NPROC;
- Позволяет
превышать
максимальное
количество
консолей
при
выделении
консоли;
- Позволяет
превышать
максимальное
количество
раскладок;
- Позволяет
использовать
более чем 64hz
прерывания
из часов
реального
времени;
- Позволяет
назначать
значение
msg_qbytes очереди
сообщений
System V больше
ограничения
/proc/sys/kernel/msgmnb
(смотрите
msgop(2) и msgctl(2));
- Позволяет
обходить
ограничитель
ресурса
RLIMIT_NOFILE для
файловых
дескрипторов,
находящихся
в процессе
передачи
(«в
полёте», in-flight),
когда
файловые
дескрипторы
передаются
в другой
процесс
через
доменный
сокет UNIX
(смотрите
unix(7));
- Позволяет
превышать
ограничение
/proc/sys/fs/pipe-size-max при
назначении
вместимости
канала с
помощью
команды
F_SETPIPE_SZ у fcntl(2).
- Позволяет
использовать
F_SETPIPE_SZ для
увеличения
вместимости
канала
больше чем
ограничение,
задаваемое
в /proc/sys/fs/pipe-max-size;
- Позволяет
превышать
ограничение
/proc/sys/fs/mqueue/queues_max при
создании
очередей
сообщений
POSIX (смотрите
mq_overview(7));
- Позволяет
задействовать
операцию
prctl(2) PR_SET_MM();
- Позволяет
устанавливать
/proc/[pid]/oom_score_adj в
значение
меньшее,
чем
последнее
установленное
значение
процессом
с помощью
CAP_SYS_RESOURCE.
- CAP_SYS_TIME
- Позволяет
настраивать
системные
часы (settimeofday(2), stime(2),
adjtimex(2)) и часы
реального
времени
(аппаратные).
- CAP_SYS_TTY_CONFIG
- Позволяет
использовать
vhangup(2);
задействовать
различные
привилегированные
операции
ioctl(2) с
виртуальными
терминалами.
- CAP_SYSLOG
(начиная с Linux
2.6.37)
- Позволяет
выполнять
привилегированные
операции
syslog(2).
Смотрите в
syslog(2) какие
операции
требуют
прав.
- Позволяет
просматривать
адреса
ядра,
показываемые
в /proc и
других
интерфейсах,
когда
значение
/proc/sys/kernel/kptr_restrict
равно 1
(смотрите
описание
kptr_restrict в proc(5)).
- CAP_WAKE_ALARM
(начиная с Linux
3.0)
- Позволяет
вызывать
что-либо
при
пробуждении
системы
(устанавливать
таймеры
CLOCK_REALTIME_ALARM и CLOCK_BOOTTIME_ALARM).
Старая и
текущая
реализации
Для
полной
реализации
мандатов
требуется:
- 1.
- Для всех
привилегированных
операций
ядро
должно
проверять,
имеет ли
нить
требуемый
мандат в
его
эффективном
наборе.
- 2.
- Ядро
должно
предоставлять
системные
вызовы,
позволяющие
получать и
изменять
наборы
мандатов
нити.
- 3.
- Файловая
система
должна
поддерживать
присоединение
мандатов к
исполняемому
файлу для
того, чтобы
при
исполнении
файла у
процесса
повышались
права
согласно
этим
мандатам.
До ядра
версии 2.6.24
были
реализованы
только
первые два
пункта;
начиная с
версии 2.6.24
реализованы
все три
пункта.
Замечания
разработчикам
ядра
При
добавлении
новых
возможностей
ядра,
которые
должны
регулироваться
мандатом,
нужно
учитывать
некоторые
моменты.
- Цель
мандатов —
разделить
возможности
суперпользователя
на части, и
если
программа
с одним или
несколькими
мандатами
будет
скомпрометирована,
то её
возможности
нанести
вред
системе
будут
меньше, чем
от такой же
программы,
выполняемой
с правами
суперпользователя.
- Вы можете
создать
новый
мандат для
новой
возможности
или
привязать
возможность
к одному из
существующих
мандатов.
Чтобы
сохранить
набор
мандатов
приемлемого
размера,
последний
вариант
предпочтителен,
если нет
неопровержимых
доводов за
первый
вариант
(есть также
техническое
ограничение:
размер
набора
мандатов в
настоящее
время
ограничен
64 битами).
- Для
определения
какой
существующий
мандат мог
бы лучше
подойти
новой
возможности,
просмотрите
список
мандатов,
представленный
выше.
Выясните,
есть ли
другие
возможности,
требующие
мандатов,
которые
всегда
будут
использоваться
вместе с
новой
возможностью.
Если новая
возможность
бесполезна
без этих
других
возможностей,
то нужно
использовать
тот же
мандат как
у других
возможностей.
- Не
используйте
CAP_SYS_ADMIN, если
этого
можно
избежать! С
ним
связана
большая
часть
существующих
проверок
мандатов
(смотрите
часть
списка
выше). Его
оправданно
можно
называть
«новым
суперпользователем»,
так как с
одной
стороны, он
даёт
широкий
спектр
полномочий,
а с другой
его
широкий
спектр
действия
означает,
что данный
мандат
требуется
многим
привилегированным
программам.
Не делайте
проблему
хуже. Новые
возможности,
которые
должны
быть
связаны с
CAP_SYS_ADMIN должны
сильно
совпадать
с
существующими,
использующими
данное
хранилище.
- Если
действительно
необходимо
создать
новый
мандат для
новой
возможности,
не делайте
или
называйте
его как
«только
для этой
возможности».
То есть,
например,
добавление
очень
специализированного
CAP_SYS_PACCT было бы,
вероятно,
ошибкой.
Вместо
этого
попытайтесь
идентифицировать
и назвать
новый
мандат
более
вместительным
понятием, в
которое
могут
войти и
другие
будущие
возможности.
Наборы
мандатов
нити
Каждая
нить имеет
следующие
наборы
мандатов,
содержащие
ноль или
более
перечисленных
выше
мандатов:
- Permitted
- Ограничивающий
набор
эффективных
мандатов,
которыми
наделяется
нить. Этот
набор
также
ограничивает
список
мандатов,
которые
могут быть
добавлены
в
наследуемый
набор для
нити,
которая не
имеет
мандата
CAP_SETPCAP в своём
эффективном
наборе.
- Если нить
сбрасывает
мандат в
своём
разрешительном
наборе, то
она не
сможет
получить
его назад
(если
только не
выполняется
execve(2) для
программы
с set-user-ID-root или
программа,
чьи
соответствующие
мандаты
файла
предоставляют
этот
мандат).
- Inheritable
- Этот набор
мандатов
сохраняется
при вызове
execve(2).
Наследуемые
мандаты
остаются
наследуемыми
при
выполнении
любой
программы,
и
наследуемые
мандаты
добавляются
в
разрешительный
набор, если
выполняющаяся
программа
имеет
соответствующие
установленные
биты в
файловом
наследуемом
наборе.
- Так как
наследуемые
мандаты,
обычно, не
сохраняются
после execve(2),
если
выполнение
происходит
не от
суперпользователя,
то для
приложений,
которым
нужно
выполнять
вспомогательные
программы
с
повышенными
мандатами,
нужно
использовать
наружные
мандаты (ambient
capabilities),
описанные
ниже.
- Effective
- Данный
набор
мандатов
используется
ядром при
выполнении
проверок
прав нити.
- Bounding
(в каждой
нити
начиная с Linux
2.6.25)
- Ограничивающий
набор
мандатов —
это
механизм,
который
можно
использовать
для
ограничения
мандатов,
которые
могут быть
получены
при execve(2).
- Начиная с Linux
2.6.25 данный
набор
мандатов
есть у
каждой
нити. В
старых
ядрах
ограничивающий
набор
мандатов
был
системным
свойством,
единым для
всех нитей
в системе.
- Дополнительную
информацию
об
ограничивающем
наборе
мандатов
смотрите
далее.
- Ambient
(начиная с Linux
4.3)
- Данный
набор
мандатов
сохраняется
после execve(2)
для
непривилегированных
программ.
Для набора
наружных
мандатов (ambient
capability set)
соблюдается
правило,
что ни один
мандат не
сможет
быть
наружным,
если он
одновременно
разрешающий
и
наследуемый.
- Набор
наружных
мандатов
можно
непосредственно
изменять с
помощью prctl(2).
Наружные
мандаты
автоматически
понижаются,
если
понижаются
соответствующие
разрешительные
или
наследуемые
мандаты.
- При
запуске
программы,
у которой
изменяются
UID или GID из-за
set-user-ID или set-group-ID,
или у
которой
установлен
любой
набор
файловых
мандатов,
наружный
набор
будет
очищен.
Наружные
мандаты
добавляются
в
разрешающий
набори
назначаются
в
эффективный
набор при
вызове execve(2).
Если из-за
наружных
мандатов
увеличиваются
разрешающий
и
эффективный
наборы при
execve(2), то это
не
вызывает
режима
безопасного
выполнения,
описанного
в ld.so(8).
Потомок,
созданный
fork(2),
наследует
копии
наборов
мандатов
своего
родителя.
Далее
смотрите
описание
отношения
к
мандатами
при execve(2).
С помощью
capset(2) нить
может
изменять
свои
наборы
мандатов
(смотрите
далее).
Начиная с
Linux 3.2, файл
/proc/sys/kernel/cap_last_cap
содержит
числовое
значение
самого
большого
мандата,
поддерживаемого
работающим
ядром; это
может быть
использовано
для
определения
наибольшего
бита,
который
может быть
установлен
в наборе
мандатов.
Файловые
мандаты
Начиная с
ядра
версии 2.6.24, с
помощью setcap(8)
поддерживается
связь
наборов
мандатов с
исполняемым
файлом.
Наборы
мандатов
файла
хранятся в
расширенном
атрибуте
(смотрите
setxattr(2) и xattr(7)) с
именем security.capability.
Для записи
в этот
расширенный
атрибут
требуется
мандат CAP_SETFCAP.
Наборы
файловых
мандатов
вместе с
наборами
мандатов
нити
определяют
наборы
мандатов
нити после
выполнения
execve(2).
Три
файловых
набора
мандатов:
- Permitted
(ранее
называвшийся
forced):
- Эти
мандаты
автоматически
разрешаются
нити
независимо
от
унаследованных
мандатов
нити.
- Inheritable
(ранее
называвшийся
allowed):
- Этот набор
объединяется
(AND) с
унаследованным
набором
нити для
определения,
какие
унаследованные
мандаты
будут
включены в
разрешительный
набор нити
после execve(2).
- Effective:
- В
действительности,
это не
набор, а
одиночный
бит. Если
бит
включён, то
при вызове
execve(2) все
новые
разрешённые
мандаты
нити будут
также
добавлены
в
эффективный
набор. Если
бит
выключен,
то после execve(2)
ни один из
новых
разрешённых
мандатов
не будет
добавлен в
новый
эффективный
набор.
- Включение
эффективного
файлового
мандатного
бита
подразумевает,
что любой
файловый
разрешительный
или
наследуемый
мандат,
который
позволяет
нити
получить
соответствующий
разрешительный
мандат при
execve(2)
(смотрите
правила
преобразования,
описанные
далее),
также
получит
этот
мандат в
эффективном
наборе.
Поэтому,
когда
назначаются
мандаты
файлу (setcap(8),
cap_set_file(3), cap_set_fd(3)),
если мы
укажем
эффективный
флаг как
включённый
для любого
мандата, то
эффективный
флаг
должен
также быть
указан
включённым
для всех
остальных
мандатов,
для
которых
включён
соответствующий
разрешительный
или
наследуемый
флаги.
Версии
расширенного
атрибута
файловых
мандатов
С целью
расширяемости
ядро
поддерживает
схему
кодирования
номера
версии
внутри
расширенного
атрибута
security.capability,
который
используется
в
реализации
файловых
мандатов.
Эти номера
версий
введены
только для
реализации
и
непосредственно
не видны
приложениям
пользовательского
пространства.
В
настоящее
время
поддерживаются
следующие
версии:
- VFS_CAP_REVISION_1
- Первоначальная
реализация
файловых
мандатов,
поддерживает
32-битные
маски
файловых
мандатов.
- VFS_CAP_REVISION_2
(начиная с Linux
2.6.25)
- В данной
версии
поддерживаются
64-битные
маски
файловых
мандатов, и
и новый
номер
версии
стал
необходим
для
поддержки
мандатов
более 32.
Ядро
продолжает
прозрачно
поддерживать
выполнение
файлов с
32-битными
масками
мандатов
1-й версии,
но при
добавлении
мандатов к
файлам, у
которых их
ещё не
было, или
при
изменение
мандатов
существующих
файлов, оно
автоматически
использует
схему 2-й
версии
(или,
возможно,
схему 3-ей
версии как
описано
далее).
- VFS_CAP_REVISION_3
(начиная с Linux
4.14)
- Версия 3
файловые
мандатов
предоставляет
поддержку
файловых
мандатов
пространства
имён
(описано
далее).
- Как и в
версии 2,
версия 3
имеет
64-битную
маску
файловых
мандатов.
Но в
дополнении,
в
расширенном
атрибуте
security.capability
кодируется
ID
суперпользователя
пространства
имён (ID
суперпользователя
пространства
имён — это
значение,
на которое
отображается
пользовательский
ID 0 этого
пространства
имён в
изначальном
пользовательском
пространстве
имён).
- Файловые
мандаты
версии 3
могут
сосуществовать
с
мандатами
версии 2; то
есть в
современной
системе Linux
одни файлы
могут быть
с
мандатами
версии 2, а
другие с
версией 3.
До Linux 4.14
типом
мандата
расширенного
атрибута,
который
мог быть
присоединён
к файлу, был
только
атрибут
VFS_CAP_REVISION_2.
Начиная с Linux 4.14
версия
расширенного
атрибута
security.capability,
присоединённого
к файлу,
зависит от
обстоятельств,
при
которых
был создан
атрибут.
Начиная с
Linux 4.14,
расширенный
атрибут
security.capability
автоматически
создаётся
(или
преобразуется)
как
атрибут
версии 3
(VFS_CAP_REVISION_3), если
оба
условия
истинны:
- (1)
- Нить,
записывающая
атрибут,
расположена
не в
изначальном
пользовательском
пространстве
имён (более
точно: нить
располагается
в
пользовательском
пространстве
имён
отличном
от того, из
которого
смонтирована
нижележащая
файловая
система).
- (2)
- Нить имеет
мандат CAP_SETFCAP
поверх
файловой
иноды, то
есть (a) нит
имеет
мандат CAP_SETFCAP
в своём
собственном
пользовательском
пространстве
имён; и (b) UID и GID
файловой
иноды
отображаются
в
пользовательское
пространство
имён
записывающего.
При
создании
расширенного
атрибута
security.capability с типом
VFS_CAP_REVISION_3 ID
суперпользователя
пользовательского
пространства
имён
создающей
нити
сохраняется
в
расширенном
атрибуте.
Но при
создании
или
изменении
расширенного
атрибута
security.capability из
привилегированной
(CAP_SETFCAP) нити,
находящейся
в
пространстве
имён, в
котором
смонтирована
нижележащая
файловая
система
(обычно, это
изначальное
пользовательское
пространство
имён),
автоматически
вызывает
создание
атрибута с
версией 2
(VFS_CAP_REVISION_2).
Заметим,
что
создании
расширенного
атрибута
security.capability версии
3
происходит
автоматически.
То есть
когда
приложение
пользовательского
пространства
записывает
(setxattr(2))
атрибут
security.capability в
формате
версии 2
ядра
автоматически
создаёт
версию
атрибут
версии 3,
если
атрибут
создаётся
в условиях,
описанных
выше. И,
соответственно,
кода
атрибут
security.capability версии
3
возвращается
(getxattr(2))
процессу,
расположенному
в
пользовательском
пространстве
имён,
которое
было
создано с ID
суперпользователя
(или
потомком
этого
пользовательского
пространства
имён),
атрибут
(автоматически)
упрощается
до версии 2
(т. е.,
возвращаемое
значение
имеет
размер
атрибута
версии 2 и не
включает ID
суперпользователя).
Эти
автоматические
преобразования
позволяют
не
переписывать
требуемые
инструменты
пользовательского
пространства
(например,
setcap(1) и getcap(1)) для
создания и
получения
атрибута
security.capability версии
3.
Заметим,
что файл
может
иметь
расширенный
атрибут
security.capability версии
2 или версии
3, но не оба
одновременно:
создание
или
изменение
расширенного
атрибута
security.capability
автоматически
приведёт к
изменению
версии
согласно
условиям, в
которых он
изменяется.
Преобразование
мандатов
при execve()
При execve(2)
ядро
вычисляет
новые
мандаты
процесса
по
следующему
алгоритму:
P'(ambient) = (привилегированный файл) ? 0 : P(ambient)
P'(permitted) = (P(inheritable) & F(inheritable)) |
(F(permitted) & P(bounding)) | P'(ambient)
P'(effective) = F(effective) ? P'(permitted) : P'(ambient)
P'(inheritable) = P(inheritable) [т. е., не изменяется]
P'(bounding) = P(bounding) [т. е., не изменяется]
где:
Опишем
подробней
правила
преобразования
описанного
выше
мандата:
- Набор
мандатов ambient
появился
начиная с Linux
4.3. При
определении
преобразования
набора ambient в
execve(2)
привилегированный
файл — это
файл,
имеющий
один из
этих
мандатов,
или у него
установлен
бит set-user-ID или
set-group-ID.
- До Linux 2.6.25
ограничивающий
набор
мандатов
был
общесистемным
атрибутом,
общим для
всех нитей.
Его
значение
использовалось
для
вычисления
нового
разрешительного
набора в execve(2)
таким же
образом
как для P(bounding),
показанном
выше.
Замечание:
во время
изменений
мандатов,
описанных
выше,
файловые
мандаты
могут
игнорироваться
(считаться
пустыми) по
тем же
причинам
что и
игнорируются
биты set-user-ID и set-group-ID;
смотрите
execve(2).
Файловые
мандаты
также
игнорируются,
если ядро
было
загружено
с
параметром
no_file_caps.
Замечание:
в
соответствии
с
правилами
выше, если
процесс
ненулевым
идентификатором
пользователя
выполняет
execve(2), то все
его
мандаты в
разрешительном
и
действующим
наборах
будут
очищены.
Учёт
мандатов в
случае,
когда
процесс
имеет
нулевой
идентификатор
пользователя
и
выполняет
execve(2), описан
далее в
разделе
Мандаты и
выполнение
программы
с правами
root.
Проверка
на
безопасность
двоичных
файлов, не
отзывчивых
к мандатам
Двоичный
файл, не
отзывчивый
к мандатам
(capability-dumb binary) — это
приложение,
которое
помечено
как
имеющее
файловые
мандаты, но
не
преобразованное
для работы
с
программным
интерфейсом
libcap(3) для
управления
своими
мандатами
(иначе
говоря, это
обычная set-user-ID-root
программа,
у которой
указали
файловые
мандаты, но
код
которой не
был
изменён
для
понимания
мандатов). У
таких
приложений
на файле
установлен
эффективный
файловый
мандатный
бит, из-за
чего при
исполнении
файла у его
процесса в
эффективном
наборе
автоматически
включаются
разрешительные
мандаты.
Если ядро
считает
файл с
установленным
эффективным
файловым
мандатным
битом не
отзывчивым
к мандатам,
то
выполняются
проверки,
описанные
далее.
При
запуске
выполняемого
файла, не
отзывчивого
к мандатам,
ядро
проверяет
получил ли
процесс
все
разрешительные
мандаты,
указанные
в файловом
разрешительном
наборе,
после
преобразований
мандатов,
описанных
выше
(обычной
причиной,
почему это
может не
произойти,
является
то, что
ограничивающий
набор
мандатов
перекрывает
некоторые
мандаты из
файлового
разрешительного
набора).
Если
процесс не
получил
полный
набор
файловых
разрешительных
мандатов,
то execve(2)
завершится
с ошибкой
EPERM. Это
предотвращает
возникновение
проблем с
безопасностью,
которые
могли бы
появиться,
если
приложение,
не
отзывчивое
к мандатам,
выполняется
с меньшими
правами
чем
требуется.
Заметим,
что по
определению
само
приложение
не может
увидеть
эту
проблему,
так как не
используется
программный
интерфейс
libcap(3).
Мандаты и
выполнение
программ с
правами root
Чтобы
отразить
обычную
семантику
UNIX, ядро
выполняет
специальные
действия с
файловыми
мандатами,
когда
процесс с UID 0
(корневой)
выполняет
программу
и когда
выполняется
программа
с set-user-ID-root.
После
применения
изменений
к
эффективному
ID процесса,
которые
возникли
из-за
режимного
бита set-user-ID у
исполняемого
файла —
например,
переключение
действующего
ID
пользователя
на 0 (root) из-за
запуска
программы
с set-user-ID-root — ядро
вычисляет
набор
файловых
мандатов
следующим
образом:
- 1.
- Если
реальный и
эффективный
ID
пользователя
процесса
равен 0 (root), то
файловый
разрешительные
или
наследуемые
наборы
игнорируются;
вместо
этого
условно
считается,
что все их
биты
установлены
(т. е.,
разрешены
все
мандаты).
(Существует
одно
исключение
из этого
правила,
описано в
Программы
set-user-ID-root с
файловыми
мандатами.)
- 2.
- Если
эффективный
ID
пользователя
процесса
равен 0 (root) или
файловый
эффективный
бит
фактически
установлен,
то
файловый
эффективный
бит
условно
считается
равным
единице
(включен).
Затем эти
условные
значения
файлового
набора
мандатов
используются,
как
описано
выше, для
вычисления
преобразования
мандатов
процесса
при execve(2).
Таким
образом,
когда
процесс с
ненулевым UID
запускает
с помощью
execve(2)
программу
с set-user-ID-root, у
которой
нет
присоединённых
мандатов,
или когда
процесс,
чей
реальный и
эффективный
UID равны
нулю,
запускают
программу
через execve(2),
вычисление
новых
разрешённых
мандатов
упрощается
до:
P'(permitted) = P(inheritable) | P(bounding)
P'(effective) = P'(permitted)
В связи с
этим,
процесс
получает
все
мандаты в
своих
разрешительном
и
эффективном
наборе
мандатов ,
за
исключением
заглушаемых
ограничивающим
набором
мандатов. (В
вычислении
P'(permitted),
значение P'(ambient)
можно
сократить,
так как оно
определяется
корректным
поднабором
P(inheritable).)
Специальное
действие
для ID
пользователя
0 (root),
описанное
в этом
абзаце,
можно
отключить
с помощью
механизма
securebits,
описанного
далее.
Программы
set-user-ID-root с
файловыми
мандатами
Есть одно
исключение
в
поведении,
описанном
в Мандаты
и
выполнение
программ с
правами root.
Если (a) к
исполняемому
двоичному
файлу
присоединены
мандаты и (b)
реальный
пользовательский
ID процесса
не равен 0 (root)
и (c)
эффективный
пользовательский
ID процесса
равен 0 (root), то
биты
файловых
мандатов
учитываются
(т. е., они не
условно
считаются
установленными
в единицы).
Обычно, эта
ситуация
может
возникать
при
исполнении
программы
с set-UID-root, у
которой
также
заданы
файловые
мандаты.
При
выполнении
такой
программы
процесс
получает
только
мандаты,
данные
программе
(т. е., не все
мандаты,
как это
происходит,
когда
выполняемая
программа
с set-user-ID-root не
имеет
связанных
файловых
мандатов).
Заметим,
что файлу
программы
можно
назначить
пустой
набор
мандатов, и
таким
образом
возможно
создать
программу
с set-user-ID-root,
которая
изменяет
эффективный
и
сохранённый
set-user-ID
процесса,
исполняющего
программу,
на 0, но не
даёт
мандаты
этому
процессу.
Ограничивающий
набор
мандатов
Ограничивающий
набор
мандатов —
это
механизм
безопасности,
который
можно
использовать
для
ограничения
мандатов,
которые
могут быть
получены
при execve(2).
Ограничивающий
набор
используется
так:
- При execve(2)
ограничивающий
набор
мандатов
складывается
(AND) с
файловым
разрешительным
набором
мандатов, и
результат
этой
операции
назначается
разрешительному
набору
мандатов
нити. Таким
образом,
ограничивающий
набор
мандатов
ограничивает
разрешённые
мандаты,
которые
может
предоставить
исполняемый
файл.
- (начиная с Linux
2.6.25)
Ограничивающий
набор
мандатов
служит
ограничивающим
набором
мандатов,
которые
нить может
добавить в
свой
наследуемый
набор с
помощью capset(2).
Это
означает,
что если
мандат
отсутствует
в
ограничивающем
наборе
мандатов,
то нить не
может
добавить
этот
мандат в
свой
наследуемый
набор даже,
если он
есть в
разрешительном
наборе
мандатов и
поэтому не
может
сохранить
данный
мандат в
разрешительный
набор при
вызове execve(2)
для файла,
который
имеет
мандат в
своём
наследуемом
наборе.
Заметим,
что
ограничивающий
набор
скрывает
файловые
разрешительные
мандаты, но
не
наследуемые
мандаты.
Если нить
имеет
мандат в
своём
наследуемом
наборе,
который
отсутствует
в
ограничивающем
наборе, то
она
по-прежнему
обладает
этим
мандатом в
своём
разрешительном
наборе при
выполнении
файла,
который
имеет
мандат в
своём
наследуемом
наборе.
В
зависимости
от версии
ядра
ограничивающий
набор
мандатов
является
либо
системным
свойством,
либо
атрибутом
процесса.
Ограничивающий
набор
мандатов
начиная с Linux
2.6.25
Начиная с
Linux 26.25,
ограничивающий
набор
мандатов
является
атрибутом
нити
(системного
ограничивающего
набора
мандатов,
описываемого
далее,
больше
нет).
Ограничивающий
набор
наследуется
при fork(2) от
нити
родителя и
сохраняется
при execve(2).
Нить
может
удалять
мандаты из
своего
ограничивающего
набора
мандатов с
помощью
вызова prctl(2) с
операцией
PR_CAPBSET_DROP при
наличии
мандата CAP_SETPCAP.
После
удаления
мандата из
ограничивающего
набора
обратно
его
восстановить
невозможно.
Нить может
определить
наличие
мандата в
своём
ограничивающем
наборе с
помощью
вызова prctl(2) с
операцией
PR_CAPBSET_READ.
Удаление
мандатов
из
ограничивающего
набора
доступно
только,
если ядро
собрано с
поддержкой
файловых
мандатов. В
ядре Linux до
версии 2.6.33
файловые
мандаты
являлись
необязательным
свойством,
настраиваемым
параметром
CONFIG_SECURITY_FILE_CAPABILITIES.
Начиная с Linux
2.6.33, параметр
настройки
был удалён
и теперь
файловые
мандаты
всегда
являются
частью
ядра. Когда
файловые
мандаты в
ядре,
процесс init
(предок
всех
процессов)
запускается
с полным
ограничивающим
набором.
Если
файловые
мандаты не
добавлены
в ядро, то init
запускается
с полным
ограничивающим
набором
минус CAP_SETPCAP,
так как
этот
мандат
имеет
другое
значение,
если
файловые
мандаты
отсутствуют.
Удаление
мандата из
ограничивающего
набора не
удаляет
его из
наследуемого
набора
нити.
Однако это
предотвращает
от
добавления
мандата
обратно в
наследуемый
набор нити
в будущем.
Ограничивающий
набор
мандатов
до Linux 2.6.25
В ядрах до
версии 2.6.25
ограничивающий
набор
мандатов
был
системным
атрибутом,
который
влиял на
все нити
системы.
Ограничивающий
набор
доступен
через файл
/proc/sys/kernel/cap-bound (по
непонятной
причине,
данный
параметр,
битовая
маска, в
/proc/sys/kernel/cap-bound
записывался
в виде
знакового
десятичного
числа).
Только
процесс init
может
задавать
мандаты в
ограничивающем
наборе
мандатов;
помимо
этого,
суперпользователь
(точнее,
процесс с
мандатом
CAP_SYS_MODULE) может
только
удалять
мандаты из
набора.
В
стандартной
системе в
ограничивающем
наборе
мандатов
всегда
удаляется
мандат CAP_SETPCAP.
Чтобы
убрать это
ограничение
(опасно!),
нужно
изменить
определение
CAP_INIT_EFF_SET в include/linux/capability.h и
пересобрать
ядро.
Системное
свойство,
ограничивающий
набор
мандатов,
было
добавлено
в ядро Linux
версии 2.2.11.
Влияние
изменения
пользовательского
ID на
мандаты
Для
сохранения
привычной
семантики
при
переходе
от 0 к
ненулевым
пользовательским
ID, ядро
делает
следующие
изменения
наборов
мандатов
нити при
изменении
у нити
реального,
эффективного,
сохранённого
ID и
пользовательского
ID файловой
системы (с
помощью setuid(2),
setresuid(2) или
подобных):
- 1.
- Если ранее
реальный,
эффективный
или
сохранённый
пользовательский
ID не был
равен 0, и в
результате
изменения
UID все эти ID
получили
ненулевое
значение,
то все
мандаты
удаляются
из
разрешительного,
эффективного,
и
наружного
набора
мандатов.
- 2.
- Если
эффективный
пользовательский
ID
изменяется
с 0 на
ненулевое
значение,
то все
мандаты
удаляются
из
эффективного
набора
мандатов.
- 3.
- Если
эффективный
пользовательский
ID
изменяется
с
ненулевого
значения
на 0, то
разрешительный
набор
копируется
в
эффективный
набор.
- 4.
- Если
пользовательский
ID файловой
системы
изменяется
с 0 на
ненулевое
значение
(смотрите
setfsuid(2)), то
следующие
мандаты
удаляются
из
эффективного
набора: CAP_CHOWN,
CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER,
CAP_FSETID, CAP_LINUX_IMMUTABLE
(начиная с Linux
2.6.30), CAP_MAC_OVERRIDE и CAP_MKNOD
(начиная с Linux
2.6.30). Если
пользовательский
ID файловой
системы
изменяется
с
ненулевого
значения
на 0, то
любой из
мандатов,
включённых
в
разрешительный
набор,
включается
в
эффективном
наборе.
Если нить,
у которой
один или
более
пользовательских
ID равно 0,
хочет
предотвратить
удаление
разрешительных
мандатов
при сбросе
всех
пользовательских
ID в
ненулевые
значения,
то она
может
использовать
флаг SECBIT_KEEP_CAPS в
securebits,
описанный
далее.
Программное
изменение
наборов
мандатов
Нить
может
получать и
изменять
свои
разрешительные,
действующие
и
наследуемые
наборы
мандатов с
помощью
системных
вызовов capget(2)
и capset(2). Однако
для этой
цели лучше
использовать
cap_get_proc(3) и cap_set_proc(3) из
пакета libcap.
Следующие
правила
применяются
при
изменении
наборов
нити:
- 1.
- Если
вызывающий
не имеет
мандата
CAP_SETPCAP, то
новый
наследуемый
набор
должен
быть
поднабором
комбинации
существующего
наследуемого
и
разрешительного
наборов.
- 2.
- (начиная с Linux
2.6.25) Новый
наследуемый
набор
должен
быть
поднабором
комбинации
существующего
наследуемого
и
ограничивающего
наборов.
- 3.
- Новый
разрешительный
набор
должен
быть
поднабором
существующего
разрешительного
набора (т. е.,
невозможно
приобрести
разрешительные
мандаты,
которых
нить не
имеет).
- 4.
- Новый
эффективный
набор
должен
быть
поднабором
нового
разрешительного
набора.
Флаги securebits:
организация
исключительно
мандатного
окружения
Начиная с
ядра
версии 2.6.26 с
включённой
поддержкой
файловых
мандатов, в
Linux
реализован
набор
флагов securebits
(для каждой
нити),
который
можно
использовать
для
отключения
специальных
действий
мандатов
для UID 0 (root). К
этим
флагам
относятся:
- SECBIT_KEEP_CAPS
- Установка
этого
флага
позволяет
нити иметь
один или
более 0 UIDов,
чтобы
оставить
мандаты в
разрешительном
наборе,
когда она
переключается
все свои UIDы
в
ненулевые
значения.
Если этот
флаг не
установлен,
то
переключение
такого UID
приводит к
тому, что
нить
теряет все
мандаты в
этих
наборах.
Этот флаг
всегда
сбрасывается
при execve(2).
- Заметим,
что даже с
установленным
флагом SECBIT_KEEP_CAPS
эффективные
мандаты
нити
очищаются,
когда она
переключает
свой
эффективный
UID на
ненулевое
значение.
Однако,
если нить
устанавливает
этот флаг и
её
эффективный
UID уже не
равен нулю
и затем
нить
переключает
все другие
UID в
ненулевые
значения,
то
эффективные
мандаты не
будут
очищены.
- Установка
флага SECBIT_KEEP_CAPS
игнорируется,
если
указан
флаг SECBIT_NO_SETUID_FIXUP
(этот флаг
предоставляет
надмножество
свойств
первого
флага).
- Этот флаг
предоставляет
возможности
старой
операции
PR_SET_KEEPCAPS вызова
prctl(2).
- SECBIT_NO_SETUID_FIXUP
- Установка
этого
флага не
даёт ядру
изменить
разрешительный,
эффективный
и наружный
набор
мандатов
при
изменении
эффективного
UID и UID
файловой
системы
нити с 0 на
ненулевое
значение
(смотрите
раздел
Влияние
изменения
пользовательского
ID на
мандаты).
- SECBIT_NOROOT
- Если этот
бит
установлен,
то ядро не
предоставляет
мандаты
при
исполнении
программы,
имеющей
бит set-user-ID-root, или
когда
процесс с
эффективным
или
реальным UID
равным 0
вызывает
execve(2)
(смотрите
раздел
Мандаты и
выполнение
программа
от root).
- SECBIT_NO_CAP_AMBIENT_RAISE
- Установка
этого
флага
запрещает
повышение
наружных
мандатов
посредством
prctl(2)с
операцией
PR_CAP_AMBIENT_RAISE.
Каждый из
перечисленных
выше
«базовых»
флагов
имеет
дополнительный
флаг
«блокировки».
Установка
любого из
флагов
«блокировки»
необратима
и
запрещает
дальнейшие
изменения
соответствующего
«базового»
флага.
Флаги
блокировки:
SECBIT_KEEP_CAPS_LOCKED, SECBIT_NO_SETUID_FIXUP_LOCKED,
SECBIT_NOROOT_LOCKED и
SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED.
Флаги securebits
можно
изменять и
получать с
помощью
вызова prctl(2) с
операциями
PR_SET_SECUREBITS и PR_GET_SECUREBITS.
Для
изменения
флагов
требуется
мандат CAP_SETPCAP.
Заметим,
что
константы
SECBIT_*
доступны
только
после
включения
в код
заголовочного
файла
<linux/securebits.h>.
Флаги securebits
наследуются
дочерними
процессами.
При execve(2) все
флаги
сохраняются,
за
исключением
SECBIT_KEEP_CAPS,
который
всегда
сбрасывается.
Приложение
может
использовать
следующий
вызов для
собственной
блокировки
и
помещение
всех своих
потомков в
окружение,
в котором
есть
только
один
способ
добавить
права —
запустить
программу
со
связанными
с ней
файловыми
мандатами:
prctl(PR_SET_SECUREBITS,
/* SECBIT_KEEP_CAPS off */
SECBIT_KEEP_CAPS_LOCKED |
SECBIT_NO_SETUID_FIXUP |
SECBIT_NO_SETUID_FIXUP_LOCKED |
SECBIT_NOROOT |
SECBIT_NOROOT_LOCKED);
/* установка/блокировка SECBIT_NO_CAP_AMBIENT_RAISE
не требуется */
Программы
set-user-ID-root с
отдельными
пространствами
имён
пользователя
Программе
set-user-ID, чей UID
совпадает
с UID
создателя
пространства
имён
пользователя,
будут
предоставлены
мандаты в
разрешительном
и
эффективном
наборах,
при
выполнении
любого
процесса
внутри
этого
пространства
имён или в
любом
дочернем
пространстве
имён
пользователя.
Правила
преобразования
мандатов
процесса
при execve(2)
точно
такие же
как
описаны в
подразделах
Преобразование
мандатов
при execve() и
Мандаты и
выполнение
программы
с правами root,
но с
отличием: в
последнем
подразделе
«root» это UID
создателя
пространства
имён
пользователя.
Файловые
мандаты
пространства
имён
Обычные
(т. е., с
версией 2)
файловые
мандаты
представляют
собой
только
связь
набора
мандатных
масок и
двоичного
исполняемого
файла.
Когда
процесс
выполняет
двоичный
файл с
такими
мандатами
он
получает
присоединённые
мандаты
(внутри
своего
пользовательского
пространства
имён)
согласно
правилам,
описанным
выше в
«Преобразование
мандатов
при execve()».
Так как
файловые
мандаты
версии 2
предоставляются
выполняющемуся
процессу
независимо
от того, в
каком
пользовательском
пространстве
имён он
располагается,
то только
привилегированным
процессам
разрешено
связывать
мандаты с
файлом.
Здесь
«привилегированным»
считается
процесс,
имеющий
мандат CAP_SETFCAP в
пользовательском
пространстве
имён, в
котором
была
смонтирована
файловая
система
(обычно,
изначальное
пользовательское
пространство
имён). Это
ограничение
в
определённых
случаях
делает
файловые
мандаты
бесполезными.
Например, в
контейнерах
пользовательских
пространств
имён может
требоваться
возможность
создания
двоичных
файлов,
которые
предоставляют
мандаты
только
процессам,
выполняемым
внутри
контейнера,
но не
процессам,
выполняемым
вне
контейнера.
В Linux 4.14
добавлены
так
называемые
файловые
мандаты
пространства
имён; это
введено
специально
для таких
случаев.
Файловые
мандаты
пространства
имён
записываются
в версию 3 (т.
е., VFS_CAP_REVISION_3)
расширенных
атрибутов
security.capability. Данный
атрибут
автоматически
создаётся
при
условиях,
описанных
выше в
«Версии
расширенного
атрибута
файловых
мандатов».
Когда
создаётся
расширенный
атрибутsecurity.capability
версии 3
ядро
записывает
в
расширенный
атрибут не
только
маску
мандатов,
но и ID
суперпользователя
пространства
имён.
Подобно
двоичному
файлу с
файловыми
мандатами
VFS_CAP_REVISION_2 файл с
файловыми
мандатами
VFS_CAP_REVISION_3
предоставляет
мандаты
процессу
при execve().
Однако
мандаты
предоставляются
только,
если
двоичный
файл,
выполняемый
процессом,
располагается
в
пользовательском
пространстве
имён, в
котором UID 0
отображается
в ID
суперпользователя,
сохранённого
в
расширенном
атрибуте,
или когда
выполняется
процессом,
располагаемом
в потомке
такого
пространства
имён.
Взаимодействие
с
пользовательскими
пространствами
имён
Дополнительную
информацию
о связи
мандатов с
пространствами
пользователя
смотрите в
user_namespaces(7).