为什么exec()在chroot()之后不起作用?

时间:2014-06-21 14:52:50

标签: c++ c linux exec

我正在玩exec - 家庭功能,我看到了一个非常奇怪的行为:它们在chroot()系统调用后似乎无法工作。

以下是联机帮助页的相关报价:

  

execlp()和execvp()

的特殊语义      

execlp(),execvp()和execvpe()函数复制了它的动作      如果指定的文件名,shell搜索可执行文件      不包含斜杠(/)字符。该文件是在寻求      在PATH环境中指定的以冒号分隔的目录路径名列表      ronment变量。如果未定义此变量,则为路径列表      默认为当前目录,后跟目录列表      由confstr(_CS_PATH)返回。 (此confstr(3)调用通常会返回      值“/ bin:/ usr / bin”。)

     

如果指定的文件名包含斜杠字符,则PATH为        忽略,并执行指定路径名的文件。

这就是理论,现在让我们看看它的表现如何:

  • 我有prog.c文件将由execlp执行:

    #include <stdio.h>
    
    int main()
    {
        puts("works!");
        return 0;
    }
    
  • 我有exec.c个文件会尝试执行prog

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <errno.h>
    #include <dirent.h>
    
    int main(int argc, char* const argv[])
    {
        const char path[] = "/home/zaffy/cool";
    
        if (argc < 2)
            return 1;
    
        if (argc > 2 && (chdir(path) || chroot(path)))
        {
            printf("Cannot chroot(%s): %s\n", path, strerror(errno));
            return 1;
        }
    
        /* Clear our environment, including PATH */
        clearenv();
    
        if (execlp(argv[1], argv[1], NULL))
        {
            printf("Cannot execlp(%s): %s\n", argv[1], strerror(errno));
    
            /* Well, we failed... let's see
               contents of the current root */
            struct dirent* entry;
            DIR* dir = opendir("/");
            while ( (entry = readdir(dir)) )
                printf("%s\n", entry->d_name);
            closedir(dir);
        }
    
        return 0;
    }
    
  • 所有测试都在/home/zaffy/cool完成:

    /home/zaffy/cool
    ├── exec
    ├── exec.c
    ├── prog
    └── prog.c
    

测试一:exec没有调用chroot:

# /home/zaffy/cool/exec /home/zaffy/cool/prog
works!

测试二:exec调用chroot:

# /home/zaffy/cool/exec /prog 1
Cannot execlp(/prog): No such file or directory
.
..
prog.c
prog
exec.c
exec

我很困惑!根据man-pages,如果我已通过execlp的绝对路径,则不应在PATH中搜索,或者如果未设置PATH,则应将其设置为当前目录所以我无法在这里看到问题。

该文件肯定存在且可用!即使我在fopen之前使用execlpfopen也会找到并打开该文件,但execlp仍然会发出错误此类文件或目录。

你知道为什么会这样吗?为什么exec()在chroot()之后不起作用?

1 个答案:

答案 0 :(得分:6)

您的问题很可能是您尝试执行的程序是动态链接的,并且chroot环境中的/lib中不存在动态链接器。这会导致ENOENTNo such file or directory)错误。然而,仅仅添加它本身并没有帮助。您需要动态链接程序所依赖的所有其他文件,包括共享库和任何必要的配置/表/等。这些库需要的文件。