Почему мой код работает без функции chroot, но не работает с функцией chroot?

Я пытаюсь заставить свой код работать под chroot('/root/test1'), но он работает неправильно.

Но когда я удалю chroot('/root/test1') и изменю execl("/test2", "test2", NULL) на execl("/root/test1/test2", "test2", NULL), все будет работать очень хорошо, как и ожидалось. Почему это?

Кроме того, я хотел бы спросить, если я установлю перенаправление fp на stdin, а затем использую функцию execl для работы с другой программой, дочерняя программа получит ввод в fp или нет?

Файл в '/root/test1/':

test2
test2.cpp
test3
test3.cpp

Значение, возвращаемое функцией execl, равно -1, а errno равно 2.

test3.cpp

int main() {
    FILE *fp;
    errno = 0;
    fp = fopen("log.txt", "r");
    dup2(fileno(fp), fileno(stdin));
    cout << chdir("/root/test1") << endl;
    cout << chroot("/root/test1") << endl;

    DIR *dir = opendir("/");
    dirent *list;
    while ((list = readdir(dir)) != NULL) {
        cout << list -> d_name << "  ";
    }
    cout << endl;
    closedir(dir);
    errno = 0;
    cout << execl("/test2", "test2", NULL) << endl;
    cout << errno << endl;
    cout << strerror(errno) << endl;
    return 0;
}

test2.cpp

#include <cstdio>
#include <iostream>
using namespace std;
int main() {
    int a,b;
    cin >> a;
    scanf("%d",&b);
    cout << a+b << endl;
    printf("%d",a+b);
    return 0;
}

log.txt

111 222

вывод*

0
0
.  test3.cpp  test3  ..  test2  test2.cpp  log.txt
-1
2
No such file or directory

person Steve    schedule 21.08.2019    source источник
comment
Что находится в test2? Это исполняемый файл? Сценарий оболочки? Связывается ли он с общими библиотеками? Каков результат ldd test2 ? Копируются ли эти общие библиотеки в /root/test1?   -  person KamilCuk    schedule 21.08.2019
comment
Вы проверили, что возвращает каждый из ваших системных вызовов? Нигде нет провала?   -  person Some programmer dude    schedule 21.08.2019
comment
Только пользователь root может chroot. Вы работаете как root?   -  person molbdnilo    schedule 21.08.2019
comment
Также обратите внимание, что в Linux 2 — это ошибка ENOENT, означающая, что execl не может найти программу. Используйте, например. strerror(errno), чтобы напечатать строку с кратким объяснением ошибки.   -  person Some programmer dude    schedule 21.08.2019
comment
@Steve Вам нужно проверять после каждого звонка. Некоторые функции в случае успеха оставляют errno нетронутым, а некоторые сбрасывают его в нормальное состояние.   -  person Thomas Jager    schedule 21.08.2019
comment
Почти для всех функций состояние errno после вызова не определено, если нет ошибки. Вам нужно проверить, что на самом деле возвращают функции, чтобы увидеть, завершаются ли они неудачно или успешно. Только в случае сбоя функции вы должны проверить значение errno и получить (и, возможно, сохранить во временной переменной) как можно скорее (до того, как другая функция может изменить его).   -  person Some programmer dude    schedule 21.08.2019
comment
Что chroot возвращает? Вы должны проверить, что это удается. Что произойдет, если это не удастся? Прямо сейчас, с кодом, который вы показываете, вы не проверяете это. Вам нужно сделать что-то вроде if (chroot(...) == -1) { perror("chroot"); return 1; }   -  person Some programmer dude    schedule 21.08.2019
comment
Ошибка, вероятно, связана с отсутствием библиотек в chroot-каталоге.   -  person Ian Abbott    schedule 21.08.2019
comment
@Ian Abbott Так как это решить?   -  person Steve    schedule 21.08.2019
comment
Один из способов — заставить test2 выполнить chroot самостоятельно (используя аргументы argv, чтобы сообщить ему, куда нужно выполнить chroot), после чего он уже должен был загрузить свои библиотеки.   -  person Ian Abbott    schedule 21.08.2019
comment
Спасибо. Отсутствие библиотек — это правильно. Я пытаюсь скопировать /usr/lib/lib64 и /bin/bash в /root/test1, и это может работать отлично! @ Ян Эбботт   -  person Steve    schedule 21.08.2019


Ответы (1)


Скопируйте /usr/lib/lib64 и /bin/bash в /root/test1

person Steve    schedule 21.08.2019