예제 #1
0
파일: exec.go 프로젝트: jcantrill/geard
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
}
예제 #2
0
파일: exec.go 프로젝트: jcantrill/geard
// 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
}