From 178bad5e7101c3b93f17886fe7668514de66efa5 Mon Sep 17 00:00:00 2001 From: Phil Estes Date: Tue, 1 Mar 2016 13:19:07 -0500 Subject: [PATCH] Properly setuid/setgid after entering userns The re-work of namespace entering lost the setuid/setgid that was part of the Go-routine based process exec in the prior code. A side issue was found with setting oom_score_adj before execve() in a userns that is also solved here. Docker-DCO-1.1-Signed-off-by: Phil Estes (github: estesp) --- libcontainer/init_linux.go | 7 ++++--- libcontainer/nsenter/nsexec.c | 10 ++++++++++ libcontainer/process_linux.go | 8 ++++++++ libcontainer/setns_init_linux.go | 3 --- libcontainer/standard_init_linux.go | 4 +--- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go index 5b78b85a1c9..8a61516d8da 100644 --- a/libcontainer/init_linux.go +++ b/libcontainer/init_linux.go @@ -325,9 +325,10 @@ func setupRlimits(config *configs.Config) error { return nil } -func setOomScoreAdj(oomScoreAdj int) error { - path := "/proc/self/oom_score_adj" - return ioutil.WriteFile(path, []byte(strconv.Itoa(oomScoreAdj)), 0700) +func setOomScoreAdj(oomScoreAdj int, pid int) error { + path := fmt.Sprintf("/proc/%d/oom_score_adj", pid) + + return ioutil.WriteFile(path, []byte(strconv.Itoa(oomScoreAdj)), 0600) } // killCgroupProcesses freezes then iterates over all the processes inside the diff --git a/libcontainer/nsenter/nsexec.c b/libcontainer/nsenter/nsexec.c index fbeeb290d23..da800f79feb 100644 --- a/libcontainer/nsenter/nsexec.c +++ b/libcontainer/nsenter/nsexec.c @@ -368,6 +368,16 @@ static void process_nl_attributes(int pipenum, char *data, int data_size) exit(1); } + if (setuid(0) == -1) { + pr_perror("setuid failed"); + exit(1); + } + + if (setgid(0) == -1) { + pr_perror("setgid failed"); + exit(1); + } + if (consolefd != -1) { if (ioctl(consolefd, TIOCSCTTY, 0) == -1) { pr_perror("ioctl TIOCSCTTY failed"); diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go index ebae030b976..9ff43861512 100644 --- a/libcontainer/process_linux.go +++ b/libcontainer/process_linux.go @@ -88,6 +88,10 @@ func (p *setnsProcess) start() (err error) { if err := utils.WriteJSON(p.parentPipe, p.config); err != nil { return newSystemError(err) } + // set oom_score_adj + if err := setOomScoreAdj(p.config.Config.OomScoreAdj, p.pid()); err != nil { + return newSystemError(err) + } if err := syscall.Shutdown(int(p.parentPipe.Fd()), syscall.SHUT_WR); err != nil { return newSystemError(err) @@ -276,6 +280,10 @@ loop: if err := p.manager.Set(p.config.Config); err != nil { return newSystemError(err) } + // set oom_score_adj + if err := setOomScoreAdj(p.config.Config.OomScoreAdj, p.pid()); err != nil { + return newSystemError(err) + } // call prestart hooks if !p.config.Config.Namespaces.Contains(configs.NEWNS) { if p.config.Config.Hooks != nil { diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go index 2dfec9b7926..5d78cc5be1f 100644 --- a/libcontainer/setns_init_linux.go +++ b/libcontainer/setns_init_linux.go @@ -31,9 +31,6 @@ func (l *linuxSetnsInit) Init() error { if err := setupRlimits(l.config.Config); err != nil { return err } - if err := setOomScoreAdj(l.config.Config.OomScoreAdj); 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 diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go index 134205d55a1..23604196ffa 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -76,9 +76,7 @@ func (l *linuxStandardInit) Init() error { 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) {