1

I try to make my code work under chroot('/root/test1'), but it doesn't work correctly.

But when I delete chroot('/root/test1'), and modify execl("/test2", "test2", NULL) to execl("/root/test1/test2", "test2", NULL), it will work very well as expected. Why is that?

In addition, I would like to ask that if I set fp redirect to stdin, and then use execl function to work another program, the child program will get input at fp whether or not?

The file in '/root/test1/':

test2
test2.cpp
test3
test3.cpp

The value return by execl funtion is -1 and errno is 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

output*

0
0
.  test3.cpp  test3  ..  test2  test2.cpp  log.txt
-1
2
No such file or directory
Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
Steve
  • 21
  • 5
  • What is in `test2`? Is it a executable? A shell script? Does it link with shared libraries? What is the output of `ldd test2` ? Does those shared libraries are copied to `/root/test1`? – KamilCuk Aug 21 '19 at 12:16
  • 4
    Have you checked what each of your system calls return? There's no failure anywhere? – Some programmer dude Aug 21 '19 at 12:16
  • 4
    Only the root user is allowed to `chroot`. Are you running as root? – molbdnilo Aug 21 '19 at 12:18
  • Also note that in Linux, `2` is the error `ENOENT` meaning that `execl` can't find the program. Use e.g. `strerror(errno)` to print a string with a short explanation of the error. – Some programmer dude Aug 21 '19 at 12:19
  • @Steve You need to check after every call. Some functions leave `errno` untouched on success, and some reset it to a non-error state. – Thomas Jager Aug 21 '19 at 13:10
  • For almost all functions, the state of `errno` is *undefined* after the call, unless there's an error. You need to check what the functions actually *return* to see if they fail or succeed. Only if a function failed you should check the value of `errno`, and you should get (and possibly store in a temporary variable) as soon as possible (before another function *might* change it). – Some programmer dude Aug 21 '19 at 13:14
  • What does `chroot` ***return***? You need to check that it succeeds. What happens if it fails? Right now, with the code you show, you don't check for that. You need to do something like `if (chroot(...) == -1) { perror("chroot"); return 1; }` – Some programmer dude Aug 21 '19 at 13:26
  • 2
    The error is likely due to missing libraries in the chrooted directory. – Ian Abbott Aug 21 '19 at 13:32
  • @Ian Abbott So how to solve it? – Steve Aug 21 '19 at 13:34
  • 1
    One way is to make test2 do the chroot itself (using argv arguments to tell it where to chroot to), at which point it should have already loaded its libraries. – Ian Abbott Aug 21 '19 at 13:44
  • Thanks. Lack of libraries is right. I try to copy /usr /lib /lib64 and /bin/bash to /root/test1, and it can works perfectly! @Ian Abbott – Steve Aug 21 '19 at 13:51

1 Answers1

1

Copy /usr /lib /lib64 and /bin/bash to /root/test1

Steve
  • 21
  • 5