- 论坛徽章:
- 0
|
请教chroot()函数和execl()函数联合使用时的问题
想实现一个非常简单的功能: 在子进程中chroot到指定目录,然后通过execl()函数执行指定路径下的sh。
结果是:
chroot()成功执行,但是execl函数会报错,errno==2(Exec format errno)。
如下代码中设置了一个是否进行chroot的开关,发现如果不chroot,execl()函数可以正常执行指定路径下的sh,所以可以排除由execl()函数调用的函数无法运行的可能性。
程序如下:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
int
main(int argc, char *argv[])
{
char path_des[50];
char path_curr[50];
char path_exec[50];
char command[50];
/* 指定${RootPath)的路径*/
sprintf(path_des, "/opt/STM/STLinux-2.2/devkit/sh4/target" ;
printf("path_des: %s\n", path_des);
printf("uid=%d, gid=%d, pid=%d\n\n", getuid(), getgid(), getpid());
/*更改当前目录到指定路径下*/
if( chdir(path_des) ){
printf("change dir error\n" ;
return 1;
}
/*获取当前路径*/
getcwd( path_curr, sizeof(path_curr) );
printf("Before chroot: \n" ;
printf("current path: %s\n\n", path_curr);
pid_t pid;
if((pid = fork()) < 0){
printf("fork error\n" ;
return 1;
}else if(0 == pid){ /* child process */
printf("Get into the child process\n" ;
printf("uid=%d, gid=%d, pid=%d\n\n", getuid(), getgid(), getpid());
char chroot_flag ;
/*为了方便观察输出结果,选择是否进行chroot*/
printf("Decide whether to chroot n-->no, y-->yes)\n" ;
chroot_flag = getchar();
printf("chroot_flag: %c\n", chroot_flag);
if('y' == chroot_flag){
/*执行chroot*/
printf("Root will be changed \n" ;
if( chroot(path_des) ){
printf("chroot error\n" ;
printf("Chroot(errno): %d\n", errno);
return 1;
}
/*再次获取当前路径*/
getcwd( path_curr, sizeof(path_curr) );
printf("After chroot: \n" ;
printf("current path: %s\n\n", path_curr);
}else{
printf("Root is not changed \n\n" ;
}
if(-1 == setuid(0)){
printf("setuid error\n");
return 1;
}
if(-1 == setgid(0)){
printf("setgid error\n");
return 1;
}
/*利用execl()函数调用sh*/
if('n' == chroot_flag){
/*没有chroot情况下,利用原来的绝对路径*/
sprintf(path_exec, "/opt/STM/STLinux-2.2/devkit/sh4/target/bin/sh");
printf("path_exec: %s\n", path_exec);
}else{
/*chroot情况下,利用相对路径*/
sprintf(path_exec, "/bin/sh");
printf("path_exec: %s\n", path_exec);
}
sprintf(command, "sh");
printf("command: %s\n\n", command);
printf("Before execl(errno): %d\n", errno);
if(-1 == execl(path_exec, command, "-i", (char *)0)){
printf("Execl error\n");
printf("After execl(errno): %d\n", errno);
return 1;
}
}
if(pid != waitpid(pid, NULL, 0)){ /* 等待子进程结束 */
printf("waitpid error\n");
return 1;
}
return 1;
} |
|