首页 > 解决方案 > execve(2) 系统命令在执行前退出

问题描述

我正在尝试实现一个容器,为此我使用带有适当标志的 clone(2) 系统调用创建一个进程:

  if ((child_pid = clone(child_main, process_struct.Stack + process_struct.StackPtr,
   CLONE_NEWCGROUP
  |CLONE_NEWIPC
  |CLONE_NEWNET
  |CLONE_NEWNS
  |CLONE_NEWPID
  |CLONE_NEWUTS
  |SIGCHLD, &process_struct, checkpoint)) == -1){
     fprintf(stderr,"Failed...%m \n");
    exit(EXIT_FAILURE);

  }else{
    fprintf(stderr,"Done\n");
    waitpid(child_pid, NULL, 0);
  }

在 child_main() 中,我更改了进程命名空间的主机名,还设置了挂载命名空间,我在分区上安装了 Linux 文件系统层次结构,就像普通的 Linux 安装一样(我这样做是为了创建一个干净的文件系统映像文件和二进制文件),然后将传播类型设置为 MS_UNBINDABLE,然后使用 pivot_root(2) 更改进程的根目录。

const int child_main(struct process *process_struct, int *checkpoint){

  char c;
  fprintf(stderr,"=> IPC setup...");
  //double check the IPC
  close(checkpoint[1]);
  fprintf(stderr,"Done\n");

  if ( sethostname(process_struct->Hostname, 
strlen(process_struct->Hostname)) || mounting(process_struct)){
    return -1;
  }

  // startup the IPC pipes
  read(checkpoint[0], &c, 1);

  if(execve("/bin/bash", (char*)0, NULL) == -1 ){
    fprintf(stderr,"--> Launching process Failed %m\n");
    return -1;
  }
    return 0;

}

问题是我的系统通过了 execve(2) 并且没有启动 /bin/bash 并且程序没有错误地运行。当我在 execve(2) 之前添加 system(2) 语句时:system("ls");它列出了适当的文件系统和当前工作目录。此外,当我将 execve(2) 参数更改为: execve("/bin/ls", (char*)0, NULL)execve("/bin/pstree", (char*)0, NULL)任何其他参数时,它将返回以下错误:No such file or directory or A NULL argv[0] was passed through an exec system call,同样当我 strace 我的在 execve(2) 系统调用中给出的程序:NULL, 0, NULL) = 17992

该错误与文件系统映像无关,我已经执行了更多测试并且如下所示,我将系统的文件系统用于我的挂载命名空间,而不是我安装在分区上并且运行 /bin/bash 的文件系统仍然没有工作,我创建了一个简单的 C 程序并编译它,它运行良好,所以有一些错误阻止 bin/bash 被执行,为了进一步测试这些结果,我为我的挂载命名空间重用了我的文件系统我移动了相同的可执行文件系统的第一个"/"和第二个在同一路径下 我的主系统路径到可执行文件= /home/omar/docs/test.out 我安装的文件系统从分区路径到可执行文件= /home/omar/docs/test.out 因为我想检查在向每个可执行文件中添加语句时相同的路径是否会引起混淆,因此可以判断我的程序采用了哪个路径,并且它运行良好,没有任何问题并且按预期正确,所以问题只是那个系统基本命令将不起作用。

标签: clinuxnamespaces

解决方案


您需要将适当的argv数组传递给execve. 如果您只想传递当前环境,请使用execv而不是execve.

char *argv[] = {"bash", NULL};
if(execv("/bin/bash", argv) == -1 ){
    perror("execv");
    return -1;
}

推荐阅读