CAPGET(2) | Руководство программиста Linux | CAPGET(2) |
capget, capset - установка/получение мандатов нити(ей)
#include <sys/capability.h>
int capget(cap_user_header_t hdrp, cap_user_data_t datap);
int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
Данные системные вызовы представляют собой низкоуровневый интерфейс ядра для получения и установки мандатов нити. Кроме того, что эти системные вызовы есть только в 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 добавлена в Linux 2.6.25; устарело */ #define _LINUX_CAPABILITY_VERSION_2 0x20071026 #define _LINUX_CAPABILITY_U32S_2 2 /* V3 добавлена в 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 описаны только указатели.
Ядра до версии 2.6.25 предъявляют 32-битные мандаты с версией _LINUX_CAPABILITY_VERSION_1. В Linux 2.6.25+ добавлены 64-битные наборы мандатов с версией _LINUX_CAPABILITY_VERSION_2. Однако имеется незначительная проблема в программном интерфейсе и в Linux 2.6.26 добавлена _LINUX_CAPABILITY_VERSION_3 для её исправления.
Заметим, что в 64-битных мандатах используются datap[0] и datap[1], в то время как в 32-битных только datap[0].
В ядрах, которые поддерживают файловые мандаты (поддержка мандатов VFS) эти системные вызовы ведут себя немного по-другому. Данная поддержка добавлена как необязательная в Linux 2.6.24 и стала постоянной (не отключаемой) в Linux 2.6.33.
С помощью вызова capget() можно выполнить проверку мандатов любого процесса, указав его ID в поле hdrp->pid.
Подробную информацию о данных смотрите в capabilities(7).
Для мандатов VFS используется расширенный атрибут файла (смотрите xattr(7)), позволяющий присоединять мандаты к исполняемым файлам. Данная модель привилегий делает устаревшей ядерную поддержку асинхронного назначения мандатов одного процесса другому. То есть в ядрах с мандатами VFS при вызове capset() разрешены только значения hdrp->pid равные 0 или gettid(2), что приводит к тому же результату.
В старых ядрах без поддержки мандатов 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. Таким способом можно проверить какая версия мандатов является предпочтительной.
Данные системные вызовы есть только в Linux.
Переносимый интерфейс для запроса и установки мандатов предоставляется библиотекой libcap, которая доступна по адресу: http://git.kernel.org/cgit/linux/kernel/git/morgan/libcap.git
2019-03-06 | Linux |