commit:     8bd76a7d71bd8549706fe1bf2ba60a7cbe972fab
Author:     Manuel Rüger <mrueg <AT> gentoo <DOT> org>
AuthorDate: Wed Jan 11 11:34:13 2017 +0000
Commit:     Manuel Rüger <mrueg <AT> gentoo <DOT> org>
CommitDate: Wed Jan 11 11:35:03 2017 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=8bd76a7d

app-emulation/runc: Apply fix for CVE-2016-9962

Package-Manager: Portage-2.3.3, Repoman-2.3.1

 .../files/runc-1.0.0_rc2-init-non-dumpable.patch   | 108 +++++++++++++++++++++
 app-emulation/runc/runc-1.0.0_rc2-r2.ebuild        |  59 +++++++++++
 2 files changed, 167 insertions(+)

diff --git a/app-emulation/runc/files/runc-1.0.0_rc2-init-non-dumpable.patch 
b/app-emulation/runc/files/runc-1.0.0_rc2-init-non-dumpable.patch
new file mode 100644
index 00000000..486835a
--- /dev/null
+++ b/app-emulation/runc/files/runc-1.0.0_rc2-init-non-dumpable.patch
@@ -0,0 +1,108 @@
+From 50a19c6ff828c58e5dab13830bd3dacde268afe5 Mon Sep 17 00:00:00 2001
+From: Michael Crosby <[email protected]>
+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 <[email protected]>
+---
+ 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")
+       }

diff --git a/app-emulation/runc/runc-1.0.0_rc2-r2.ebuild 
b/app-emulation/runc/runc-1.0.0_rc2-r2.ebuild
new file mode 100644
index 00000000..4f5cf2f
--- /dev/null
+++ b/app-emulation/runc/runc-1.0.0_rc2-r2.ebuild
@@ -0,0 +1,59 @@
+# Copyright 1999-2017 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+EAPI=6
+EGO_PN="github.com/opencontainers/${PN}"
+
+if [[ ${PV} == *9999 ]]; then
+       inherit golang-vcs
+else
+       MY_PV="${PV/_/-}"
+       EGIT_COMMIT="v${MY_PV}"
+       RUNC_COMMIT="c91b5be" # Change this when you update the ebuild
+       SRC_URI="https://${EGO_PN}/archive/${EGIT_COMMIT}.tar.gz -> ${P}.tar.gz"
+       KEYWORDS="~amd64 ~ppc64"
+       inherit golang-vcs-snapshot
+fi
+
+DESCRIPTION="runc container cli tools"
+HOMEPAGE="http://runc.io";
+
+LICENSE="Apache-2.0"
+SLOT="0"
+IUSE="apparmor hardened +seccomp"
+
+RDEPEND="
+       apparmor? ( sys-libs/libapparmor )
+       seccomp? ( sys-libs/libseccomp )
+"
+
+S=${WORKDIR}/${P}/src/${EGO_PN}
+
+PATCHES=( "${FILESDIR}"/${P}-init-non-dumpable.patch )
+
+src_compile() {
+       # Taken from app-emulation/docker-1.7.0-r1
+       export CGO_CFLAGS="-I${ROOT}/usr/include"
+       export CGO_LDFLAGS="$(usex hardened '-fno-PIC ' '')
+               -L${ROOT}/usr/$(get_libdir)"
+
+       # Setup GOPATH so things build
+       rm -rf .gopath
+       mkdir -p .gopath/src/"$(dirname "${GITHUB_URI}")"
+       ln -sf ../../../.. .gopath/src/"${GITHUB_URI}"
+       export GOPATH="${PWD}/.gopath:${PWD}/vendor"
+
+       # build up optional flags
+       local options=(
+               $(usex apparmor 'apparmor')
+               $(usex seccomp 'seccomp')
+       )
+
+       emake BUILDTAGS="${options[*]}" \
+               COMMIT="${RUNC_COMMIT}"
+}
+
+src_install() {
+       dobin runc
+}

Reply via email to