func setupHostname(args *DockerInitArgs) error { hostname := getEnv(args, "HOSTNAME") if hostname == "" { return nil } return syscall.Sethostname([]byte(hostname)) }
func setupHostname(c *Config) error { hostname := c.Env["HOSTNAME"] if hostname == "" { return nil } return syscall.Sethostname([]byte(hostname)) }
// SetHostname sets both the kernel hostname and /etc/hostname to the specified string func (t *BaseOperations) SetHostname(hostname string, aliases ...string) error { defer trace.End(trace.Begin("setting hostname to " + hostname)) old, err := os.Hostname() if err != nil { log.Warnf("Unable to get current hostname - will not be able to revert on failure: %s", err) } err = syscall.Sethostname([]byte(hostname)) if err != nil { log.Errorf("Unable to set hostname: %s", err) return err } log.Debugf("Updated kernel hostname") // update /etc/hostname to match err = ioutil.WriteFile(hostnameFile, []byte(hostname), 0644) if err != nil { log.Errorf("Failed to update hostname in %s", hostnameFile) // revert the hostname if old != "" { log.Warnf("Reverting kernel hostname to %s", old) err2 := syscall.Sethostname([]byte(old)) if err2 != nil { log.Errorf("Unable to revert kernel hostname - kernel and hostname file are out of sync! Error: %s", err2) } } return err } // add entry to hosts for resolution without nameservers lo4 := net.IPv4(127, 0, 1, 1) for _, a := range append(aliases, hostname) { t.hosts.SetHost(a, lo4) } if err = t.hosts.Save(); err != nil { return err } return nil }
// configureHostname calls to set the hostname to the one provided via // configuration. func (r *runner) configureHostname() error { if r.config.Hostname == "" { return nil } r.log.Infof("Setting hostname: %s", r.config.Hostname) if err := syscall.Sethostname([]byte(r.config.Hostname)); err != nil { r.log.Errorf("- Failed to set hostname: %v", err) } return nil }
func setup(cfg Cfg) error { if err := mount(cfg); err != nil { return err } if err := pivotRoot(cfg.Rootfs); err != nil { return fmt.Errorf("Pivot root error: %v", err) } if err := syscall.Sethostname([]byte(cfg.Hostname)); err != nil { return fmt.Errorf("Sethostname: %v", err) } return nil }
/* setup() is tasked with running the setup code from within the namespace, * before the target executable is invoked. It is designed to only execute the * correct hooks for the features the namespace was created with. */ func setup() error { // Read in container environment variables. nsId, _ := syscall.Getenv("LXNS_ID") // Read in container configuration. config, e := GetConfig(os.NewFile(3, "-")) if e != nil { return fmt.Errorf("Failed to import configuration: %v", e) } // Create a key set to check flags against. nsCloneFlags := make(map[string]struct{}) for _, v := range config.Features { nsCloneFlags[v] = empty } // Do we have networking namespace? if _, ok := nsCloneFlags["net"]; ok { if e := SetupNetwork(config.NetworkAddr); e != nil { return e } } // Do we have mounting namespace? if _, ok := nsCloneFlags["ns"]; ok { // If we have PID namespace, then mount /proc if _, ok := nsCloneFlags["pid"]; ok { if e := syscall.Mount("proc", "/proc", "proc", syscall.MS_NOEXEC|syscall.MS_NOSUID|syscall.MS_NODEV, ""); e != nil { return fmt.Errorf("Failed to mount proc: %v", e) } } // Change our root filesystem using pivot_root syscall if len(config.RootFS) > 0 { PivotRoot(config.RootFS) } } // Do we have hostname namespace? if _, ok := nsCloneFlags["uts"]; ok { hostname := fmt.Sprintf("lxns-%s", nsId) if e := syscall.Sethostname([]byte(hostname)); e != nil { return e } } return nil }
func SetHostname(cc *rancherConfig.CloudConfig) (string, error) { name, _ := os.Hostname() if cc.Hostname != "" { name = cc.Hostname } if name != "" { //set hostname if err := syscall.Sethostname([]byte(name)); err != nil { log.WithFields(log.Fields{"err": err, "hostname": name}).Error("Error setting hostname") return "", err } } return name, nil }
func SetHostnameFromCloudConfig(cc *config.CloudConfig) error { var hostname string if cc.Hostname == "" { hostname = cc.DefaultHostname } else { hostname = cc.Hostname } if hostname == "" { return nil } // set hostname if err := syscall.Sethostname([]byte(hostname)); err != nil { return err } return nil }
func (st *initState) runInit() { st.log.Info("Starting oz-init for profile: %s", st.profile.Name) sigs := make(chan os.Signal) signal.Notify(sigs, syscall.SIGTERM, os.Interrupt) s, err := ipc.NewServer(st.sockaddr, messageFactory, st.log, handlePing, st.handleRunProgram, st.handleRunShell, ) if err != nil { st.log.Error("NewServer failed: %v", err) os.Exit(1) } if err := os.Chown(st.sockaddr, int(st.uid), int(st.gid)); err != nil { st.log.Warning("Failed to chown oz-init control socket: %v", err) } if err := st.setupFilesystem(nil); err != nil { st.log.Error("Failed to setup filesytem: %v", err) os.Exit(1) } if st.user != nil && st.user.HomeDir != "" { st.launchEnv = append(st.launchEnv, "HOME="+st.user.HomeDir) } if st.profile.Networking.Nettype != network.TYPE_HOST { err := network.NetSetup(st.network) if err != nil { st.log.Error("Unable to setup networking: %+v", err) os.Exit(1) } } network.NetPrint(st.log) if syscall.Sethostname([]byte(st.profile.Name)) != nil { st.log.Error("Failed to set hostname to (%s)", st.profile.Name) os.Exit(1) } if syscall.Setdomainname([]byte("local")) != nil { st.log.Error("Failed to set domainname") } st.log.Info("Hostname set to (%s.local)", st.profile.Name) if err := st.setupDbus(); err != nil { st.log.Error("Unable to setup dbus: %v", err) os.Exit(1) } oz.ReapChildProcs(st.log, st.handleChildExit) if st.profile.XServer.Enabled { st.xpraReady.Add(1) st.startXpraServer() } st.xpraReady.Wait() st.log.Info("XPRA started") if st.needsDbus() { if err := st.getDbusSession(); err != nil { st.log.Error("Unable to get dbus session information: %v", err) os.Exit(1) } } fsbx := path.Join("/tmp", "oz-sandbox") err = ioutil.WriteFile(fsbx, []byte(st.profile.Name), 0644) // Signal the daemon we are ready os.Stderr.WriteString("OK\n") go st.processSignals(sigs, s) st.ipcServer = s if err := s.Run(); err != nil { st.log.Warning("MsgServer.Run() return err: %v", err) } st.log.Info("oz-init exiting...") }
func (l *linuxStandardInit) Init() error { ringname, keepperms, newperms := l.getSessionRingParams() // do not inherit the parent's session keyring sessKeyId, err := keyctl.JoinSessionKeyring(ringname) if err != nil { return err } // make session keyring searcheable if err := keyctl.ModKeyringPerm(sessKeyId, keepperms, newperms); err != nil { return err } var console *linuxConsole if l.config.Console != "" { console = newConsoleFromPath(l.config.Console) if err := console.dupStdio(); err != nil { return err } } if console != nil { if err := system.Setctty(); err != nil { return err } } if err := setupNetwork(l.config); err != nil { return err } if err := setupRoute(l.config.Config); err != nil { return err } label.Init() // InitializeMountNamespace() can be executed only for a new mount namespace if l.config.Config.Namespaces.Contains(configs.NEWNS) { if err := setupRootfs(l.config.Config, console, l.pipe); err != nil { return err } } if hostname := l.config.Config.Hostname; hostname != "" { if err := syscall.Sethostname([]byte(hostname)); err != nil { return err } } if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil { return err } if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil { return err } for key, value := range l.config.Config.Sysctl { if err := writeSystemProperty(key, value); err != nil { return err } } for _, path := range l.config.Config.ReadonlyPaths { if err := remountReadonly(path); err != nil { return err } } for _, path := range l.config.Config.MaskPaths { if err := maskFile(path); err != nil { return err } } pdeath, err := system.GetParentDeathSignal() if err != nil { return err } if l.config.NoNewPrivileges { if err := system.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil { return err } } // Tell our parent that we're ready to Execv. This must be done before the // Seccomp rules have been applied, because we need to be able to read and // write to a socket. if err := syncParentReady(l.pipe); err != nil { return err } // Without NoNewPrivileges seccomp is a privileged operation, so we need to // do this before dropping capabilities; otherwise do it as late as possible // just before execve so as few syscalls take place after it as possible. if l.config.Config.Seccomp != nil && !l.config.NoNewPrivileges { if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil { return err } } if err := finalizeNamespace(l.config); err != nil { return err } // finalizeNamespace can change user/group which clears the parent death // signal, so we restore it here. if err := pdeath.Restore(); err != nil { return err } // compare the parent from the inital start of the init process and make sure that it did not change. // if the parent changes that means it died and we were reparened to something else so we should // just kill ourself and not cause problems for someone else. if syscall.Getppid() != l.parentPid { return syscall.Kill(syscall.Getpid(), syscall.SIGKILL) } if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges { if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil { return err } } return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ()) }
func (l *linuxStandardInit) Init() error { // do not inherit the parent's session keyring sessKeyId, err := keyctl.JoinSessionKeyring("") if err != nil { return err } // make session keyring searcheable // without user ns we need 'UID' search permissions // with user ns we need 'other' search permissions if err := keyctl.ModKeyringPerm(sessKeyId, 0xffffffff, 0x080008); err != nil { return err } // join any namespaces via a path to the namespace fd if provided if err := joinExistingNamespaces(l.config.Config.Namespaces); err != nil { return err } var console *linuxConsole if l.config.Console != "" { console = newConsoleFromPath(l.config.Console) if err := console.dupStdio(); err != nil { return err } } if _, err := syscall.Setsid(); err != nil { return err } if console != nil { if err := system.Setctty(); err != nil { return err } } if err := setupNetwork(l.config); err != nil { return err } if err := setupRoute(l.config.Config); err != nil { return err } if err := setupRlimits(l.config.Config); err != nil { return err } if err := setOomScoreAdj(l.config.Config.OomScoreAdj); err != nil { return err } label.Init() // InitializeMountNamespace() can be executed only for a new mount namespace if l.config.Config.Namespaces.Contains(configs.NEWNS) { if err := setupRootfs(l.config.Config, console); err != nil { return err } } if hostname := l.config.Config.Hostname; hostname != "" { if err := syscall.Sethostname([]byte(hostname)); err != nil { return err } } if err := apparmor.ApplyProfile(l.config.Config.AppArmorProfile); err != nil { return err } if err := label.SetProcessLabel(l.config.Config.ProcessLabel); err != nil { return err } for key, value := range l.config.Config.Sysctl { if err := writeSystemProperty(key, value); err != nil { return err } } for _, path := range l.config.Config.ReadonlyPaths { if err := remountReadonly(path); err != nil { return err } } for _, path := range l.config.Config.MaskPaths { if err := maskFile(path); err != nil { return err } } pdeath, err := system.GetParentDeathSignal() if err != nil { return err } if l.config.Config.NoNewPrivileges { if err := system.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil { return err } } // Tell our parent that we're ready to Execv. This must be done before the // Seccomp rules have been applied, because we need to be able to read and // write to a socket. if err := syncParentReady(l.pipe); err != nil { return err } if l.config.Config.Seccomp != nil { if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil { return err } } if err := finalizeNamespace(l.config); err != nil { return err } // finalizeNamespace can change user/group which clears the parent death // signal, so we restore it here. if err := pdeath.Restore(); err != nil { return err } // compare the parent from the inital start of the init process and make sure that it did not change. // if the parent changes that means it died and we were reparened to something else so we should // just kill ourself and not cause problems for someone else. if syscall.Getppid() != l.parentPid { return syscall.Kill(syscall.Getpid(), syscall.SIGKILL) } return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ()) }
func (l *linuxStandardInit) Init() error { // join any namespaces via a path to the namespace fd if provided if err := joinExistingNamespaces(l.config.Config.Namespaces); err != nil { return err } var console *linuxConsole if l.config.Console != "" { console = newConsoleFromPath(l.config.Console) if err := console.dupStdio(); err != nil { return err } } if _, err := syscall.Setsid(); err != nil { return err } if console != nil { if err := system.Setctty(); err != nil { return err } } if err := setupNetwork(l.config); err != nil { return err } if err := setupRoute(l.config.Config); err != nil { return err } if err := setupRlimits(l.config.Config); err != nil { return err } label.Init() // InitializeMountNamespace() can be executed only for a new mount namespace if l.config.Config.Namespaces.Contains(configs.NEWNS) { if err := setupRootfs(l.config.Config, console); err != nil { return err } } if hostname := l.config.Config.Hostname; hostname != "" { if err := syscall.Sethostname([]byte(hostname)); err != nil { return err } } if err := apparmor.ApplyProfile(l.config.Config.AppArmorProfile); err != nil { return err } if err := label.SetProcessLabel(l.config.Config.ProcessLabel); err != nil { return err } for _, path := range l.config.Config.ReadonlyPaths { if err := remountReadonly(path); err != nil { return err } } for _, path := range l.config.Config.MaskPaths { if err := maskFile(path); err != nil { return err } } pdeath, err := system.GetParentDeathSignal() if err != nil { return err } if err := finalizeNamespace(l.config); err != nil { return err } // finalizeNamespace can change user/group which clears the parent death // signal, so we restore it here. if err := pdeath.Restore(); err != nil { return err } // Signal self if parent is already dead. Does nothing if running in a new // PID namespace, as Getppid will always return 0. if syscall.Getppid() == 1 { return syscall.Kill(syscall.Getpid(), syscall.SIGKILL) } return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ()) }
func (l *linuxStandardInit) Init() error { // join any namespaces via a path to the namespace fd if provided if err := joinExistingNamespaces(l.config.Config.Namespaces); err != nil { return err } var console *linuxConsole if l.config.Console != "" { console = newConsoleFromPath(l.config.Console) if err := console.dupStdio(); err != nil { return err } } if _, err := syscall.Setsid(); err != nil { return err } if console != nil { if err := system.Setctty(); err != nil { return err } } if err := setupNetwork(l.config); err != nil { return err } if err := setupRoute(l.config.Config); err != nil { return err } if err := setupRlimits(l.config.Config); err != nil { return err } label.Init() // InitializeMountNamespace() can be executed only for a new mount namespace if l.config.Config.Namespaces.Contains(configs.NEWNS) { if err := setupRootfs(l.config.Config, console); err != nil { return err } } if hostname := l.config.Config.Hostname; hostname != "" { if err := syscall.Sethostname([]byte(hostname)); err != nil { return err } } if err := apparmor.ApplyProfile(l.config.Config.AppArmorProfile); err != nil { return err } if err := label.SetProcessLabel(l.config.Config.ProcessLabel); err != nil { return err } for key, value := range l.config.Config.Sysctl { if err := writeSystemProperty(key, value); err != nil { return err } } for _, path := range l.config.Config.ReadonlyPaths { if err := remountReadonly(path); err != nil { return err } } for _, path := range l.config.Config.MaskPaths { if err := maskFile(path); err != nil { return err } } pdeath, err := system.GetParentDeathSignal() if err != nil { return err } if l.config.Config.Seccomp != nil { if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil { return err } } if err := finalizeNamespace(l.config); err != nil { return err } // finalizeNamespace can change user/group which clears the parent death // signal, so we restore it here. if err := pdeath.Restore(); err != nil { return err } // compare the parent from the inital start of the init process and make sure that it did not change. // if the parent changes that means it died and we were reparened to something else so we should // just kill ourself and not cause problems for someone else. if syscall.Getppid() != l.parentPid { return syscall.Kill(syscall.Getpid(), syscall.SIGKILL) } return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ()) }
func (l *linuxStandardInit) Init() error { if !l.config.Config.NoNewKeyring { ringname, keepperms, newperms := l.getSessionRingParams() // do not inherit the parent's session keyring sessKeyId, err := keys.JoinSessionKeyring(ringname) if err != nil { return err } // make session keyring searcheable if err := keys.ModKeyringPerm(sessKeyId, keepperms, newperms); err != nil { return err } } if err := setupNetwork(l.config); err != nil { return err } if err := setupRoute(l.config.Config); err != nil { return err } label.Init() // prepareRootfs() can be executed only for a new mount namespace. if l.config.Config.Namespaces.Contains(configs.NEWNS) { if err := prepareRootfs(l.pipe, l.config.Config); err != nil { return err } } // Set up the console. This has to be done *before* we finalize the rootfs, // but *after* we've given the user the chance to set up all of the mounts // they wanted. if l.config.CreateConsole { if err := setupConsole(l.pipe, l.config, true); err != nil { return err } if err := system.Setctty(); err != nil { return err } } // Finish the rootfs setup. if l.config.Config.Namespaces.Contains(configs.NEWNS) { if err := finalizeRootfs(l.config.Config); err != nil { return err } } if hostname := l.config.Config.Hostname; hostname != "" { if err := syscall.Sethostname([]byte(hostname)); err != nil { return err } } if err := apparmor.ApplyProfile(l.config.AppArmorProfile); err != nil { return err } if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil { return err } for key, value := range l.config.Config.Sysctl { if err := writeSystemProperty(key, value); err != nil { return err } } for _, path := range l.config.Config.ReadonlyPaths { if err := remountReadonly(path); err != nil { return err } } for _, path := range l.config.Config.MaskPaths { if err := maskPath(path); err != nil { return err } } pdeath, err := system.GetParentDeathSignal() if err != nil { return err } if l.config.NoNewPrivileges { if err := system.Prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); err != nil { return err } } // Tell our parent that we're ready to Execv. This must be done before the // Seccomp rules have been applied, because we need to be able to read and // write to a socket. if err := syncParentReady(l.pipe); err != nil { return err } // Without NoNewPrivileges seccomp is a privileged operation, so we need to // do this before dropping capabilities; otherwise do it as late as possible // just before execve so as few syscalls take place after it as possible. if l.config.Config.Seccomp != nil && !l.config.NoNewPrivileges { if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil { return err } } if err := finalizeNamespace(l.config); err != nil { return err } // finalizeNamespace can change user/group which clears the parent death // signal, so we restore it here. if err := pdeath.Restore(); err != nil { return err } // compare the parent from the initial start of the init process and make sure that it did not change. // if the parent changes that means it died and we were reparented to something else so we should // just kill ourself and not cause problems for someone else. if syscall.Getppid() != l.parentPid { return syscall.Kill(syscall.Getpid(), syscall.SIGKILL) } // check for the arg before waiting to make sure it exists and it is returned // as a create time error. name, err := exec.LookPath(l.config.Args[0]) if err != nil { return err } // close the pipe to signal that we have completed our init. l.pipe.Close() // wait for the fifo to be opened on the other side before // exec'ing the users process. fd, err := syscall.Openat(l.stateDirFD, execFifoFilename, os.O_WRONLY|syscall.O_CLOEXEC, 0) if err != nil { return newSystemErrorWithCause(err, "openat exec fifo") } if _, err := syscall.Write(fd, []byte("0")); err != nil { return newSystemErrorWithCause(err, "write 0 exec fifo") } if l.config.Config.Seccomp != nil && l.config.NoNewPrivileges { if err := seccomp.InitSeccomp(l.config.Config.Seccomp); err != nil { return newSystemErrorWithCause(err, "init seccomp") } } if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil { return newSystemErrorWithCause(err, "exec user process") } return nil }
// TODO(vishh): This is part of the libcontainer API and it does much more than just namespaces related work. // Move this to libcontainer package. // Init is the init process that first runs inside a new namespace to setup mounts, users, networking, // and other options required for the new container. // The caller of Init function has to ensure that the go runtime is locked to an OS thread // (using runtime.LockOSThread) else system calls like setns called within Init may not work as intended. func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, syncPipe *syncpipe.SyncPipe, args []string) (err error) { defer func() { if err != nil { syncPipe.ReportChildError(err) } }() rootfs, err := utils.ResolveRootfs(uncleanRootfs) if err != nil { return err } // clear the current processes env and replace it with the environment // defined on the container if err := LoadContainerEnvironment(container); err != nil { return err } // We always read this as it is a way to sync with the parent as well var networkState *network.NetworkState if err := syncPipe.ReadFromParent(&networkState); err != nil { return err } if consolePath != "" { if err := console.OpenAndDup(consolePath); err != nil { return err } } if _, err := syscall.Setsid(); err != nil { return fmt.Errorf("setsid %s", err) } if consolePath != "" { if err := system.Setctty(); err != nil { return fmt.Errorf("setctty %s", err) } } if err := ipc.Initialize(container.IpcNsPath); err != nil { return fmt.Errorf("setup IPC %s", err) } if err := setupNetwork(container, networkState); err != nil { return fmt.Errorf("setup networking %s", err) } if err := setupRoute(container); err != nil { return fmt.Errorf("setup route %s", err) } label.Init() if err := mount.InitializeMountNamespace(rootfs, consolePath, container.RestrictSys, (*mount.MountConfig)(container.MountConfig)); err != nil { return fmt.Errorf("setup mount namespace %s", err) } if container.Hostname != "" { if err := syscall.Sethostname([]byte(container.Hostname)); err != nil { return fmt.Errorf("sethostname %s", err) } } if err := apparmor.ApplyProfile(container.AppArmorProfile); err != nil { return fmt.Errorf("set apparmor profile %s: %s", container.AppArmorProfile, err) } if err := label.SetProcessLabel(container.ProcessLabel); err != nil { return fmt.Errorf("set process label %s", err) } // TODO: (crosbymichael) make this configurable at the Config level if container.RestrictSys { if err := restrict.Restrict("proc/sys", "proc/sysrq-trigger", "proc/irq", "proc/bus"); err != nil { return err } } pdeathSignal, err := system.GetParentDeathSignal() if err != nil { return fmt.Errorf("get parent death signal %s", err) } if err := FinalizeNamespace(container); err != nil { return fmt.Errorf("finalize namespace %s", err) } // FinalizeNamespace can change user/group which clears the parent death // signal, so we restore it here. if err := RestoreParentDeathSignal(pdeathSignal); err != nil { return fmt.Errorf("restore parent death signal %s", err) } return system.Execv(args[0], args[0:], os.Environ()) }
func initUserNs(container *libcontainer.Config, uncleanRootfs, consolePath string, pipe *os.File, args []string) (err error) { // clear the current processes env and replace it with the environment // defined on the container if err := LoadContainerEnvironment(container); err != nil { return err } // We always read this as it is a way to sync with the parent as well var networkState *network.NetworkState if err := json.NewDecoder(pipe).Decode(&networkState); err != nil { return err } // join any namespaces via a path to the namespace fd if provided if err := joinExistingNamespaces(container.Namespaces); err != nil { return err } if consolePath != "" { if err := console.OpenAndDup("/dev/console"); err != nil { return err } } if _, err := syscall.Setsid(); err != nil { return fmt.Errorf("setsid %s", err) } if consolePath != "" { if err := system.Setctty(); err != nil { return fmt.Errorf("setctty %s", err) } } if container.WorkingDir == "" { container.WorkingDir = "/" } if err := setupRlimits(container); err != nil { return fmt.Errorf("setup rlimits %s", err) } cloneFlags := GetNamespaceFlags(container.Namespaces) if container.Hostname != "" { if (cloneFlags & syscall.CLONE_NEWUTS) == 0 { return fmt.Errorf("unable to set the hostname without UTS namespace") } if err := syscall.Sethostname([]byte(container.Hostname)); err != nil { return fmt.Errorf("unable to sethostname %q: %s", container.Hostname, err) } } if err := apparmor.ApplyProfile(container.AppArmorProfile); err != nil { return fmt.Errorf("set apparmor profile %s: %s", container.AppArmorProfile, err) } if err := label.SetProcessLabel(container.ProcessLabel); err != nil { return fmt.Errorf("set process label %s", err) } if container.RestrictSys { if (cloneFlags & syscall.CLONE_NEWNS) == 0 { return fmt.Errorf("unable to restrict access to kernel files without mount namespace") } if err := restrict.Restrict("proc/sys", "proc/sysrq-trigger", "proc/irq", "proc/bus"); err != nil { return err } } pdeathSignal, err := system.GetParentDeathSignal() if err != nil { return fmt.Errorf("get parent death signal %s", err) } if err := FinalizeNamespace(container); err != nil { return fmt.Errorf("finalize namespace %s", err) } // FinalizeNamespace can change user/group which clears the parent death // signal, so we restore it here. if err := RestoreParentDeathSignal(pdeathSignal); err != nil { return fmt.Errorf("restore parent death signal %s", err) } return system.Execv(args[0], args[0:], os.Environ()) }
func (s syscallImpl) Sethostname(hostname []byte) error { return syscall.Sethostname(hostname) }
func initDefault(container *libcontainer.Config, uncleanRootfs, consolePath string, pipe *os.File, args []string) (err error) { rootfs, err := utils.ResolveRootfs(uncleanRootfs) if err != nil { return err } // clear the current processes env and replace it with the environment // defined on the container if err := LoadContainerEnvironment(container); err != nil { return err } // We always read this as it is a way to sync with the parent as well var networkState *network.NetworkState if err := json.NewDecoder(pipe).Decode(&networkState); err != nil { return err } // join any namespaces via a path to the namespace fd if provided if err := joinExistingNamespaces(container.Namespaces); err != nil { return err } if consolePath != "" { if err := console.OpenAndDup(consolePath); err != nil { return err } } if _, err := syscall.Setsid(); err != nil { return fmt.Errorf("setsid %s", err) } if consolePath != "" { if err := system.Setctty(); err != nil { return fmt.Errorf("setctty %s", err) } } cloneFlags := GetNamespaceFlags(container.Namespaces) if (cloneFlags & syscall.CLONE_NEWNET) == 0 { if len(container.Networks) != 0 || len(container.Routes) != 0 { return fmt.Errorf("unable to apply network parameters without network namespace") } } else { if err := setupNetwork(container, networkState); err != nil { return fmt.Errorf("setup networking %s", err) } if err := setupRoute(container); err != nil { return fmt.Errorf("setup route %s", err) } } if err := setupRlimits(container); err != nil { return fmt.Errorf("setup rlimits %s", err) } label.Init() // InitializeMountNamespace() can be executed only for a new mount namespace if (cloneFlags & syscall.CLONE_NEWNS) == 0 { if container.MountConfig != nil { return fmt.Errorf("mount config is set without mount namespace") } } else if err := mount.InitializeMountNamespace(rootfs, consolePath, container.RestrictSys, 0, // Default Root Uid 0, // Default Root Gid (*mount.MountConfig)(container.MountConfig)); err != nil { return fmt.Errorf("setup mount namespace %s", err) } if container.Hostname != "" { if (cloneFlags & syscall.CLONE_NEWUTS) == 0 { return fmt.Errorf("unable to set the hostname without UTS namespace") } if err := syscall.Sethostname([]byte(container.Hostname)); err != nil { return fmt.Errorf("unable to sethostname %q: %s", container.Hostname, err) } } if err := apparmor.ApplyProfile(container.AppArmorProfile); err != nil { return fmt.Errorf("set apparmor profile %s: %s", container.AppArmorProfile, err) } if err := label.SetProcessLabel(container.ProcessLabel); err != nil { return fmt.Errorf("set process label %s", err) } // TODO: (crosbymichael) make this configurable at the Config level if container.RestrictSys { if (cloneFlags & syscall.CLONE_NEWNS) == 0 { return fmt.Errorf("unable to restrict access to kernel files without mount namespace") } if err := restrict.Restrict("proc/sys", "proc/sysrq-trigger", "proc/irq", "proc/bus"); err != nil { return err } } pdeathSignal, err := system.GetParentDeathSignal() if err != nil { return fmt.Errorf("get parent death signal %s", err) } if err := FinalizeNamespace(container); err != nil { return fmt.Errorf("finalize namespace %s", err) } // FinalizeNamespace can change user/group which clears the parent death // signal, so we restore it here. if err := RestoreParentDeathSignal(pdeathSignal); err != nil { return fmt.Errorf("restore parent death signal %s", err) } return system.Execv(args[0], args[0:], os.Environ()) }
func doChild(rootdir string, progfile string, plan plan, stdin_fd, stdout_fd, stderr_fd [2]int) (error, string) { if os.Getpid() != 1 { return errors.New("not cloned?"), "" } if err := syscall.Dup2(stdin_fd[0], 0); err != nil { return err, "dup2 failed" } syscall.Close(stdin_fd[0]) syscall.Close(stdin_fd[1]) if err := syscall.Dup2(stdout_fd[1], 1); err != nil { return err, "dup2 failed" } syscall.Close(stdout_fd[0]) syscall.Close(stdout_fd[1]) if err := syscall.Dup2(stderr_fd[1], 2); err != nil { return err, "dup2 failed" } syscall.Close(stderr_fd[0]) syscall.Close(stderr_fd[1]) if _, _, err := syscall.Syscall(syscall.SYS_PRCTL, syscall.PR_SET_PDEATHSIG, uintptr(syscall.SIGKILL), 0); err != 0 { return error(err), "PR_SET_PDEATHSIG failed" } if err := syscall.Sethostname([]byte("poe-sandbox")); err != nil { return err, "sethostname failed" } mounts := []mountPoint{ {"none", "/", "", syscall.MS_PRIVATE | syscall.MS_REC, ""}, {rootdir, rootdir, "bind", syscall.MS_BIND | syscall.MS_REC, ""}, // { "none", rootdir + "/proc", "proc", syscall.MS_NOSUID | syscall.MS_NOEXEC | syscall.MS_NODEV, "" }, // { "none", rootdir + "/dev", "devtmpfs", syscall.MS_NOSUID | syscall.MS_NOEXEC, "" }, // { "none", rootdir + "/dev/shm", "tmpfs", syscall.MS_NOSUID | syscall.MS_NODEV, "" }, } for _, point := range mounts { if err := syscall.Mount(point.source, point.target, point.fstype, point.flags, point.data); err != nil { return err, fmt.Sprintf("mount '%s' on '%s' (%s) failed", point.source, point.target, point.fstype) } } if err := syscall.Chroot(rootdir); err != nil { return err, "chroot failed" } if _, err := syscall.Setsid(); err != nil { return err, "setsid failed" } pw, err := user.Lookup(username) if err != nil { return err, "getpwnam failed" } uid, err := strconv.Atoi(pw.Uid) if err != nil { return err, "atoi error" } gid, err := strconv.Atoi(pw.Gid) if err != nil { return err, "atoi error" } // TODO: initgroups if err := syscall.Setresgid(gid, gid, gid); err != nil { return err, "setresgid failed" } if err := syscall.Setresuid(uid, uid, uid); err != nil { return err, "setresuid failed" } if err := syscall.Chdir("/tmp"); err != nil { return err, "chdir failed" } // stop os.Stdin.Read(make([]byte, 1)) // be traced if _, _, err := syscall.Syscall(syscall.SYS_PRCTL, PR_SET_NO_NEW_PRIVS, 1, 0); err != 0 { return error(err), "PR_SET_NO_NEW_PRIVS failed" } if err := SetupSeccomp(); err != nil { return err, "seccomp fail" } envp := []string{ "PATH=/opt/bin:/usr/bin", "USER="******"LOGNAME=" + username, } cmdl := make([]string, 0, len(plan.Compiler.Command)+len(plan.Extra)-1) for _, arg := range plan.Compiler.Command { if arg == "PROGRAM" { cmdl = append(cmdl, progfile) } else if arg == "EXTRA" { cmdl = append(cmdl, plan.Extra...) } else { cmdl = append(cmdl, arg) } } if err := syscall.Exec(cmdl[0], cmdl, envp); err != nil { return err, "execve failed" } return errors.New("unreachable"), "" }
func (*hostNameSetter) SetHostname(hostname string) error { return syscall.Sethostname([]byte(hostname)) }
func main() { var console *os.File // Parse flags. flag.Parse() if *server_fd == -1 { // Open the console. if f, err := os.OpenFile(*control, os.O_RDWR, 0); err != nil { log.Fatal("Problem opening console:", err) } else { console = f } // Make sure devpts is mounted. err := mount("devpts", "/dev/pts") if err != nil { log.Fatal(err) } // Notify novmm that we're ready. buffer := make([]byte, 1, 1) buffer[0] = protocol.NoGuestStatusOkay n, err := console.Write(buffer) if err != nil || n != 1 { log.Fatal(err) } // Read our response. n, err = console.Read(buffer) if n != 1 || err != nil { log.Fatal(protocol.UnknownCommand) } // Rerun to cleanup argv[0], or create a real init. new_args := make([]string, 0, len(os.Args)+1) new_args = append(new_args, "noguest") new_args = append(new_args, "-serverfd", "0") new_args = append(new_args, os.Args[1:]...) switch buffer[0] { case protocol.NoGuestCommandRealInit: // Run our noguest server in a new process. proc_attr := &syscall.ProcAttr{ Dir: "/", Env: os.Environ(), Files: []uintptr{console.Fd(), 1, 2}, } _, err := syscall.ForkExec(os.Args[0], new_args, proc_attr) if err != nil { log.Fatal(err) } // Exec our real init here in place. err = syscall.Exec("/sbin/init", []string{"init"}, os.Environ()) log.Fatal(err) case protocol.NoGuestCommandFakeInit: // Since we don't have any init to setup basic // things, like our hostname we do some of that here. syscall.Sethostname([]byte("novm")) default: // What the heck is this? log.Fatal(protocol.UnknownCommand) } } else { // Open the defined fd. console = os.NewFile(uintptr(*server_fd), "console") } // Small victory. log.Printf("~~~ NOGUEST ~~~") // Create our RPC server. rpc.Run(console) }
func SetHostname(hostname string) error { if err := syscall.Sethostname([]byte(hostname)); err != nil { return err } return ioutil.WriteFile("/etc/hostname", []byte(hostname), 0644) }
func Sethostname(name string) error { return syscall.Sethostname([]byte(name)) }
// TODO(vishh): This is part of the libcontainer API and it does much more than just namespaces related work. // Move this to libcontainer package. // Init is the init process that first runs inside a new namespace to setup mounts, users, networking, // and other options required for the new container. // The caller of Init function has to ensure that the go runtime is locked to an OS thread // (using runtime.LockOSThread) else system calls like setns called within Init may not work as intended. func Init(container *libcontainer.Config, uncleanRootfs, consolePath string, pipe *os.File, args []string) (err error) { defer func() { // if we have an error during the initialization of the container's init then send it back to the // parent process in the form of an initError. if err != nil { // ensure that any data sent from the parent is consumed so it doesn't // receive ECONNRESET when the child writes to the pipe. ioutil.ReadAll(pipe) if err := json.NewEncoder(pipe).Encode(initError{ Message: err.Error(), }); err != nil { panic(err) } } // ensure that this pipe is always closed pipe.Close() }() rootfs, err := utils.ResolveRootfs(uncleanRootfs) if err != nil { return err } // clear the current processes env and replace it with the environment // defined on the container if err := LoadContainerEnvironment(container); err != nil { return err } // We always read this as it is a way to sync with the parent as well var networkState *network.NetworkState if err := json.NewDecoder(pipe).Decode(&networkState); err != nil { return err } // join any namespaces via a path to the namespace fd if provided if err := joinExistingNamespaces(container.Namespaces); err != nil { return err } if consolePath != "" { if err := console.OpenAndDup(consolePath); err != nil { return err } } if _, err := syscall.Setsid(); err != nil { return fmt.Errorf("setsid %s", err) } if consolePath != "" { if err := system.Setctty(); err != nil { return fmt.Errorf("setctty %s", err) } } if err := setupNetwork(container, networkState); err != nil { return fmt.Errorf("setup networking %s", err) } if err := setupRoute(container); err != nil { return fmt.Errorf("setup route %s", err) } if err := setupRlimits(container); err != nil { return fmt.Errorf("setup rlimits %s", err) } label.Init() if err := mount.InitializeMountNamespace(rootfs, consolePath, container.RestrictSys, (*mount.MountConfig)(container.MountConfig)); err != nil { return fmt.Errorf("setup mount namespace %s", err) } if container.Hostname != "" { if err := syscall.Sethostname([]byte(container.Hostname)); err != nil { return fmt.Errorf("unable to sethostname %q: %s", container.Hostname, err) } } if err := apparmor.ApplyProfile(container.AppArmorProfile); err != nil { return fmt.Errorf("set apparmor profile %s: %s", container.AppArmorProfile, err) } if err := label.SetProcessLabel(container.ProcessLabel); err != nil { return fmt.Errorf("set process label %s", err) } // TODO: (crosbymichael) make this configurable at the Config level if container.RestrictSys { if err := restrict.Restrict("proc/sys", "proc/sysrq-trigger", "proc/irq", "proc/bus"); err != nil { return err } } pdeathSignal, err := system.GetParentDeathSignal() if err != nil { return fmt.Errorf("get parent death signal %s", err) } if err := FinalizeNamespace(container); err != nil { return fmt.Errorf("finalize namespace %s", err) } // FinalizeNamespace can change user/group which clears the parent death // signal, so we restore it here. if err := RestoreParentDeathSignal(pdeathSignal); err != nil { return fmt.Errorf("restore parent death signal %s", err) } return system.Execv(args[0], args[0:], os.Environ()) }