1

I am trying to create a process with new namespaces, and for that i need to use clone(2) with the appropriate flags, the following is the clone system call and a printf() statement to print the parent PID:

printf("clone() = %ld\n", (long)getpid());
printf("PID: %ld\n", (long)getpid());
struct utsname utsname;
uname(&utsname);
printf("parent namespace hostname: %s\n", utsname.nodename);

clone(child_main(&process_struct, checkpoint), stack + process_struct.Stack,
  CLONE_NEWCGROUP
 |CLONE_NEWIPC
 |CLONE_NEWNET
 |CLONE_NEWNS
 |CLONE_NEWPID
 |CLONE_NEWUTS|SIGCHLD, &process_struct)

and the child_main() function, the child function will set the hostname and then will print the child's PID, the problem is that the hostname of the system changes not just the namespace's hostname, and the child's PID is the same of the parent, this wrong and the child PID from within the namespace should be 1 and its PPID is 0 (meaning no parent), also sethostname(2) must only affect the child process namespace

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

  char c;

  fprintf(stderr,"=> IPC setup...");
  //double check the IPC
  close(checkpoint[1]);
  fprintf(stderr,"Done\n");
  if ( sethostname(process->Hostname, strlen(process->Hostname)){

    //close(process->File_descriptor);
    return -1;
  }


  printf("PID: %ld\n", (long)getpid());
  struct utsname utsname;
  uname(&utsname);
  printf("child namespace hostname: %s\n", utsname.nodename);

  // startup the IPC pipes
  read(checkpoint[0], &c, 1);
  char* argv[]={(char*)0};
  if(execve("/bin/bash", argv, NULL) == -1 ){
    fprintf(stderr,"--> Launching process Failed %m\n");
    return -1;
  }

  return 0;

}

  • please post a minimal working example. changing the hostname in the child should only had effect in its namespace. – mosvy May 8 at 14:53
  • I have updated my question, does this make it clear? and yes that the problem. – o.awajan May 8 at 15:35
  • 1
    I don't see how that could ever work, since clone() takes a function pointer as the first argument, and you're passing it an int (the return from child_main). – mosvy May 8 at 15:54
2

The clone() glibc wrapper takes a function pointer as it first argument.

You're not passing it a function pointer, but an int (the return of child_main, which is called in the parent process, before calling clone). If child_main is passed a NULL pointer as the first argument (the 0 return from your child_main), it will return -1 and set errno to EINVAL, but I guess that you didn't check its return value.

From the clone() manpage:

EINVAL Returned by the glibc clone() wrapper function when fn or child_stack is specified as NULL.

So, child_main will run in the parent process, no child process or namespace is ever created, and child_main sets the hostname in the initial namespace, ie for your whole machine.

  • thanks alot, it seems I miss understood the parameters of clone(2). – o.awajan May 8 at 19:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.