Какой механизм определяет, что setgroups () и initgroups () должны вызываться с суперпользователем? - PullRequest
0 голосов
/ 05 сентября 2018

от APUE

#include <grp.h> /* on Linux */
int setgroups(int ngroups, const gid_t grouplist[]);

Функция setgroups может быть вызвана суперпользователем для установки списка дополнительных идентификаторов групп для вызывающего процесса: grouplist содержит массив идентификаторов групп, и ngroups определяет количество элементов в массиве. Значение ngroups не может быть больше, чем NGROUPS_MAX.

#include <grp.h> /* on Linux and Solaris */
int initgroups(const char *username, gid_t basegid);

Для вызова initgroups() нужно быть суперпользователем , так как он вызывает setgroups().

Какой механизм определяет, что setgroups() и initgroups() должны вызываться суперпользователем?

Под «механизмом» я подразумеваю нечто подобное или аналогичное следующему. в Linux я узнал, что мы можем определить доступность процесса к файлу на основе списка контроля доступа (ACL):

  • эффективный идентификатор пользователя, эффективный идентификатор группы и дополнительные идентификаторы группы процесса и

  • биты прав доступа к файлу.

Спасибо.

Ответы [ 3 ]

0 голосов
/ 05 сентября 2018

В Linux, если процесс имеет возможность CAP_SETGID , ядро ​​будет обрабатывать вызовы setgid(), setegid(), setregid(), setresgid() и setgroups() (если не отказано модулем безопасности Linux, таким как SELinux).

Существует два основных механизма, которыми непривилегированный пользователь может получить возможность:

  • Наследование от привилегированного процесса. Для обычных пользователей дополнительные возможности могут предоставляться модулями PAM при входе в систему.

  • Через возможности файловой системы.

Возможности файловой системы более интересны и полезны для сервисов / приложений. Они работают только для двоичных файлов, а не для сценариев, потому что ядро ​​обновляет возможности как часть механизма для выполнения двоичных файлов; сценарии интерпретируются оболочками с использованием совершенно другого, полностью пользовательского механизма.

(Файловая система должна поддерживать расширенные атрибуты. Некоторые файловые системы, такие как ext2, ext3 и reiserfs, должны быть смонтированы с опцией монтирования user_xattr для включения расширенных атрибутов. Ext4, xfs, jfs, btrfs и zfs все должны поддерживать расширенные атрибуты атрибутов с использованием параметров монтирования по умолчанию. Некоторые дистрибутивы Linux, такие как Debian и Ubuntu, уже используют расширенные атрибуты и возможности файловой системы.)

Примечание: вы можете использовать утилиты getcap и lsattr для проверки возможностей двоичной файловой системы и расширенных атрибутов. В моей системе Ubuntu 16.04.4 LTS двоичный файл /usr/bin/systemd-detect-virt имеет разрешенные и эффективные возможности CAP_DAC_OVERRIDE и CAP_SYS_PTRACE.

Использование возможностей файловой системы на практике очень просто, но для безопасной работы сначала следует тщательно рассмотреть последствия для безопасности: это мощный инструмент, но вы (разработчик, менеджер пакетов и / или системный администратор) несете ответственность за уверен, что он используется правильно.

Например, если вы устанавливаете /usr/bin/yourprog, который является доверенным и требует возможности CAP_SETGID, все, что вам нужно сделать, - это установить эту возможность, разрешенную и эффективную для этого двоичного файла. Для этого вы запускаете setcap cap_setgid=pe /usr/bin/yourprog с правами root. (В сценарии установки пакета Debian .deb, который обычно запускается в сценарии после установки.)

0 голосов
/ 05 сентября 2018

Вы можете посмотреть действительный код для групп . Это начинается так:

SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist)
{
    struct group_info *group_info;
    int retval;

    if (!may_setgroups())
        return -EPERM;

    // other stuff
}

А вот и may_setgroups:

bool may_setgroups(void)
{
    struct user_namespace *user_ns = current_user_ns();

    return ns_capable(user_ns, CAP_SETGID) &&
        userns_may_setgroups(user_ns);
}

А вот userns_may_setgroups, если вы не используете пространства имен пользователя:

static inline bool userns_may_setgroups(const struct user_namespace *ns)
{
    return true;
}

Итак: setgroups вернет EPERM ошибку , если у вас нет возможности CAP_SETGID .

Следствие: Вы можете позвонить setgroups, если у вас есть возможность CAP_SETGID.

Root имеет все возможности автоматически (поэтому root может вызывать setgroups), но вы также можете вызвать его, если вы не root и у вас есть возможность CAP_SETGID.

0 голосов
/ 05 сентября 2018

Формулировка в APUE, возможно, немного неточна; это учебное пособие для программистов, а не юридический сборник. Любой процесс может вызвать setgroups() или initgroups(). Но если процесс не имеет привилегий root, функция не сделает ничего, кроме как установит errno в EPERM и вернет сообщение об ошибке.

Очевидно, что проверка прав не может быть выполнена с правами пользователя. Функция библиотеки - это просто оболочка вокруг системного вызова, и тесты выполняются внутри ядра.

Что стоит, вот первый хит, который Google дал мне, когда его спросили о механизме системного вызова Linux: http://www.linux.it/~rubini/docs/ksys/. Но, возможно, у вас есть лучший ресурс под рукой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...