LD_PRELOAD с бинарником setuid

Я пытаюсь использовать LD_PRELOAD для предварительной загрузки библиотеки с приложением, имеющим разрешения setuid. Сначала пробовал LD_PRELOAD, и казалось, что он игнорируется с помощью бинарного файла setuid, хотя он работал, когда я пробовал его с другими, такими как ls, dir и т.д.

Из документации LD_PRELOAD:

   LD_PRELOAD
          A whitespace-separated list of additional, user-specified, ELF shared
          libraries to be loaded before all others.  This can be used to
          selectively override functions in other shared libraries.  For set-
          user-ID/set-group-ID ELF binaries, only libraries in the standard
          search directories that are also set-user-ID will be loaded.

Я попытался поместить библиотеку в /usr/lib, /usr/local/lib и /usr/lib64 с разрешениями setuid в соответствии с этой документацией выше, но она по-прежнему не работает. Если я не даю LD_PRELOAD путь в случае, когда у меня есть библиотека в стандартном dirs с setuid, она не может найти библиотеку. Если я дам ему путь, он ничего не сделает.

Бинарный файл setuid - это двоичный файл с правами root, который запускается в оболочке пользователя без root. Есть предположения? Не уверен, что мне не хватает пути, переменной среды, или я неправильно понимаю документацию выше.

Изменить: разрешения по запросу:

Библиотека:

-rwsr-sr-x 1 root root 72580 2012-02-10 07:51

приложения:

-rwsr-xr-x 1 root root 137517601 2012-02-10 

env | grep LD
LD_LIBRARY_PATH=/usr/lib (I added this manually myself, usually LD_LIBRARY_PATH is empty)

Ответ 1

LD_PRELOAD не может использоваться с setuid. Это функция безопасности в Linux. Для справки проверьте эту статью, в которой подробно описывается, как использовать LD_PRELOAD для замены некоторых вызовов библиотеки с помощью специального кода, на примере malloc.

Ответ 2

Если вы используете SELinux, это может быть связано с этим. Одним из вспомогательных векторов ELF, поддерживающих glibc, является AT_SECURE. Этот конкретный параметр (который либо равен 0 по умолчанию, либо 1) указывает динамическому компоновщику ELF на отмену различных переменных среды, которые считаются потенциально опасными для вашей системы. Один из них - LD_PRELOAD. Обычно такая санитария среды выполняется, когда вызывается приложение setuid/setgid (чтобы предотвратить очевидные уязвимости). SELinux также улучшил эту санитарию до того, как приложение инициирует переход домена в SELinux (скажем sysadm_t - mozilla_t через двоичную метку moz или что-то еще); SELinux устанавливает флаг AT_SECURE для загруженного приложения (в примере, mozilla/firefox).

Разрешение noatsecure отключает деятельность по санитарии окружающей среды для конкретного перехода. Вы можете сделать это с помощью следующей инструкции allow (как это применимо в примере выше):

allow sysadm_t mozilla_t:process { noatsecure };

Ответ 3

В системе с glibc вы можете предварительно загрузить библиотеку другим поддерживаемым способом: добавив библиотеку в /etc/ld.so.preload. Этот не страдает от ограничений LD_PRELOAD.

В частности, таким образом я смог предварительно загрузить (бесполезно, просто чтобы продемонстрировать, что он работает) libgtk3-nocsd.so в /usr/bin/passwd, и, когда я запустил passwd ruslan, библиотека появилась в /proc/<PID_OF_PASSWD>/maps в то время как passwd был в ожидании текущего ввода пароля.

Одним из недостатков является то, что вы не можете сделать это для каждого приложения, как вы могли бы с LD_PRELOAD. Если вам это действительно нужно, возможно, вы могли бы изменить свою библиотеку, чтобы попытаться проверить, хочет ли она что-либо сделать, основываясь на том, какой путь к текущему двоичному файлу процесса (обнаружение этого, как описано здесь).

Ответ 4

Установите свой lib как таковой:

  • местоположение:/lib или /usr/lib
  • разрешений: root: root
  • имеет setuid и setgid на

Убедитесь, что LD_PRELOAD экспортируется в вашу среду.

$ export LD_PRELOAD=/usr/lib/yourlib.so
$ env | grep LD_PRELOAD  # verify

Затем запустите свою программу.