Проблемы с командой chmod u+s

Проблемы с командой chmod u+s

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

Программа успешно выполняется, но от имени обычного пользователя, а не root.

Однако, как говорят в интернете, chmod u+sкоманда заставляет его запускаться от имени владельца (в моем случае - root).

Программа представляет собой простую system(argv[1])строку, которая выполнит все, что находится внутри аргумента командной строки.

Например - Вывод для whoamiвозвращает моего пользователя, а не root.

Попытка вывести список содержимого также /rootзаканчивается сообщением «Отказано в доступе».

Разрешения файла -

-rwsr-xr-x  1 root     root     16608 Aug 25 15:20 test

В этот момент я попытался настроить права доступа к файлу 4755(безуспешно).

Перемещение файла /rootтакже оказалось неудачным.

решение1

Вызов system() использует execl()системный вызов для создания нового процесса оболочки. Но системный вызов игнорирует эффективный идентификатор пользователя и возвращает ошибку EPERM (отказано в доступе).

Это потому, что оболочки Linux не наследуют бит seteuid. Почему? Ну, потому что есть реальные опасения по поводу запуска скрипта с эффективным идентификатором пользователя в качестве root. Для более подробной информации по теме см.здесь.

Можно запустить оболочку, которая действует на эффективный UID, передав параметр -p. Из shстраницы руководства:

-p приват Не пытайтесь сбросить эффективный uid, если он не совпадает с uid. Это не установлено по умолчанию, чтобы помочь избежать неправильного использования setuid root-программами через system(3) или popen(3).

Ограничение, конечно, не распространяется на системные вызовы. В качестве демонстрации эта программа на языке C пытается перечислить /root с помощью system(), а затем делает то же самое с помощью системных вызовов opendir()и readdir().

Если двоичный файл принадлежит пользователю root с установленным идентификатором пользователя, то запуск программы пользователем, не являющимся пользователем root, приведет к тому, что первый листинг /root завершится ошибкой, второй (с использованием display_dir()works.

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<dirent.h>
#include<errno.h>

int display_dir(const char *dirname)
{
    DIR *dp = opendir(dirname);
    struct dirent *sd=NULL;
    if (!dp) return(errno);
    while ((sd = readdir(dp)) != NULL)
    {
        printf("%s\n", sd->d_name);
    }
    closedir(dp);
    return 0;
}

int main()
{
    system("ls /root");
    printf("Display returned %d\n", display_dir("/root"));
}

Связанный контент