fork и execve для наследования возможностей непривилегированного родительского процесса - PullRequest
8 голосов
/ 27 мая 2011

В системе Linux непривилегированный пользователь запускает программу.Созданный процесс имеет возможности CAP_NET_RAW,CAP_NET_ADMIN с режимом effective,permitted,inheritable.Затем этот процесс создает дочерний процесс, вызывая fork и execv для вызова другой программы udhcpc , но дочерний процесс не наследует возможности CAP_NET_RAW,CAP_NET_ADMIN, как ожидалось.Несмотря на то, что перед настройкой возможностей я позвонил prctl(PR_SET_KEEPCAPS, 1).

Любое предложение о том, что делать для наследования возможностей непривилегированного родительского процесса при fork, за которым следует execve?

Ответы [ 4 ]

12 голосов
/ 30 мая 2011

На execve() проверяются наборы возможностей файла исполняемого файла (в данном случае udhcpc) и объединяются с наборами возможностей потока. В частности, набор Inheritable файла имеет AND -ед с набором Inheritable потока, определяющим новый набор Permitted, а бит Effective файла должен быть установлен для нового набора Effective быть скопированным из набора Permitted.

Это означает, что в вашем случае вы должны использовать setcap cap_net_raw,cap_net_admin=ei /path/to/udhcpc для получения желаемого эффекта (в дополнение к настройке возможностей в родительском процессе - prctl() не требуется).

2 голосов
/ 25 августа 2011

Согласно «Интерфейсу программирования Linux» Майкла Керриска (No Starch Press, 2010):

Начиная с ядра 2.6.24, можно прикреплять возможности к файлу. Различные другие функции были добавлены в ядра 2.6.25 и 2.6.26 в Для завершения реализации возможностей.

Инструменты sucap и execcap - это то, что вы должны искать. Однако они, насколько я помню, ограничены, а не предоставляют возможности. Посмотрите на:

http://www.linuxjournal.com/article/5737

и

http://lkml.indiana.edu/hypermail/linux/kernel/0503.1/2540.html

1 голос
/ 04 июня 2016

Извлечено из руководства, произошли некоторые изменения. В соответствии с этим fork не меняет возможностей. И теперь есть набор окружения, кажется, это то, что вы пытаетесь сделать.

   Ambient (since Linux 4.3):
          This is a set of capabilities that are preserved across an execve(2) of a program that is not privileged.  The ambient capability set obeys the invariant that no capability can ever
          be ambient if it is not both permitted and inheritable.

          The ambient capability set can be directly modified using
          prctl(2).  Ambient capabilities are automatically lowered if
          either of the corresponding permitted or inheritable
          capabilities is lowered.

          Executing a program that changes UID or GID due to the set-
          user-ID or set-group-ID bits or executing a program that has
          any file capabilities set will clear the ambient set.  Ambient
          capabilities are added to the permitted set and assigned to
          the effective set when execve(2) is called.

   A child created via fork(2) inherits copies of its parent's
   capability sets.  See below for a discussion of the treatment of
   capabilities during execve(2).

...

       P'(ambient) = (file is privileged) ? 0 : P(ambient)

       P'(permitted) = (P(inheritable) & F(inheritable)) |
                       (F(permitted) & cap_bset) | P'(ambient)

       P'(effective) = F(effective) ? P'(permitted) : P'(ambient)

       P'(inheritable) = P(inheritable)    [i.e., unchanged]

   where:

       P         denotes the value of a thread capability set before the
                 execve(2)

       P'        denotes the value of a thread capability set after the
                 execve(2)

       F         denotes a file capability set

       cap_bset  is the value of the capability bounding set (described
                 below).
0 голосов
/ 25 июня 2019

Полезно иметь программу-обертку, которая может выполнять любую программу с определенными возможностями, без необходимости устанавливать возможности для целевых программ . Такая оболочка особенно полезна для запуска программного обеспечения из каталога сборки (где setcap было бы громоздко) или для запуска интерпретаторов, таких как Python (там, где это было бы неуместно).

Как объяснено в других ответах, окружающие возможности решают эту проблему, но они доступны только начиная с ядра 4.3. Эту проблему можно обойти, если оболочка загружает целевую программу напрямую, а не с помощью exec. Под этим я подразумеваю открыть исполняемый файл, отобразить соответствующие разделы, настроить стек и т. Д. И перейти к его коду. Это довольно сложная задача, но, к счастью, программа wine-preloader из проекта Wine делает именно это (и некоторые другие вещи, которые не имеют отношения к этой цели).

Запустите что-то вроде этого от имени пользователя root для настройки оболочки:

cp /usr/bin/wine-preloader /path/to/wrapper
setcap cap_net_raw+ep /path/to/wrapper # set whatever capabilities you need

Теперь у нас есть копия wine-preloader, которая может запускать любую программу с такими возможностями:

/path/to/wrapper /path/to/executable arguments...

Это работает, но есть некоторые подводные камни:

  • Целевая программа должна быть путем к исполняемому файлу, она не может найти программы в PATH.
  • Не работает, если целевой программой является скрипт с интерпретатором (#!).
  • wine-preloader выводит сообщение о невозможности найти что-то (но программа по-прежнему работает нормально).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...