Пример #1
0
func switchRoot(rootfs, subdir string, rmUsr bool) error {
	if err := syscall.Unmount(config.OEM, 0); err != nil {
		log.Debugf("Not umounting OEM: %v", err)
	}

	if subdir != "" {
		fullRootfs := path.Join(rootfs, subdir)
		if _, err := os.Stat(fullRootfs); os.IsNotExist(err) {
			if err := os.MkdirAll(fullRootfs, 0755); err != nil {
				log.Errorf("Failed to create directory %s: %v", fullRootfs, err)
				return err
			}
		}

		log.Debugf("Bind mounting mount %s to %s", fullRootfs, rootfs)
		if err := syscall.Mount(fullRootfs, rootfs, "", syscall.MS_BIND, ""); err != nil {
			log.Errorf("Failed to bind mount subdir for %s: %v", fullRootfs, err)
			return err
		}
	}

	for _, i := range []string{"/dev", "/sys", "/proc", "/run"} {
		log.Debugf("Moving mount %s to %s", i, path.Join(rootfs, i))
		if err := os.MkdirAll(path.Join(rootfs, i), 0755); err != nil {
			return err
		}
		if err := syscall.Mount(i, path.Join(rootfs, i), "", syscall.MS_MOVE, ""); err != nil {
			return err
		}
	}

	if err := copyMoveRoot(rootfs, rmUsr); err != nil {
		return err
	}

	log.Debugf("chdir %s", rootfs)
	if err := syscall.Chdir(rootfs); err != nil {
		return err
	}

	log.Debugf("mount MS_MOVE %s", rootfs)
	if err := syscall.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil {
		return err
	}

	log.Debug("chroot .")
	if err := syscall.Chroot("."); err != nil {
		return err
	}

	log.Debug("chdir /")
	if err := syscall.Chdir("/"); err != nil {
		return err
	}

	log.Debugf("Successfully moved to new root at %s", path.Join(rootfs, subdir))
	os.Unsetenv("DOCKER_RAMDISK")

	return nil
}
Пример #2
0
// EnterChroot changes the current directory to the path specified,
// and then calls chroot(2) with the same path.  This must be called
// while the process has CAP_SYS_CHROOT.
func EnterChroot(path string) (err error) {
	if err = syscall.Chdir(path); err != nil {
		return
	}
	if err = syscall.Chroot(path); err != nil {
		return
	}
	if err = syscall.Chdir("/"); err != nil {
		return
	}
	return
}
Пример #3
0
func main() {
	cwd1 := make([]byte, BUF_SZ)

	fmt.Print("This is where I am now: ")
	if _, err := syscall.Getcwd(cwd1); err != nil {
		log.Fatal("Error: syscall.Getcwd(2): ", err)
	}
	fmt.Println(string(cwd1))

	fmt.Println("chroot(2)ing back to /home/christos")
	// Commented out doesn't work for some reason. TODO: Why not?
	//cwd_s := string(cwd[:])
	//if err := syscall.Chroot(cwd_s); err != nil {
	if err := syscall.Chroot("/home/christos"); err != nil {
		log.Fatal("Error: syscall.Chroot(2): ", err)
	}

	fmt.Print("This is where I am now: ")
	cwd2 := make([]byte, BUF_SZ)
	if _, err := syscall.Getcwd(cwd2); err != nil {
		log.Fatal("Error: syscall.Getcwd(2): ", err)
	}
	fmt.Println(string(cwd2))

	fmt.Println("chdir(2)ing to parent")
	if err := syscall.Chdir(".."); err != nil {
		log.Fatal("Error: syscall.Chdir(2): ", err)
	}

	fmt.Print("This is where I am now: ")
	cwd3 := make([]byte, BUF_SZ)
	if _, err := syscall.Getcwd(cwd3); err != nil {
		log.Fatal("Error: syscall.Getcwd(2): ", err)
	}
	fmt.Println(string(cwd3))

	fmt.Println("Again, chdir(2)ing to parent")
	if err := syscall.Chdir(".."); err != nil {
		log.Fatal("Error: syscall.Chdir(2): ", err)
	}

	fmt.Print("This is where I am now: ")
	cwd4 := make([]byte, BUF_SZ)
	if _, err := syscall.Getcwd(cwd4); err != nil {
		log.Fatal("Error: syscall.Getcwd(2): ", err)
	}
	fmt.Println(string(cwd4))

	return
}
Пример #4
0
func afterDaemonize(err error) {
	// Ignore SIGCHLD signal
	signal.Ignore(syscall.SIGCHLD)

	// Close STDOUT, STDIN, STDERR
	syscall.Close(0)
	syscall.Close(1)
	syscall.Close(2)

	// Become the process group leader
	syscall.Setsid()

	// // Clear umask
	syscall.Umask(022)

	// // chdir for root directory
	syscall.Chdir("/")

	// Notify that the child process started successfuly
	pipe := os.NewFile(uintptr(3), "pipe")
	if pipe != nil {
		defer pipe.Close()
		if err == nil {
			pipe.Write([]byte{DAEMONIZE_SUCCESS})
		} else {
			pipe.Write([]byte{DAEMONIZE_FAIL})
		}
	}
}
Пример #5
0
// InitializeMountNamespace sets up the devices, mount points, and filesystems for use inside a
// new mount namespace.
func InitializeMountNamespace(rootfs, console string, sysReadonly bool, mountConfig *MountConfig) error {
	var (
		err  error
		flag = syscall.MS_PRIVATE
	)
	if mountConfig.NoPivotRoot {
		flag = syscall.MS_SLAVE
	}
	if err := syscall.Mount("", "/", "", uintptr(flag|syscall.MS_REC), ""); err != nil {
		return fmt.Errorf("mounting / with flags %X %s", (flag | syscall.MS_REC), err)
	}
	if err := syscall.Mount(rootfs, rootfs, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
		return fmt.Errorf("mouting %s as bind %s", rootfs, err)
	}
	if err := mountSystem(rootfs, sysReadonly, mountConfig); err != nil {
		return fmt.Errorf("mount system %s", err)
	}
	if err := setupBindmounts(rootfs, mountConfig); err != nil {
		return fmt.Errorf("bind mounts %s", err)
	}
	if err := nodes.CreateDeviceNodes(rootfs, mountConfig.DeviceNodes); err != nil {
		return fmt.Errorf("create device nodes %s", err)
	}
	if err := SetupPtmx(rootfs, console, mountConfig.MountLabel); err != nil {
		return err
	}

	// stdin, stdout and stderr could be pointing to /dev/null from parent namespace.
	// Re-open them inside this namespace.
	if err := reOpenDevNull(rootfs); err != nil {
		return fmt.Errorf("Failed to reopen /dev/null %s", err)
	}

	if err := setupDevSymlinks(rootfs); err != nil {
		return fmt.Errorf("dev symlinks %s", err)
	}

	if err := syscall.Chdir(rootfs); err != nil {
		return fmt.Errorf("chdir into %s %s", rootfs, err)
	}

	if mountConfig.NoPivotRoot {
		err = MsMoveRoot(rootfs)
	} else {
		err = PivotRoot(rootfs)
	}
	if err != nil {
		return err
	}

	if mountConfig.ReadonlyFs {
		if err := SetReadonly(); err != nil {
			return fmt.Errorf("set readonly %s", err)
		}
	}

	syscall.Umask(0022)

	return nil
}
Пример #6
0
func main() {
	flag.Usage = usage
	flag.Parse()
	if flag.NArg() < 1 {
		usage()
	}
	args := flag.Args()

	ck(syscall.Chroot(args[0]))
	ck(syscall.Chdir("/"))

	var cmd *exec.Cmd
	if len(args) == 1 {
		shell := os.Getenv("SHELL")
		if shell == "" {
			shell = "/bin/sh"
		}
		cmd = exec.Command(shell, "-i")
	} else {
		cmd = exec.Command(args[1], args[2:]...)
	}
	cmd.Stdin = os.Stdin
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	ck(cmd.Run())
}
Пример #7
0
func pivotRoot(rootfs, pivotBaseDir string) error {
	if pivotBaseDir == "" {
		pivotBaseDir = "/"
	}
	tmpDir := filepath.Join(rootfs, pivotBaseDir)
	if err := os.MkdirAll(tmpDir, 0755); err != nil {
		return fmt.Errorf("can't create tmp dir %s, error %v", tmpDir, err)
	}
	pivotDir, err := ioutil.TempDir(tmpDir, ".pivot_root")
	if err != nil {
		return fmt.Errorf("can't create pivot_root dir %s, error %v", pivotDir, err)
	}
	if err := syscall.PivotRoot(rootfs, pivotDir); err != nil {
		return fmt.Errorf("pivot_root %s", err)
	}
	if err := syscall.Chdir("/"); err != nil {
		return fmt.Errorf("chdir / %s", err)
	}
	// path to pivot dir now changed, update
	pivotDir = filepath.Join(pivotBaseDir, filepath.Base(pivotDir))

	// Make pivotDir rprivate to make sure any of the unmounts don't
	// propagate to parent.
	if err := syscall.Mount("", pivotDir, "", syscall.MS_PRIVATE|syscall.MS_REC, ""); err != nil {
		return err
	}

	if err := syscall.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
		return fmt.Errorf("unmount pivot_root dir %s", err)
	}
	return os.Remove(pivotDir)
}
Пример #8
0
func pivotRoot(root string) error {
	// we need this to satisfy restriction:
	// "new_root and put_old must not be on the same filesystem as the current root"
	if err := syscall.Mount(root, root, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
		return fmt.Errorf("Mount rootfs to itself error: %v", err)
	}
	// create rootfs/.pivot_root as path for old_root
	pivotDir := filepath.Join(root, ".pivot_root")
	if err := os.Mkdir(pivotDir, 0777); err != nil {
		return err
	}
	logrus.Debugf("Pivot root dir: %s", pivotDir)
	logrus.Debugf("Pivot root to %s", root)
	// pivot_root to rootfs, now old_root is mounted in rootfs/.pivot_root
	// mounts from it still can be seen in `mount`
	if err := syscall.PivotRoot(root, pivotDir); err != nil {
		return fmt.Errorf("pivot_root %v", err)
	}
	// change working directory to /
	// it is recommendation from man-page
	if err := syscall.Chdir("/"); err != nil {
		return fmt.Errorf("chdir / %v", err)
	}
	// path to pivot root now changed, update
	pivotDir = filepath.Join("/", ".pivot_root")
	// umount rootfs/.pivot_root(which is now /.pivot_root) with all submounts
	// now we have only mounts that we mounted ourself in `mount`
	if err := syscall.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
		return fmt.Errorf("unmount pivot_root dir %v", err)
	}
	// remove temporary directory
	return os.Remove(pivotDir)
}
Пример #9
0
func pivotRoot(rootfs, pivotBaseDir string) error {
	if pivotBaseDir == "" {
		pivotBaseDir = "/"
	}
	tmpDir := filepath.Join(rootfs, pivotBaseDir)
	if err := os.MkdirAll(tmpDir, 0755); err != nil {
		return fmt.Errorf("can't create tmp dir %s, error %v", tmpDir, err)
	}
	pivotDir, err := ioutil.TempDir(tmpDir, ".pivot_root")
	if err != nil {
		return fmt.Errorf("can't create pivot_root dir %s, error %v", pivotDir, err)
	}
	if err := syscall.PivotRoot(rootfs, pivotDir); err != nil {
		return fmt.Errorf("pivot_root %s", err)
	}
	if err := syscall.Chdir("/"); err != nil {
		return fmt.Errorf("chdir / %s", err)
	}
	// path to pivot dir now changed, update
	pivotDir = filepath.Join(pivotBaseDir, filepath.Base(pivotDir))
	if err := syscall.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
		return fmt.Errorf("unmount pivot_root dir %s", err)
	}
	return os.Remove(pivotDir)
}
Пример #10
0
// Setup working directory
func setupWorkingDirectory(workdir string) {
	if workdir == "" {
		return
	}
	if err := syscall.Chdir(workdir); err != nil {
		log.Fatalf("Unable to change dir to %v: %v", workdir, err)
	}
}
Пример #11
0
// Setup working directory
func setupWorkingDirectory(args *DockerInitArgs) error {
	if args.workDir == "" {
		return nil
	}
	if err := syscall.Chdir(args.workDir); err != nil {
		return fmt.Errorf("Unable to change dir to %v: %v", args.workDir, err)
	}
	return nil
}
Пример #12
0
func realChroot(path string) error {
	if err := syscall.Chroot(path); err != nil {
		return fmt.Errorf("Error after fallback to chroot: %v", err)
	}
	if err := syscall.Chdir("/"); err != nil {
		return fmt.Errorf("Error changing to new root after chroot: %v", err)
	}
	return nil
}
Пример #13
0
// setupRootfs sets up the devices, mount points, and filesystems for use inside a
// new mount namespace.
func setupRootfs(config *configs.Config, console *linuxConsole) (err error) {
	if err := prepareRoot(config); err != nil {
		return newSystemError(err)
	}

	setupDev := len(config.Devices) == 0
	for _, m := range config.Mounts {
		for _, precmd := range m.PremountCmds {
			if err := mountCmd(precmd); err != nil {
				return newSystemError(err)
			}
		}
		if err := mountToRootfs(m, config.Rootfs, config.MountLabel); err != nil {
			return newSystemError(err)
		}

		for _, postcmd := range m.PostmountCmds {
			if err := mountCmd(postcmd); err != nil {
				return newSystemError(err)
			}
		}
	}
	if !setupDev {
		if err := createDevices(config); err != nil {
			return newSystemError(err)
		}
		if err := setupPtmx(config, console); err != nil {
			return newSystemError(err)
		}
		if err := setupDevSymlinks(config.Rootfs); err != nil {
			return newSystemError(err)
		}
	}
	if err := syscall.Chdir(config.Rootfs); err != nil {
		return newSystemError(err)
	}
	if config.NoPivotRoot {
		err = msMoveRoot(config.Rootfs)
	} else {
		err = pivotRoot(config.Rootfs, config.PivotDir)
	}
	if err != nil {
		return newSystemError(err)
	}
	if !setupDev {
		if err := reOpenDevNull(); err != nil {
			return newSystemError(err)
		}
	}
	if config.Readonlyfs {
		if err := setReadonly(); err != nil {
			return newSystemError(err)
		}
	}
	syscall.Umask(0022)
	return nil
}
Пример #14
0
func msMoveRoot(rootfs string) error {
	if err := syscall.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil {
		return err
	}
	if err := syscall.Chroot("."); err != nil {
		return err
	}
	return syscall.Chdir("/")
}
Пример #15
0
// Initialises a daemon with recommended values. Called by Daemonize.
//
// Currently, this only calls umask(0) and chdir("/").
func Init() error {
	syscall.Umask(0)

	err := syscall.Chdir("/")
	if err != nil {
		return err
	}

	// setrlimit RLIMIT_CORE
	return nil
}
Пример #16
0
func MsMoveRoot(rootfs string) error {
	if err := syscall.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil {
		return fmt.Errorf("mount move %s into / %s", rootfs, err)
	}

	if err := syscall.Chroot("."); err != nil {
		return fmt.Errorf("chroot . %s", err)
	}

	return syscall.Chdir("/")
}
Пример #17
0
func containerChroot(fsPath string) error {
	err := syscall.Mount(fsPath, "/", "", syscall.MS_MOVE, "")
	if err != nil {
		return err
	}
	err = syscall.Chroot(".")
	if err != nil {
		return err
	}
	return syscall.Chdir("/")
}
Пример #18
0
// setupRootfs sets up the devices, mount points, and filesystems for use inside a
// new mount namespace.
func setupRootfs(config *configs.Config, console *linuxConsole) (err error) {
	if err := prepareRoot(config); err != nil {
		return newSystemError(err)
	}
	for _, m := range config.Mounts {
		for _, precmd := range m.PremountCmds {
			if err := mountCmd(precmd); err != nil {
				return newSystemError(err)
			}
		}
		if err := mountToRootfs(m, config.Rootfs, config.MountLabel); err != nil {
			return newSystemError(err)
		}

		for _, postcmd := range m.PostmountCmds {
			if err := mountCmd(postcmd); err != nil {
				return newSystemError(err)
			}
		}
	}
	if err := createDevices(config); err != nil {
		return newSystemError(err)
	}
	if err := setupPtmx(config, console); err != nil {
		return newSystemError(err)
	}
	// stdin, stdout and stderr could be pointing to /dev/null from parent namespace.
	// re-open them inside this namespace.
	if err := reOpenDevNull(config.Rootfs); err != nil {
		return newSystemError(err)
	}
	if err := setupDevSymlinks(config.Rootfs); err != nil {
		return newSystemError(err)
	}
	if err := syscall.Chdir(config.Rootfs); err != nil {
		return newSystemError(err)
	}
	if config.NoPivotRoot {
		err = msMoveRoot(config.Rootfs)
	} else {
		err = pivotRoot(config.Rootfs, config.PivotDir)
	}
	if err != nil {
		return newSystemError(err)
	}
	if config.Readonlyfs {
		if err := setReadonly(); err != nil {
			return newSystemError(err)
		}
	}
	syscall.Umask(0022)
	return nil
}
Пример #19
0
// pivotRoot will call pivot_root such that rootfs becomes the new root
// filesystem, and everything else is cleaned up.
func pivotRoot(rootfs string) error {
	// While the documentation may claim otherwise, pivot_root(".", ".") is
	// actually valid. What this results in is / being the new root but
	// /proc/self/cwd being the old root. Since we can play around with the cwd
	// with pivot_root this allows us to pivot without creating directories in
	// the rootfs. Shout-outs to the LXC developers for giving us this idea.

	oldroot, err := syscall.Open("/", syscall.O_DIRECTORY|syscall.O_RDONLY, 0)
	if err != nil {
		return err
	}
	defer syscall.Close(oldroot)

	newroot, err := syscall.Open(rootfs, syscall.O_DIRECTORY|syscall.O_RDONLY, 0)
	if err != nil {
		return err
	}
	defer syscall.Close(newroot)

	// Change to the new root so that the pivot_root actually acts on it.
	if err := syscall.Fchdir(newroot); err != nil {
		return err
	}

	if err := syscall.PivotRoot(".", "."); err != nil {
		return fmt.Errorf("pivot_root %s", err)
	}

	// Currently our "." is oldroot (according to the current kernel code).
	// However, purely for safety, we will fchdir(oldroot) since there isn't
	// really any guarantee from the kernel what /proc/self/cwd will be after a
	// pivot_root(2).

	if err := syscall.Fchdir(oldroot); err != nil {
		return err
	}

	// Make oldroot rprivate to make sure our unmounts don't propagate to the
	// host (and thus bork the machine).
	if err := syscall.Mount("", ".", "", syscall.MS_PRIVATE|syscall.MS_REC, ""); err != nil {
		return err
	}
	// Preform the unmount. MNT_DETACH allows us to unmount /proc/self/cwd.
	if err := syscall.Unmount(".", syscall.MNT_DETACH); err != nil {
		return err
	}

	// Switch back to our shiny new root.
	if err := syscall.Chdir("/"); err != nil {
		return fmt.Errorf("chdir / %s", err)
	}
	return nil
}
Пример #20
0
// Because this function is executed by multicall in a different process, it is not possible to use errwrap to return errors
func extractTarCommand() error {
	if len(os.Args) != 5 {
		return fmt.Errorf("incorrect number of arguments. Usage: %s DIR {true|false} uidShift uidCount", multicallName)
	}
	if !sys.HasChrootCapability() {
		return fmt.Errorf("chroot capability not available.")
	}
	dir := os.Args[1]
	if !filepath.IsAbs(dir) {
		return fmt.Errorf("dir %s must be an absolute path", dir)
	}
	overwrite, err := strconv.ParseBool(os.Args[2])
	if err != nil {
		return fmt.Errorf("error parsing overwrite argument: %v", err)
	}

	us, err := strconv.ParseUint(os.Args[3], 10, 32)
	if err != nil {
		return fmt.Errorf("error parsing uidShift argument: %v", err)
	}
	uc, err := strconv.ParseUint(os.Args[4], 10, 32)
	if err != nil {
		return fmt.Errorf("error parsing uidCount argument: %v", err)
	}

	uidRange := &user.UidRange{Shift: uint32(us), Count: uint32(uc)}

	if err := syscall.Chroot(dir); err != nil {
		return fmt.Errorf("failed to chroot in %s: %v", dir, err)
	}
	if err := syscall.Chdir("/"); err != nil {
		return fmt.Errorf("failed to chdir: %v", err)
	}
	fileMapFile := os.NewFile(uintptr(fileMapFdNum), "fileMap")

	fileMap := map[string]struct{}{}
	if err := json.NewDecoder(fileMapFile).Decode(&fileMap); err != nil {
		return fmt.Errorf("error decoding fileMap: %v", err)
	}
	editor, err := NewUidShiftingFilePermEditor(uidRange)
	if err != nil {
		return fmt.Errorf("error determining current user: %v", err)
	}
	if err := ExtractTarInsecure(tar.NewReader(os.Stdin), "/", overwrite, fileMap, editor); err != nil {
		return fmt.Errorf("error extracting tar: %v", err)
	}

	// flush remaining bytes
	io.Copy(ioutil.Discard, os.Stdin)

	return nil
}
Пример #21
0
func switchRoot(rootfs string) error {
	for _, i := range []string{"/dev", "/sys", "/proc", "/run"} {
		log.Debugf("Moving mount %s to %s", i, path.Join(rootfs, i))
		if err := os.MkdirAll(path.Join(rootfs, i), 0755); err != nil {
			return err
		}
		if err := syscall.Mount(i, path.Join(rootfs, i), "", syscall.MS_MOVE, ""); err != nil {
			return err
		}
	}

	if err := copyMoveRoot(rootfs); err != nil {
		return err
	}

	if err := syscall.Chdir(rootfs); err != nil {
		return err
	}

	if err := syscall.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil {
		return err
	}

	if err := syscall.Chroot("."); err != nil {
		return err
	}

	if err := syscall.Chdir("/"); err != nil {
		return err
	}

	log.Debugf("Successfully moved to new root at %s", rootfs)
	os.Unsetenv("DOCKER_RAMDISK")

	return nil
}
Пример #22
0
/*   PivotRoot()
 */
func PivotRoot(rootfs string) error {
	pivotRoot := filepath.Join(rootfs, ".pivot_root")

	if e := BindMount("/dev", filepath.Join(rootfs, "dev")); e != nil {
		return fmt.Errorf("Failed to bind mount dev: %v", e)
	}

	if e := BindMount("/proc", filepath.Join(rootfs, "proc")); e != nil {
		return fmt.Errorf("Failed to bind mount dev: %v", e)
	}

	if e := BindMount("/sys", filepath.Join(rootfs, "sys")); e != nil {
		return fmt.Errorf("Failed to mount sysfs: %v", e)
	}

	if e := BindMount(rootfs, rootfs); e != nil {
		return fmt.Errorf("Failed to bind mount rootfs: %v", e)
	}

	if _, e := os.Stat(pivotRoot); os.IsNotExist(e) {
		if e := os.Mkdir(pivotRoot, 755); e != nil {
			return fmt.Errorf("Failed to make .pivot_root dir: %v", e)
		}
	}

	if e := syscall.PivotRoot(rootfs, pivotRoot); e != nil {
		return fmt.Errorf("Failed to pivot_root: %v", e)
	}

	if e := syscall.Chdir("/"); e != nil {
		return fmt.Errorf("Failed to cd to /: %v", e)
	}

	if e := syscall.Unmount("/.pivot_root", syscall.MNT_DETACH); e != nil {
		return fmt.Errorf("Failed to unmount pivot_root dir: %v", e)
	}

	if e := os.Remove("/.pivot_root"); e != nil {
		return fmt.Errorf("Failed to rmdir /.pivot_root: %v", e)
	}

	return nil
}
Пример #23
0
func (t *pty) fork(file string, args, env []string, cwd string, cols, rows, uid, gid int) error {
	var winp = new(C.struct_winsize)
	winp.ws_col = C.ushort(cols)
	winp.ws_row = C.ushort(rows)
	winp.ws_xpixel = 0
	winp.ws_ypixel = 0

	//fork the pty
	var master C.int = -1
	var name []C.char = make([]C.char, 40)
	var pid C.int = C.GoForkpty(&master, &name[0], winp)

	t.fd = int(master)
	t.pid = int(pid)
	t.pty = C.GoString(&name[0])

	switch t.pid {
	case -1:
		return errors.New("forkpty(3) failed")
	case 0:
		if cwd != "" {
			if err := syscall.Chdir(cwd); err != nil {
				panic("chdir failed")
			}
		}

		if uid != -1 && gid != -1 {
			if err := syscall.Setgid(gid); err != nil {
				panic("setgid failed")
			}

			if err := syscall.Setuid(uid); err != nil {
				panic("setuid failed")
			}
		}

		syscall.Exec(file, args, env)
		panic("exec failed")
	}

	return nil
}
Пример #24
0
// finalizeNamespace drops the caps, sets the correct user
// and working dir, and closes any leaked file descriptors
// before executing the command inside the namespace
func finalizeNamespace(config *initConfig) error {
	// Ensure that all unwanted fds we may have accidentally
	// inherited are marked close-on-exec so they stay out of the
	// container
	if err := utils.CloseExecFrom(config.PassedFilesCount + 3); err != nil {
		return err
	}

	capabilities := config.Config.Capabilities
	if config.Capabilities != nil {
		capabilities = config.Capabilities
	}
	w, err := newCapWhitelist(capabilities)
	if err != nil {
		return err
	}
	// drop capabilities in bounding set before changing user
	if err := w.dropBoundingSet(); err != nil {
		return err
	}
	// preserve existing capabilities while we change users
	if err := system.SetKeepCaps(); err != nil {
		return err
	}
	if err := setupUser(config); err != nil {
		return err
	}
	if err := system.ClearKeepCaps(); err != nil {
		return err
	}
	// drop all other capabilities
	if err := w.drop(); err != nil {
		return err
	}
	if config.Cwd != "" {
		if err := syscall.Chdir(config.Cwd); err != nil {
			return err
		}
	}
	return nil
}
Пример #25
0
// Drops privileges to the specified UID and GID.
// This function does nothing and returns no error if all E?[UG]IDs are nonzero.
//
// If chrootDir is not empty, the process is chrooted into it. The directory
// must exist. The function tests that privilege dropping has been successful
// by attempting to setuid(0), which must fail.
//
// The current directory is set to / inside the chroot.
//
// The function ensures that /etc/hosts and /etc/resolv.conf are loaded before
// chrooting, so name service should continue to be available.
func DropPrivileges(UID, GID int, chrootDir string) (chrootErr error, err error) {
	// chroot and set UID and GIDs
	chrootErr, err = dropPrivileges(UID, GID, chrootDir)
	if err != nil {
		err = fmt.Errorf("dropPrivileges failed: %v", err)
		return
	}

	err = syscall.Chdir("/")
	if err != nil {
		return
	}

	err = ensureNoPrivs()
	if err != nil {
		err = fmt.Errorf("ensure no privs failed: %v", err)
		return
	}

	return
}
Пример #26
0
// Drops privileges to the specified UID and GID.
// This function does nothing and returns no error if all E?[UG]IDs are nonzero.
//
// If chrootDir is not empty, the process is chrooted into it. The directory
// must exist. The function tests that privilege dropping has been successful
// by attempting to setuid(0), which must fail.
//
// The current directory is set to / inside the chroot.
//
// The function ensures that /etc/hosts and /etc/resolv.conf are loaded before
// chrooting, so name service should continue to be available.
func DropPrivileges(UID, GID int, chrootDir string) (chrootErr error, err error) {
	err = setRlimits()
	if err != nil {
		err = fmt.Errorf("failed to set rlimits: %v", err)
		return
	}

	err = platformPreDropPrivileges()
	if err != nil {
		err = fmt.Errorf("platformPreDropPrivileges failed: %v", err)
		return
	}

	// chroot and set UID and GIDs
	chrootErr, err = dropPrivileges(UID, GID, chrootDir)
	if err != nil {
		err = fmt.Errorf("dropPrivileges failed: %v", err)
		return
	}

	err = syscall.Chdir("/")
	if err != nil {
		return
	}

	err = ensureNoPrivs()
	if err != nil {
		err = fmt.Errorf("ensure no privs failed: %v", err)
		return
	}

	err = platformPostDropPrivileges()
	if err != nil {
		err = fmt.Errorf("platformPostDropPrivileges failed: %v", err)
		return
	}

	err = nil
	return
}
Пример #27
0
func PivotRoot(rootfs string) error {
	pivotDir, err := ioutil.TempDir(rootfs, ".pivot_root")
	if err != nil {
		return fmt.Errorf("can't create pivot_root dir %s, error %v", pivotDir, err)
	}

	if err := syscall.PivotRoot(rootfs, pivotDir); err != nil {
		return fmt.Errorf("pivot_root %s", err)
	}

	if err := syscall.Chdir("/"); err != nil {
		return fmt.Errorf("chdir / %s", err)
	}

	// path to pivot dir now changed, update
	pivotDir = filepath.Join("/", filepath.Base(pivotDir))
	if err := syscall.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
		return fmt.Errorf("unmount pivot_root dir %s", err)
	}

	return os.Remove(pivotDir)
}
Пример #28
0
func applyLayer() {
	runtime.LockOSThread()
	flag.Parse()

	if err := syscall.Chroot(flag.Arg(0)); err != nil {
		fatal(err)
	}
	if err := syscall.Chdir("/"); err != nil {
		fatal(err)
	}
	tmpDir, err := ioutil.TempDir("/", "temp-docker-extract")
	if err != nil {
		fatal(err)
	}
	os.Setenv("TMPDIR", tmpDir)
	if err := archive.ApplyLayer("/", os.Stdin); err != nil {
		os.RemoveAll(tmpDir)
		fatal(err)
	}
	os.RemoveAll(tmpDir)
	os.Exit(0)
}
Пример #29
0
// FinalizeNamespace drops the caps, sets the correct user
// and working dir, and closes any leaky file descriptors
// before execing the command inside the namespace
func FinalizeNamespace(container *libcontainer.Config) error {
	// Ensure that all non-standard fds we may have accidentally
	// inherited are marked close-on-exec so they stay out of the
	// container
	if err := utils.CloseExecFrom(3); err != nil {
		return fmt.Errorf("close open file descriptors %s", err)
	}

	// drop capabilities in bounding set before changing user
	if err := capabilities.DropBoundingSet(container.Capabilities); err != nil {
		return fmt.Errorf("drop bounding set %s", err)
	}

	// preserve existing capabilities while we change users
	if err := system.SetKeepCaps(); err != nil {
		return fmt.Errorf("set keep caps %s", err)
	}

	if err := SetupUser(container.User); err != nil {
		return fmt.Errorf("setup user %s", err)
	}

	if err := system.ClearKeepCaps(); err != nil {
		return fmt.Errorf("clear keep caps %s", err)
	}

	// drop all other capabilities
	if err := capabilities.DropCapabilities(container.Capabilities); err != nil {
		return fmt.Errorf("drop capabilities %s", err)
	}

	if container.WorkingDir != "" {
		if err := syscall.Chdir(container.WorkingDir); err != nil {
			return fmt.Errorf("chdir to %s %s", container.WorkingDir, err)
		}
	}

	return nil
}
Пример #30
0
Файл: main.go Проект: jdp/lineup
func daemonize(server *Server) {
	pid, err := os.ForkExec("lineupd", []string{}, []string{}, "/var/run", []*os.File{});
	if err != nil {
		server.Logger().Logf("couldn't fork: %s\n", err);
		os.Exit(1);
	}
	server.Logger().Logf("%d->%d\n", os.Getpid(), pid);
	if (pid < 0) {
		os.Exit(1);
	}
	if (pid > 0) {
		os.Exit(0);
	}
	syscall.Setsid();
	for i := 0; i < 3; i++ {
		syscall.Close(i);
	}
	for i := 0; i < 3; i++ {
		syscall.Open("/dev/null", os.O_RDWR, 0644);
	}
	syscall.Umask(027);
	syscall.Chdir("/var/run");
}