Назад | Перейти на главную страницу

Возможности Linux для чтения переменных среды?

Я бы хотел запустить службу от имени непривилегированного пользователя, но она должна быть привязана к номеру системного порта (т.е. меньше 1024), поэтому я даю ему setcap 'cap_net_bind_service=+ep' <path for service>, все хорошо.

Проблема в том, что при запуске служба читает переменные среды и по какой-то причине не может этого сделать, если у нее есть cap_net_bind_service. Итак, с двумя копиями исполняемого файла, одна с cap_net_bind_service, один без, только тот, кто без него, может читать переменные среды.

Как будто есть набор возможностей по умолчанию, который позволяет читать env vars, но exe теряет эту возможность, когда я его даю cap_net_bind_service. Это правильно, или происходит что-то еще? Какие дополнительные возможности мне нужно предоставить службе, чтобы она могла читать переменные env? Нет ничего в capacity.h что выскакивает как "разрешить чтение env var"?

Я дошел до сути. Вкратце, двоичный файл использует secure_getenv для доступа к переменным среды.

Это возвращает null, вместо доступа к переменным, когда двоичный файл выполняется в режиме «безопасного выполнения» (AT_SECURE=1). Имея любую установленную возможность, заставляет его работать в этом режиме.

Подтвердите, что двоичный файл использует secure_getenv с помощью readelf:

readelf -a <path for service> | grep getenv
00000040ac28  004b00000007 R_X86_64_JUMP_SLO 0000000000000000 secure_getenv@GLIBC_2.17 + 0
00000040ad90  007a00000007 R_X86_64_JUMP_SLO 0000000000000000 getenv@GLIBC_2.2.5 + 0
    75: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND secure_getenv@GLIBC_2.17 (6)
   122: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND getenv@GLIBC_2.2.5 (2)

Убедитесь, что он работает в безопасном режиме выполнения с переменными среды (как ни парадоксально!) LD_DEBUG=all и / или LD_SHOW_AUXV (видеть man ld.so).

Если это не так, то LD_SHOW_AUXV производит вывод с AT_SECURE установлено на 0. Нет вывода из LD_SHOW_AUXV когда он работает в безопасном режиме выполнения.

Обычно нет / нет вывода из LD_DEBUG тоже, когда он работает / не работает в безопасном режиме выполнения. Однако если /etc/suid-debug присутствует (пустой файл, создать касанием), то LD_DEBUG выдаст вывод при работе в безопасном режиме выполнения.

Видеть man getauxval для получения дополнительной информации о AT_SECURE и безопасный режим выполнения.