Если процесс, запущенный с двоичного разветвления setuid, и дочерний процесс отбрасывает привилегии, можно ли доверять дочернему процессу? - PullRequest
2 голосов
/ 10 января 2020

Допустим, следующая программа выполняется из двоичного файла setuid- root пользователем, не являющимся root:

int main()
{
    if (fork()) {
        /* Parent process */
        int wstatus; wait(&wstatus);
        if (WEXITSTATUS(wstatus) == 0) {
            /* Child process exited with return code indicating success */
            do_something_potentially_dangerous();
            return 0;
        } else {
            /* Child process exited with return code indicating failure */
            puts("Access denied");
            return 1;
        }
    } else {
        /* Child process */
        setuid(getuid());
        /*
        ...
        */
        return do_critical_security_check();  /* let's say this returns 0 if it's safe */
    }
}

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

Но когда дочерний процесс удаляет привилегии root, он также удаляет какую-либо из этих защит? Запретив уязвимость в коде дочернего процесса, сможет ли непривилегированный пользователь вмешаться в do_critical_security_check() или иным образом заставить дочерний процесс вернуть 0, если не должен? (Предположим, kernel.yama.ptrace_scope установлен на 0.)

1 Ответ

0 голосов
/ 10 января 2020

Страница man ptrace указывает, что это будет (мой акцент):

Запретить доступ, если не выполнено ни одно из :

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

  • вызывающая сторона имеет возможность CAP_SYS_PTRACE в пространстве имен пользователя цели.

Так что, если есть сохраненный UID, который не доступен для трассировщика, то процесс отслеживания не может присоединить и захватить дочерний элемент для доступа к нему.

Если дочерний элемент безвозвратно сбрасывает свой EUID (используя setresuid()), процесс отслеживания может присоединиться, но не существует сохраненного UID для злоупотребления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...