我正在玩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
# /home/zaffy/cool/exec /home/zaffy/cool/prog
works!
# /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
之前使用execlp
,fopen
也会找到并打开该文件,但execlp
仍然会发出错误此类文件或目录。
你知道为什么会这样吗?为什么exec()在chroot()之后不起作用?
答案 0 :(得分:6)
您的问题很可能是您尝试执行的程序是动态链接的,并且chroot环境中的/lib
中不存在动态链接器。这会导致ENOENT
(No such file or directory
)错误。然而,仅仅添加它本身并没有帮助。您需要动态链接程序所依赖的所有其他文件,包括共享库和任何必要的配置/表/等。这些库需要的文件。