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;

}

3
  • please post a minimal working example. changing the hostname in the child should only had effect in its namespace.
    – user313992
    Commented May 8, 2019 at 14:53
  • I have updated my question, does this make it clear? and yes that the problem.
    – o.awajan
    Commented May 8, 2019 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).
    – user313992
    Commented May 8, 2019 at 15:54

1 Answer 1

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.

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .