func execinAction(container *libcontainer.Container, cmd *libcontainer.Command, fds []uintptr) error { for _, fd := range fds { if fd > 0 { if err := JoinExistingNamespace(fd, ""); err != nil { for _, fd := range fds { syscall.Close(int(fd)) } return err } } syscall.Close(int(fd)) } if container.Namespaces.Contains(libcontainer.CLONE_NEWNS) && container.Namespaces.Contains(libcontainer.CLONE_NEWPID) { // important: // we need to fork and unshare so that re can remount proc and sys within // the namespace so the CLONE_NEWPID namespace will take effect // if we don't fork we would end up unmounting proc and sys for the entire // namespace child, err := fork() if err != nil { return fmt.Errorf("fork child %s", err) } if child == 0 { if err := unshare(CLONE_NEWNS); err != nil { writeError("unshare newns %s", err) } if err := remountProc(); err != nil { writeError("remount proc %s", err) } if err := remountSys(); err != nil { writeError("remount sys %s", err) } if err := capabilities.DropCapabilities(container); err != nil { writeError("drop caps %s", err) } if err := exec(cmd.Args[0], cmd.Args[0:], cmd.Env); err != nil { writeError("exec %s", err) } // unreachable } exit, err := utils.WaitOnPid(child) if err != nil { writeError("wait on child %s", err) } os.Exit(exit) } return nil }
// execAction runs inside the new namespaces and initializes the standard // setup func execAction(container *libcontainer.Container, rootfs string) error { if _, err := setsid(); err != nil { return fmt.Errorf("setsid %s", err) } if err := SetupNewMountNamespace(rootfs, container.ReadonlyFs); err != nil { return fmt.Errorf("setup mount namespace %s", err) } // the network namespace must be joined before chrooting the process if container.NetNsFd > 0 { if err := JoinExistingNamespace(container.NetNsFd, libcontainer.CLONE_NEWNET); err != nil { return fmt.Errorf("join existing net namespace %s", err) } } if err := chroot("."); err != nil { return fmt.Errorf("chroot . %s", err) } if err := chdir("/"); err != nil { return fmt.Errorf("chdir / %s", err) } if err := sethostname(container.ID); err != nil { return fmt.Errorf("sethostname %s", err) } if err := capabilities.DropCapabilities(container); err != nil { return fmt.Errorf("drop capabilities %s", err) } if err := setupUser(container); err != nil { return fmt.Errorf("setup user %s", err) } if container.WorkingDir != "" { if err := chdir(container.WorkingDir); err != nil { return fmt.Errorf("chdir to %s %s", container.WorkingDir, err) } } if err := exec(container.Command.Args[0], container.Command.Args[0:], container.Command.Env); err != nil { return err } // unreachable return nil }