capget(2) | System Calls Manual | capget(2) |
ИМЯ
capget, capset - установка/получение мандатов нити(ей)
БИБЛИОТЕКА
Стандартная библиотека языка C (libc, -lc)
СИНТАКСИС
#include <linux/capability.h> /* Definition of CAP_* and _LINUX_CAPABILITY_* constants */ #include <sys/syscall.h> /* Definition of SYS_* constants */ #include <unistd.h>
int syscall(SYS_capget, cap_user_header_t hdrp, cap_user_data_t datap); int syscall(SYS_capset, cap_user_header_t hdrp, const cap_user_data_t datap);
Примечание: glibc не предоставляет обёрточных функций для этих системных вызовов, что делает необходимым использование syscall(2).
ОПИСАНИЕ
Данные системные вызовы представляют собой низкоуровневый интерфейс ядра для получения и установки мандатов нити. Кроме того, что эти системные вызовы есть только в Linux, из-за них, вероятно, изменится программный интерфейс ядра; с каждой новой версией ядра эти вызовы используются всё чаще (в частности, типы cap_user_*_t), но старые программы работают как и прежде.
Переносимыми интерфейсами являются cap_set_proc(3) и cap_get_proc(3); если возможно, в приложениях используйте именно их; смотрите ЗАМЕЧАНИЯ.
Подробная информация
На данный момент в ядре определены следующие структуры:
#define _LINUX_CAPABILITY_VERSION_1 0x19980330 #define _LINUX_CAPABILITY_U32S_1 1 /* V2 added in Linux 2.6.25; deprecated */ #define _LINUX_CAPABILITY_VERSION_2 0x20071026 #define _LINUX_CAPABILITY_U32S_2 2 /* V3 added in Linux 2.6.26 */ #define _LINUX_CAPABILITY_VERSION_3 0x20080522 #define _LINUX_CAPABILITY_U32S_3 2 typedef struct __user_cap_header_struct { __u32 version; int pid; } *cap_user_header_t; typedef struct __user_cap_data_struct { __u32 effective; __u32 permitted; __u32 inheritable; } *cap_user_data_t;
Поля effective, permitted и inheritable — это битовые маски мандатов, определённых в capabilities(7). Заметим, что значения CAP_* являются индексами битов и требуется сдвиг битов перед выполнением операции ИЛИ над битовыми полями. Чтобы определить структуры для передачи в системный вызов, используйте имена struct __user_cap_header_struct и struct __user_cap_data_struct, так как посредством typedef описаны только указатели.
Kernels prior to Linux 2.6.25 prefer 32-bit capabilities with version _LINUX_CAPABILITY_VERSION_1. Linux 2.6.25 added 64-bit capability sets, with version _LINUX_CAPABILITY_VERSION_2. There was, however, an API glitch, and Linux 2.6.26 added _LINUX_CAPABILITY_VERSION_3 to fix the problem.
Заметим, что в 64-битных мандатах используются datap[0] и datap[1], в то время как в 32-битных только datap[0].
В ядрах, которые поддерживают файловые мандаты (поддержка мандатов VFS) эти системные вызовы ведут себя немного по-другому. Данная поддержка добавлена как необязательная в Linux 2.6.24 и стала постоянной (не отключаемой) в Linux 2.6.33.
С помощью вызова capget() можно выполнить проверку мандатов любого процесса, указав его ID в поле hdrp->pid.
Подробную информацию о данных смотрите в capabilities(7).
Ядро с поддержкой мандатов VFS
Для мандатов VFS используется расширенный атрибут файла (смотрите xattr(7)), позволяющий присоединять мандаты к исполняемым файлам. Данная модель привилегий делает устаревшей ядерную поддержку асинхронного назначения мандатов одного процесса другому. То есть в ядрах с мандатами VFS при вызове capset() разрешены только значения hdrp->pid равные 0 или gettid(2), что приводит к тому же результату.
Ядро без поддержки мандатов VFS
В старых ядрах без поддержки мандатов VFS вызов capset(), если вызывающий имеет мандат CAP_SETPCAP, можно использовать для изменения не только собственными мандатами вызывающего, то и мандатами других нитей. Вызов работает с мандатами нити, указанной в в поле pid из hdrp, если оно не равно нулю, или мандатами вызывающей нити, когда pid равно 0. Если pid указывает на процесс с одной нитью, то значением pid может быть обычным идентификатором процесса; работа с нитью в многонитиевом процессе требует ID нити такого же типа, что и возвращается gettid(2). У capset() pid также может быть: -1 — выполнить изменение у всех нитей, за исключением вызывающей и init(1); меньше -1 — выполнить изменение всех членов группы процесса, чей ID равен -pid.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается 0. При ошибке возвращается -1, а в errno содержится код ошибки.
Вызовы завершаются с ошибкой EINVAL и изменяют поле version в hdrp на предпочитаемое ядром значение _LINUX_CAPABILITY_VERSION_?, если указано неподдерживаемое значение version. Таким способом можно проверить какая версия мандатов является предпочтительной.
ОШИБКИ
- EFAULT
- Неправильный адрес памяти. Значение hdrp не должно быть равно NULL. Значение datap может быть NULL только, когда пользователь пытается определить предпочтительную версию формата мандатов, поддерживаемую ядром.
- EINVAL
- Один из аргументов неправилен.
- EPERM
- An attempt was made to add a capability to the permitted set, or to set a capability in the effective set that is not in the permitted set.
- EPERM
- An attempt was made to add a capability to the inheritable set, and either:
- •
- that capability was not in the caller's bounding set; or
- •
- the capability was not in the caller's permitted set and the caller lacked the CAP_SETPCAP capability in its effective set.
- EPERM
- The caller attempted to use capset() to modify the capabilities of a thread other than itself, but lacked sufficient privilege. For kernels supporting VFS capabilities, this is never permitted. For kernels lacking VFS support, the CAP_SETPCAP capability is required. (A bug in kernels before Linux 2.6.11 meant that this error could also occur if a thread without this capability tried to change its own capabilities by specifying the pid field as a nonzero value (i.e., the value returned by getpid(2)) instead of 0.)
- ESRCH
- Такой нити нет.
СТАНДАРТЫ
Linux.
ПРИМЕЧАНИЯ
Переносимый
интерфейс
для
запроса и
установки
мандатов
предоставляется
библиотекой
libcap, которая
доступна
по адресу:
http://git.kernel.org/cgit/linux/kernel/git/morgan/libcap.git
СМОТРИТЕ ТАКЖЕ
ПЕРЕВОД
Русский перевод этой страницы руководства разработал(и) Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy S. Seregin <dseregin@59.ru>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, Katrin Kutepova <blackkatelv@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>
Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков.
2 мая 2024 г. | Справочные страницы Linux 6.9.1 |