правильный способ запуска программ setuid в C - PullRequest
6 голосов
/ 15 февраля 2012

У меня есть процесс с разрешениями 4750. В моей системе Linux есть два пользователя.Пользователь root и пользователь appz.Процесс наследует разрешения диспетчера процессов, который запускается как пользователь "appz".

У меня есть две основные процедуры:

void do_root (void)
{
        int status;
        status = seteuid (euid);
        if (status < 0) { 
        exit (status);
        }    
}

/* undo root permissions */
void undo_root (void)
{
int status;
        status = seteuid (ruid);
        if (status < 0) { 
                exit (status);
        }
        status = setuid(ruid);
        if (status < 0) { 
                exit (status);
        }
}

Мой поток выглядит следующим образом:

int main() {
 undo_root();
 do some stuff;
 do_root();
 bind( port 80); //needs root perm
 undo_root();
 while(1) {

    accept commads()
    if ( commands needs root user access)
    {
       do_root();
       execute();
       undo_root();

    }

 }

Как видите, я хочу выполнить некоторые команды от имени пользователя root.Я пытаюсь временно удалить разрешения, и если задачам нужен root-доступ, я заключаю команду между вызовами do_root и undo_root.

Однако кажется, что моя программа не работает.

Какой канонический способ сделать это?

Ответы [ 3 ]

6 голосов
/ 15 февраля 2012

Старый способ заключается в том, чтобы в do_root и undo_root использовать setreuid () для замены ruid и euid:

setreuid(geteuid(), getuid());

Это вполне приемлемо, если программа достаточно мала, чтобы выполнить полный аудит безопасности.

Способ новой школы гораздо более сложный и включает в себя функцию fork () дочернего элемента, которая принимает директивы для выполнения действий от имени пользователя root, а затем выполняет setuid (getuid ()) для постоянного удаления root в родительском объекте. отвечает за проверку всех директив, которые он получает. Для достаточно большой программы это уменьшает количество кода, который должен быть проверен на безопасность, и позволяет пользователю управлять процессом с помощью управления заданиями или уничтожать его и т. Д.

5 голосов
/ 15 февраля 2012

Имеется статья Хао Чена, Дэвида Вагнера и Дрю Дина « Сетюид демистифицирован ». Он был представлен на USENIX 2002. Он описывает, как setuid() и переходы работают очень подробно (правильно по состоянию на 2002). Это стоит прочитать (несколько раз - я должен быть просрочен на год или два на перечитывание).

По сути, как отмечено в комментарии Petesh , когда процесс с EUID 0 выполняет setuid(nuid) с nuid != 0, возврат к привилегиям root (EUID 0) невозможен. И действительно, жизненно важно, чтобы это было так. В противном случае, когда вы войдете в систему, процесс root, в который вы войдете, не сможет ограничить вас вашими привилегиями - вы сможете вернуться к root. Сохраненный UID усложняет ситуацию, но я не верю, что это влияет на одностороннюю ловушку EUID 0, выполняющую setuid().

2 голосов
/ 15 февраля 2012

Страница man setuid сообщает следующее:

... программа set-user-ID-root, желающая временно отбросить привилегии root, принять личность пользователя без полномочий root, а затем восстановить корневые привилегии, впоследствии не может использовать setuid ()

Это означает, что вы не можете использовать setuid().Вы должны использовать seteuid() и, возможно, setreuid().Подробнее см. Пример программы Setuid .

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