LD_LIBRARY_PATH в envp arg execve() удаляется, даже если вызывающая родительская программа setuid отбросила свою привилегированную

Предыстория: я понял, что родительская программа с setuid не может хранить LD_LIBRARY_PATH как часть env по соображениям безопасности, поэтому любой дочерний процесс также не "видит" LD_LIBRARY_PATH.

Контекст: Моя родительская программа (см. https://github.com/shadow-robot/ethercat_grant/blob/kinetic-devel/src/ethercat_grant.cpp) нуждается в setuid для изменения возможностей, таких как CAP_NET_RAW дочерней программы. Однако дочерняя программа (под моим контролем, например, этот https://github.com/shadow-robot/ros_ethercat/blob/kinetic-devel/ros_ethercat_loop/src/main.cpp) использует библиотеки libs, найденные с помощью RPATH, которые сами нуждаются в доступе к зависимым библиотекам, не находящимся под моим контролем и находящимся только через LD_LIBRARY_PATH (из-за недавно введенного RUNPATH в бионическом ubuntu https://github.com/shadow-robot/ethercat_grant/issues/4).

Поэтому мне нужен обходной путь для передачи LD_LIBRARY_PATH дочернему процессу. Я думал, что execve() должен помочь, и мой вопрос только об этом здесь.

Обходной путь: я putenv() LD_LIBRARY_PATH=/my/path/ в родительском приложении, отбрасываю привилегии и затем вызываю execve() с новым env. Я предполагаю, что это безопасно, поскольку LD_LIBRARY_PATH, повторно добавленный в env, используется только как обычный пользователь, а не как привилегированный. Смотрите код здесь https://github.com/ubi-agni/ethercat_grant/blob/env_append/src/ethercat_grant.cpp

Проблема: LD_LIBRARY_PATH снова сбрасывается в execve(). [EDIT] Похоже, что ведет себя правильно (если привилегированные отбрасываются перед вызовом execve), если cap_set_file ранее не использовался, поэтому проблема в том, что между возможностями и execve каким-то образом есть проблема [/EDIT]

Исследование: я нашел какой-то старый, все еще открытый отчет об этом нежелательном поведении http://austingroupbugs.net/view.php?id=922, но это не объясняется явно (в man ld.so или другом), что даже если setuid соответствует seteuid (то же самое для групп) после удаления привилегий execve() снова удалит LD_LIBRARY_PATH.

Вопрос: я хотел бы знать, что это поведение все еще предназначено, или если я пропустил некоторые возможности proc / thread, я должен также изменить это, чтобы дочерний процесс не наследовал родительское "безопасное" выполнение, и, следовательно, сохранил мой новый env без изменений? [EDIT] Это действительно, похоже, связано с возможностями, влияющими на процесс ребенка [/EDIT]

Благодарю.

1 ответ

Решение

Теперь, когда я обнаружил, что проблема связана с возможностями, а не с setuid, кажется, что это также желаемое поведение, как упомянуто в этом посте /questions/37997983/kazhetsya-chto-vozmozhnosti-linux-setcap-otklyuchayut-ldlibrarypath/37997993#37997993

Другие вопросы по тегам