Есть ли способ выяснить, какие переменные среды нужны / используются исполняемым файлом?

У меня есть программа на C++, которая будет запускать некоторые очень специфические команды от имени пользователя root. Причина, по которой это необходимо, заключается в том, что другая программа, работающая под Node.js, должна выполнять такие действия, как установка системного времени, часового пояса и т. Д., Для выполнения которых требуются привилегии root. Я использую функцию execve в C++, чтобы сделать системный вызов с привилегиями root после использования команды setuid. Я специально выбрал команду execve, потому что хочу отгородиться от среды, чтобы не создавать уязвимости переменных среды.

 setuid(0);
 execve(acExeName, pArgsForExec2, pcEnv);

То, что я хочу сделать, это выяснить, в точности, pcEnv, который является списком переменных среды для программы, с которой она должна работать. Например, если я хочу запустить инструмент time-admin, как если бы я запускал его из консоли, как я могу выяснить, какие переменные среды ему нужны. Я знаю, что могу распечатать переменные окружения с помощью команды printenv, но это дает мне их все. Я совершенно уверен, что они мне не нужны, и я хочу иметь как можно меньшее подмножество.

Я знаю, что могу использовать их все, а затем медленно закомментировать каждый из них и посмотреть, будет ли он работать, но я бы действительно не хотел заходить так далеко.

Кто-нибудь получил умный способ выяснить, какие переменные среды используются программой? Я должен добавить, что я делаю это при установке Ubuntu 12.04 LTS.

Спасибо за любую помощь.

1 ответ

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

На самом деле это делают многие программы типа оболочки (или интерпретаторы сценариев).

В более общем смысле аргумент getenv(3) может быть вычислен. Таким образом, в теории вы не можете угадать его возможные значения. (Я могу ошибаться, но некоторые очень старые версии libc и из bash раньше играл в такие трюки; к сожалению, я забыл детали, но иногда использовалась переменная окружения с некоторым номером pid в названии).

И, как прокомментировали другие, вы можете использовать ltrace (или играть LD_PRELOAD трюки), или использовать gdb , чтобы узнать, как getenv называется...

И приложение может также использовать environ переменная (см. environment (7)...) или третий аргумент main....

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

Если у вас есть доступ к исходному коду программы, вы можете, если он скомпилирован GCC, использовать (только что выпущенную версию 1.0) плагин MELT. MELT является предметно-ориентированным языком для расширения GCC и может использоваться для изучения внутренних представлений Gimple, обрабатываемых GCC при компиляции вашей программы. В частности, с его новым findgimple режим вы можете найти в одной команде все вызовы getenv с постоянной строкой.

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