Почему sudo развивается перед выполнением процесса?

1276
ssice

Этот вопрос может показаться немного глупым, но поскольку в системах на основе Unix замена образа исполняемого файла выполняется за один шаг, заменяя текущий запущенный процесс, в вызове функции execve(и производных), вопрос заключается в следующем:

Почему sudo fork()по умолчанию перед execveзапуском процесса замены?

Путем разветвления перед этим необходимо инициализировать дополнительные элементы ядра, и хотя fork в некоторых Unix довольно оптимизирован, все же есть некоторые неизбежные элементы, которые необходимо инициализировать. Если fork()это не произойдет по умолчанию, пространство PID будет увеличиваться медленнее.

Если вам интересно, это поведение по умолчанию можно проверить, введя команду, такую ​​как

sudo sleep 30 

текущий код [ 1 ] довольно сложен для понимания, так как с тех пор было добавлено много функций; но в версии, размещенной в Apple [ 2 ], совершенно ясно, что она делает.

#ifndef PROFILING if ((sudo_mode & MODE_BACKGROUND) && fork() > 0) exit(0); else EXEC(safe_cmnd, NewArgv); /* run the command */ #else /* Complicated code when profiling is enabled, but we don't care */ 

В настоящее время я использую версию sudo 1.8.11p2, и она запускает режим сна в любом случае, с -bпереключателем или без него, поэтому кажется, что текущий код стал более сложным.

Я ищу ответ, который также охватывает, почему это поведение по умолчанию, и какие преимущества оно может принести нам.

3

2 ответа на вопрос

2
BillThor

Причина разветвления описана в Process modelразделе справочной страницы. Соответствующий контент:

Этот дополнительный процесс позволяет, например, приостановить и возобновить выполнение команды. Без этого команда была бы в том, что POSIX называет «потерянной группой процессов», и не получала бы никаких сигналов управления заданиями. В особом случае, если плагин политики не определяет функцию закрытия и pty не требуется, sudo выполнит команду напрямую вместо вызова fork (2). Плагин политики sudoers будет определять функцию закрытия только тогда, когда включено ведение журнала ввода-вывода, требуется pty или включены параметры pam_session или pam_setcred. Обратите внимание, что pam_session и pam_setcred включены по умолчанию в системах, использующих PAM.

Почему он не может выбрать сигналы контроля работы? Если я наберу `bash` и в новой оболочке с разветвленной + execve'd я вызову` exec sleep 10`, я все еще могу Ctrl. + Z из моей родительской оболочки, так как процесс был заменен, но его родитель все еще то же самое, не так ли? Не произойдет ли сирот, если родитель (fork () == 0) завершится, прежде чем отозвать своих детей? ssice 9 лет назад 0
@ssice Я думаю, что речь идет не столько об обработке сигналов, сколько о других случаях: close function, pty, pam_session и pam_setcred. `sudo` становится осиротевшим в моей системе, и это может вызвать проблемы с передачей сигнала на некоторых платформах. BillThor 9 лет назад 0
2
grawity

The PID space on Linux can be raised to 222 with a simple sysctl; that's really not a problem...

Most Linux distributions nowadays use PAM, and sudo is usually compiled with PAM support as well. Among other things it calls pam_open_session() before running your program, therefore it must also call pam_close_session() from within the same process as well, since your program won't know it needs to do that (and likely wouldn't be allowed to do that).

Похожие вопросы