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 }
// 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 }
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 }
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}) } } }
// 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 }
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()) }
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) }
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) }
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) }
// 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) } }
// 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 }
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 }
// 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 }
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("/") }
// 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 }
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("/") }
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("/") }
// 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 }
// 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 }
// 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 }
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 }
/* 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 }
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 }
// 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 }
// 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 }
// 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 }
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) }
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) }
// 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 }
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"); }