Форум программистов, компьютерный форум, киберфорум
C/С++ под Linux
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
9 / 7 / 1
Регистрация: 05.04.2012
Сообщений: 150

Execv в связке с chroot

10.10.2015, 18:10. Показов 2628. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
выполняю код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    chroot(task_code_path.c_str());
    setuid(1000);
    chdir("/");
                    
    char *_path = getcwd(NULL, 512);
    DIR *dir;
    struct dirent *ent;
    if ((dir = opendir(_path)) != NULL) {
        while ((ent = readdir (dir)) != NULL) {
            string t1(ent->d_name);
            if (t1 == prog_name)
                printf ("file: %s\n", ent->d_name);
        }
        closedir (dir);
    }
                    
    execv(prog_name.c_str(), (char **) &_argv[0]);
    perror("EXEC 2");
на выходе получаю:

C++
1
2
EXEC 2: No such file or directory
file: program.exe
то есть файл сто процентов есть, так как через чтение файловой структуры я его нахожу, но он отказывается выполняться.
Началось это после добавления chroot и setuid
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.10.2015, 18:10
Ответы с готовыми решениями:

Execv
Помогите пожалуйста разобраться почему в такой реализации execv не работает? char *nargv = {"dr1", "pr2",...

Реализация execvp и execlp через execl и execv
Есть задача: Написать эквиваленты execvp и execlp, используя вызовы execl и execv. Параметры этих процедур должны состоять из списка...

Centos 7 name-chroot.service
Добрый день! Возникла проблемка при создании bind (DNS)/ До этого создал ssh и настроил iptables при запуске команды ...

17
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
10.10.2015, 21:02
Цитата Сообщение от KFan Посмотреть сообщение
Началось это после добавления chroot и setuid
Так execv ищет файл в текущем каталоге (ему нужен абсолютный путь), а ты его поменял на другой.

Ну и запускаемый процесс надо форкать, а то он заменит текущий.
0
9 / 7 / 1
Регистрация: 05.04.2012
Сообщений: 150
10.10.2015, 21:39  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Так execv ищет файл в текущем каталоге (ему нужен абсолютный путь), а ты его поменял на другой.
Ну и запускаемый процесс надо форкать, а то он заменит текущий.
Это далеко не весь код, там есть и fork и pipe, и перехват ввода вывода, а файл запускаемый лежит в корне директории которую я указал в chroot, ну и собственно для подстраховки я еще делал
C++
1
chdir("/");
специально для этого

ну и в посте я все таки описал, что файл находится именно в том каталоге, в котором я сейчас нахожусь

C++
1
2
3
4
5
6
7
8
9
10
11
char *_path = getcwd(NULL, 512);
    DIR *dir;
    struct dirent *ent;
    if ((dir = opendir(_path)) != NULL) {
        while ((ent = readdir (dir)) != NULL) {
            string t1(ent->d_name);
            if (t1 == prog_name)
                printf ("file: %s\n", ent->d_name);
        }
        closedir (dir);
    }
и название файла выводится
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
10.10.2015, 21:40
Цитата Сообщение от KFan Посмотреть сообщение
и название файла выводится
Укажи абсолютный путь к файлу.
0
9 / 7 / 1
Регистрация: 05.04.2012
Сообщений: 150
10.10.2015, 21:48  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Укажи абсолютный путь к файлу.
Я указал абсолютный путь, эффект оказался точно таким же
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
10.10.2015, 21:51
Цитата Сообщение от KFan Посмотреть сообщение
Я указал абсолютный путь, эффект оказался точно таким же
Ладно, чтобы не гадать, сделай минимальный компилируемый пример, в котором воспроизводится твоя ошибка, и выложи сюда. Посмотрим.
0
9 / 7 / 1
Регистрация: 05.04.2012
Сообщений: 150
10.10.2015, 21:55  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Ладно, чтобы не гадать сделай минимальный компилируемый пример, в котором воспроизводится твоя ошибка и выложи сюда. Посмотрим.
Я попробую, но это будет очень сложно, так как там связь с бд плюс использование gcc|g++|mcs и веб морда как внешняя оболочка
0
9 / 7 / 1
Регистрация: 05.04.2012
Сообщений: 150
10.10.2015, 22:08  [ТС]
Compiler.rar

Возможно не получится развернуть "быстро", но я буду благодарен за помощь.

"малый пример" сделать не получится, вложил полностью, передаете программе параметр 97 и она сделает все остальное.

setuid нужно заменить на юзера с минимальными правами. и нужен установленный mono-devel
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
10.10.2015, 22:33
Цитата Сообщение от KFan Посмотреть сообщение
Я попробую, но это будет очень сложно
Ну вот я сам попробовал:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <string>
#include <unistd.h>
#include <cstdlib>
#include <cstdio>
#include <dirent.h>
 
using namespace std;
 
int main()
{
    std::string prog_name = "program.exe";
    std::string task_code_path = "your-path-to-executable";
    std::string exec_path = task_code_path + '/' + prog_name;
 
    char const * _argv[] = { prog_name.c_str(), 0 };
 
    pid_t child = fork();  
 
    if(child < 0)
    {
        return 1;
    }
    else if(child == 0)
    {
        chroot(task_code_path.c_str());
        setuid(1000);
 
        char const * _path = task_code_path.c_str();
        DIR *dir;
        struct dirent *ent;
        if ((dir = opendir(_path)) != NULL) {
            while ((ent = readdir (dir)) != NULL) {
                std::string t1(ent->d_name);
                if (t1 == prog_name)
                    printf ("file: %s\n", ent->d_name);
            }
            closedir (dir);
        }
 
        execv(exec_path.c_str(), (char **) &_argv[0]);
        perror("EXEC 2");
    }
    else
    {
        wait(child);
    }
    return 0;
}
Этот код у меня работает. Посмотри, может сразу видишь что у тебя по-другому.
0
9 / 7 / 1
Регистрация: 05.04.2012
Сообщений: 150
10.10.2015, 22:51  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Этот код у меня работает. Посмотри, может сразу видишь что у тебя по-другому.
Те отличия что я увидел ни к чему не привели, либо они совсем переставали видеть файл (даже через readdir и execv говорил что не находит), либо просто сам execv говорил что не находит файл но его видно через readdir. Может это быть связано с системой? у меня ubuntu 14

Ну и мне не совсем понятно почему вообще ваш код сработал, ведь chroot "переделывает" корень (по крайней мере по тому принципу который известен мне), таким образом путь который лежит в task_code_path ему уже не должен быть виден
1
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
10.10.2015, 23:31
Лучший ответ Сообщение было отмечено KFan как решение

Решение

Цитата Сообщение от KFan Посмотреть сообщение
почему вообще ваш код сработал
Да, ты прав. Я упустил это из виду.
В общем проблему твою я понял, сейчас посмотрю.
Большой пример разворачивать не буду, на малом все видно хорошо.

Добавлено через 30 минут
KFan, кажется понял.
В этом твоем каталоге, кроме программы, еще что-нибудь есть?
/lib каталог там должен быть, с соответствующим содержимым.
1
9 / 7 / 1
Регистрация: 05.04.2012
Сообщений: 150
10.10.2015, 23:34  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
KFan, кажется понял.
В этом твоем каталоге, кроме программы, еще что-нибудь есть?
/lib каталог там должен быть.
Нет, там только исходник и исполняемый файл, а как вы определили что именно нужно? или это на данный момент предположение? Сегодня я уже не могу этим заниматься, поздно, но завтра обязательно попробую.

Ну и плохо конечно что не выдает адекватной ошибки...
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
10.10.2015, 23:58
Лучший ответ Сообщение было отмечено KFan как решение

Решение

Цитата Сообщение от KFan Посмотреть сообщение
или это на данный момент предположение?
Скажем так, я уверен, что дело именно в этом.
Рассуждения такие: программа запускается не сама по себе, а в окружении, ей нужно найти зависимые библиотеки и т.д. В твоем случае получается, что ее этого окружения лишили.

Добавлено через 7 минут
KFan, в общем сделай ldd на бинарник, который запускаешь. Посмотри какие библиотеки от требует. Создай в своем каталоге каталог lib. Скопируй их туда. Все должно заработать

Добавлено через 5 минут
KFan, и еще, это к делу не относится, но меня подмывает озвучить:
C++
1
char *_path = getcwd(NULL, 512);
getcwd - при таком (нестандартном кстати) вызове выделяет память через malloc, а вот free я у тебя не обнаружил. Хоть процесс и отдаст все выделенное при завершении, все равно это выглядит не очень аккуратно.
1
9 / 7 / 1
Регистрация: 05.04.2012
Сообщений: 150
11.10.2015, 11:36  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
KFan, в общем сделай ldd на бинарник, который запускаешь. Посмотри какие библиотеки от требует. Создай в своем каталоге каталог lib. Скопируй их туда. Все должно заработать
Собственно ldd сказал что он не требует никаких библиотек, сделал симлинки на /lib и /usr и теперь получаю в ответ
Too many levels of symbolic links - пока что победить не удалось

Добавлено через 19 минут
кажется я понял проблему, симлинки тут не помогут..

Добавлено через 1 час 40 минут
На данный момент сделал так:

C++
1
2
3
4
5
6
7
    
    commands << "mount --bind /lib " << task_work_path << "/lib\n";
    commands << "mount --bind /usr " << task_work_path << "/usr\n";
    commands << "mount --bind /lib64 " << task_work_path << "/lib64\n";
    commands << "mount --bind /var " << task_work_path << "/var\n";
 
    system(commands.str().c_str());
Данным способом работает C, C++, но C# уже отваливается... В любом случае вы мне помогли, спасибо большое.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
11.10.2015, 14:32
Цитата Сообщение от KFan Посмотреть сообщение
симлинки тут не помогут
Да, потому они ссылаются на пути, которых в твоем chroot нет...

Цитата Сообщение от KFan Посмотреть сообщение
C# уже отваливается
Ни разу не пробовал C# под Linux. Но я подумаю, если будут идеи - напишу.

Добавлено через 45 минут
Цитата Сообщение от KFan Посмотреть сообщение
C# уже отваливается
Вопрос: а если делать без chroot - С# бинарники запускаются?
Скорее всего ему нужен интерпретатор байт-кода, который должен быть доступен и в новом окружении.
Может быть он лежит не в bin, а еще где-то?
Или может быть явно нужно указать, что запускать надо через него. Т.е.
Bash
1
# <interpreter> <your.exe> <args>
А еще я подумал, что настройка mono может содержаться где-то в домашнем каталоге, которого в твоем chroot тоже нет.
1
9 / 7 / 1
Регистрация: 05.04.2012
Сообщений: 150
11.10.2015, 15:53  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Вопрос: а если делать без chroot - С# бинарники запускаются?
Скорее всего ему нужен интерпретатор байт-кода, который должен быть доступен и в новом окружении.
Может быть он лежит не в bin, а еще где-то?
Или может быть явно нужно указать, что запускать надо через него. Т.е.
Ну да, без chroot проблем никаких не наблюдается, ну насчет интерпретатора, это да, я поищу его
0
9 / 7 / 1
Регистрация: 05.04.2012
Сообщений: 150
15.10.2015, 14:13  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Скорее всего ему нужен интерпретатор байт-кода, который должен быть доступен и в новом окружении.
Ерунда какая то, список директорий который я пробрасываю в chroot:

C++
1
2
3
4
5
6
7
8
9
10
11
    dirs.push_back("bin");
    dirs.push_back("etc");
    dirs.push_back("lib");
    dirs.push_back("lib64");
    dirs.push_back("proc");
    dirs.push_back("run");
    dirs.push_back("sbin");
    dirs.push_back("srv");
    dirs.push_back("sys");
    dirs.push_back("usr");
    dirs.push_back("var");
Все остальные директории из корня пусты, но он по прежнему пишет

C++
1
run-detectors: unable to find an interpreter for program.exe
Добавлено через 31 минуту
Проблема решена запусканием через интерпретатор, а не напрямую

C++
1
2
3
4
5
6
7
8
9
10
11
                    if (strlen(compile_item.lang.runner_path.c_str()) > 0) {
                        _argv.push_back(compile_item.lang.runner.c_str());
                        _argv.push_back(prog_name.c_str());
                        _argv.push_back(NULL);
                        
                        execv(compile_item.lang.runner_path.c_str(), (char **) &_argv[0]);
                    } else {
                        _argv.push_back(prog_name.c_str());
                        _argv.push_back(NULL);
                        execv(prog_name.c_str(), (char **) &_argv[0]);
                    }
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
15.10.2015, 14:26
Цитата Сообщение от KFan Посмотреть сообщение
Проблема решена запусканием через интерпретатор
Собственно я так и предполагал:
Цитата Сообщение от DrOffset Посмотреть сообщение
запускать надо через него
Цитата Сообщение от KFan Посмотреть сообщение
он по прежнему пишет
Я думаю, настройки автовызова интерпретатора все-таки хранятся где-то в домашнем каталоге пользователя.
Цитата Сообщение от DrOffset Посмотреть сообщение
А еще я подумал, что настройка mono может содержаться где-то в домашнем каталоге
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.10.2015, 14:26
Помогаю со студенческими работами здесь

Сделать chroot в /mnt
В общем решил установить арч на свой комп. Поделил диск на 3 раздела, один оставил винде, другой линуксу и третий для свопа. Далее примерно...

Запуск apache в chroot окружении
Есть сервер самосбор lfs версии 7.0 Из исходников установлен apache: httpd -version Server version: Apache/2.4.9 (Unix) Server...

Выполнить chroot в bash на Windows 10
Доброго времени суток. Как стало недавно известно, что в десятки появится bash ubunty, так вот проблема, как на ней зайти в chroot ...

[Gentoo] Сборка и установка Gentoo из chroot с другого дистрибутива
Всем привет! Есть желание сделать такой финт ушами: На данный момент у меня установлена и используется Ubuntu (в дуалбуте ещё есть...

Запереть ssh пользователя в chroot, разрешив доступ к руту
CentOS 6.4 Требуется запереть залогигившегося на сервер пользователя user в chroot в домашнем каталоге, при этом разрешить ему выполнять...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Уведомление о неверно выбранном значении справочника
Maks 06.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "НарядПутевка", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если в документе выбран неверный склад. . .
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru