diff --git a/.gitignore b/.gitignore index 9895fe1..3560535 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /runc-57b9972.tar.gz /runc-04f275d.tar.gz /runc-47ea5c7.tar.gz +/runc-c91b5be.tar.gz diff --git a/0001-Set-init-processes-as-non-dumpable.patch b/0001-Set-init-processes-as-non-dumpable.patch new file mode 100644 index 0000000..937ba38 --- /dev/null +++ b/0001-Set-init-processes-as-non-dumpable.patch @@ -0,0 +1,111 @@ +From 50a19c6ff828c58e5dab13830bd3dacde268afe5 Mon Sep 17 00:00:00 2001 +From: Michael Crosby +Date: Wed, 7 Dec 2016 15:05:51 -0800 +Subject: [PATCH] Set init processes as non-dumpable + +This sets the init processes that join and setup the container's +namespaces as non-dumpable before they setns to the container's pid (or +any other ) namespace. + +This settings is automatically reset to the default after the Exec in +the container so that it does not change functionality for the +applications that are running inside, just our init processes. + +This prevents parent processes, the pid 1 of the container, to ptrace +the init process before it drops caps and other sets LSMs. + +This patch also ensures that the stateDirFD being used is still closed +prior to exec, even though it is set as O_CLOEXEC, because of the order +in the kernel. + +https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318 + +The order during the exec syscall is that the process is set back to +dumpable before O_CLOEXEC are processed. + +Signed-off-by: Michael Crosby +--- + libcontainer/init_linux.go | 3 ++- + libcontainer/nsenter/nsexec.c | 5 +++++ + libcontainer/setns_init_linux.go | 7 ++++++- + libcontainer/standard_init_linux.go | 3 +++ + 4 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go +index b1e6762..4043d51 100644 +--- a/libcontainer/init_linux.go ++++ b/libcontainer/init_linux.go +@@ -77,7 +77,8 @@ func newContainerInit(t initType, pipe *os.File, stateDirFD int) (initer, error) + switch t { + case initSetns: + return &linuxSetnsInit{ +- config: config, ++ config: config, ++ stateDirFD: stateDirFD, + }, nil + case initStandard: + return &linuxStandardInit{ +diff --git a/libcontainer/nsenter/nsexec.c b/libcontainer/nsenter/nsexec.c +index b93f827..4b5398b 100644 +--- a/libcontainer/nsenter/nsexec.c ++++ b/libcontainer/nsenter/nsexec.c +@@ -408,6 +408,11 @@ void nsexec(void) + if (pipenum == -1) + return; + ++ /* make the process non-dumpable */ ++ if (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) != 0) { ++ bail("failed to set process as non-dumpable"); ++ } ++ + /* Parse all of the netlink configuration. */ + nl_parse(pipenum, &config); + +diff --git a/libcontainer/setns_init_linux.go b/libcontainer/setns_init_linux.go +index 2a8f345..7f5f182 100644 +--- a/libcontainer/setns_init_linux.go ++++ b/libcontainer/setns_init_linux.go +@@ -5,6 +5,7 @@ package libcontainer + import ( + "fmt" + "os" ++ "syscall" + + "github.com/opencontainers/runc/libcontainer/apparmor" + "github.com/opencontainers/runc/libcontainer/keys" +@@ -16,7 +17,8 @@ import ( + // linuxSetnsInit performs the container's initialization for running a new process + // inside an existing container. + type linuxSetnsInit struct { +- config *initConfig ++ config *initConfig ++ stateDirFD int + } + + func (l *linuxSetnsInit) getSessionRingName() string { +@@ -49,5 +51,8 @@ func (l *linuxSetnsInit) Init() error { + if err := label.SetProcessLabel(l.config.ProcessLabel); err != nil { + return err + } ++ // close the statedir fd before exec because the kernel resets dumpable in the wrong order ++ // https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318 ++ syscall.Close(l.stateDirFD) + return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ()) + } +diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go +index 2104f1a..6a65154 100644 +--- a/libcontainer/standard_init_linux.go ++++ b/libcontainer/standard_init_linux.go +@@ -171,6 +171,9 @@ func (l *linuxStandardInit) Init() error { + return newSystemErrorWithCause(err, "init seccomp") + } + } ++ // close the statedir fd before exec because the kernel resets dumpable in the wrong order ++ // https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318 ++ syscall.Close(l.stateDirFD) + if err := syscall.Exec(name, l.config.Args[0:], os.Environ()); err != nil { + return newSystemErrorWithCause(err, "exec user process") + } +-- +2.11.0 + diff --git a/runc.spec b/runc.spec index 2ca3f48..76eb96f 100644 --- a/runc.spec +++ b/runc.spec @@ -26,7 +26,7 @@ # https://github.com/opencontainers/runc %global provider_prefix %{provider}.%{provider_tld}/%{project}/%{repo} %global import_path %{provider_prefix} -%global commit 47ea5c75ebeb40a317d2cfa95f9c3536c00c1eea +%global commit c91b5bea4830a57eac7882d7455d59518cdf70ec %global shortcommit %(c=%{commit}; echo ${c:0:7}) Name: %{repo} @@ -34,11 +34,12 @@ Name: %{repo} Epoch: 1 %endif Version: 1.0.0 -Release: 2.rc2.git%{shortcommit}%{?dist} +Release: 3.rc2.git%{shortcommit}%{?dist} Summary: CLI for running Open Containers License: ASL 2.0 URL: https://%{provider_prefix} Source0: https://%{provider_prefix}/archive/%{commit}/%{repo}-%{shortcommit}.tar.gz +Patch0: 0001-Set-init-processes-as-non-dumpable.patch # e.g. el6 has ppc64 arch without gcc-go, so EA tag is required #ExclusiveArch: %%{?go_arches:%%{go_arches}}%%{!?go_arches:%%{ix86} x86_64 %{arm}} @@ -294,6 +295,10 @@ export GOPATH=%{buildroot}/%{gopath}:$(pwd)/Godeps/_workspace:%{gopath} %endif %changelog +* Wed Jan 11 2017 Lokesh Mandvekar - 1:1.0.0-3.rc2 +- Resolves: #1412238 - *CVE-2016-9962* - set init processes as non-dumpable, +runc patch from Michael Crosby + * Fri Jan 06 2017 Lokesh Mandvekar - 1:1.0.0-2.rc2.git47ea5c7 - patch to enable seccomp - Pass $BUILDTAGS to the compiler in cases where we don't have to define diff --git a/sources b/sources index fd672ca..44062ab 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (runc-47ea5c7.tar.gz) = 4a842b4bf3b29a345525abb8e832c6e27d07c863c048184725ce1daf2861bac3f3335baddebd1e397ea7fe496c931e611c7ea217a3b81772fabb658419b1bdb5 +SHA512 (runc-c91b5be.tar.gz) = cfafaa9806e5304453b8f7137a507ab3a26a8efc3c87dcff77b72ad5eb9a5331b38bb8974b333b7026352cf5e6aa995fb5792af37078bff9be7c80a1d2cbf34d