Возможности Linux для запуска процесса от имени root из программы пользовательского режима на C

#c #linux #linux-capabilities

Вопрос:

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

Что я пробовал до сих пор, так это установить ограничение на файл permitted для родительского процесса cap_setgid,cap_setuid,capkill p . Затем в том же родительском процессе я программно устанавливаю те же возможности для эффективной работы процесса перед вызовом fork exec из родительского процесса.

Для проверки на вменяемость я изменил разрешение chmod моего дочернего процесса на загрузку только как root chmod 4755 . Таким образом, он будет выполняться только как root и ничего больше.

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

Комментарии:

1. » Я пытаюсь запустить дочерний процесс как корневой из некорневого родительского процесса «-звучит как ожидающее нарушения безопасности.

2. @RemyLebeau необязательно, эти приложения устанавливаются и хранятся в привилегированных каталогах и не могут быть изменены без прав суперпользователя.

3. Я не могу воспроизвести это. Не могли бы вы, пожалуйста, дать инструкции по воспроизведению?

4. @thatotherguy что именно вы пытаетесь воспроизвести?

5. Ваша проблема в соответствии с вашим описанием

Ответ №1:

Попробуйте это ( parent.cc ):

 #include <iostream>
#include <sys/capability.h>
#include <unistd.h>

int main() {
    cap_t caps = cap_get_proc();
    cap_value_t val = CAP_SETUID;
    cap_set_flag(caps, CAP_EFFECTIVE, 1, amp;val, CAP_SET);
    if (cap_set_proc(caps)) {
        perror("failed to raise cap_setuid");
        exit(1);
    }
    if (setuid(0)) {
        perror("unable to setuid");
        exit(1);
    }
    execl("./child.sh", "child.sh", NULL);
    std::cout << "didn't work, uid=" << getuid();
    exit(1);
}
 

С этим ( child.sh ):

 #!/bin/bash
id -u
 

Создавайте и устанавливайте все:

 $ chmod  x child.sh
$ g   -o parent parent.cc -lcap
$ sudo setcap cap_setuid=p ./parent
 

Если вы запустите ./parent его, он должен работать так:

 $ ./parent 
0
 

Этот пример однопоточный. Если ваше приложение однопоточное, этого должно быть достаточно. Если ваша программа многопоточна, вам может потребоваться изучить что-то вроде libpsx.

Комментарии:

1. Потрясающе, это решило мою проблему. Я скучал setuid(0)