Accepting request 733530 from home:cyphar:containers:maint
Fix CVE patch. OBS-URL: https://build.opensuse.org/request/show/733530 OBS-URL: https://build.opensuse.org/package/show/Virtualization:containers/runc?expand=0&rev=77
This commit is contained in:
parent
1a94d9d340
commit
c0cf07af42
@ -1,40 +1,79 @@
|
||||
From 331692baa7afdf6c186f8667cb0e6362ea0802b3 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Crosby <crosbymichael@gmail.com>
|
||||
From 6ce3791ce27128f8b4ae45323effa10953fa9904 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksa Sarai <asarai@suse.de>
|
||||
Date: Mon, 23 Sep 2019 16:45:45 -0400
|
||||
Subject: [PATCH] Only allow proc mount if it is procfs
|
||||
Subject: [PATCH] CVE-2019-16884
|
||||
|
||||
Fixes #2128
|
||||
This patch includes a squash of the following upstream patches:
|
||||
|
||||
This allows proc to be bind mounted for host and rootless namespace usecases but
|
||||
it removes the ability to mount over the top of proc with a directory.
|
||||
* 331692baa7af ("Only allow proc mount if it is procfs")
|
||||
|
||||
```bash
|
||||
> sudo docker run --rm apparmor
|
||||
docker: Error response from daemon: OCI runtime create failed:
|
||||
container_linux.go:346: starting container process caused "process_linux.go:449:
|
||||
container init caused \"rootfs_linux.go:58: mounting
|
||||
\\\"/var/lib/docker/volumes/aae28ea068c33d60e64d1a75916cf3ec2dc3634f97571854c9ed30c8401460c1/_data\\\"
|
||||
to rootfs
|
||||
\\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged\\\"
|
||||
at \\\"/proc\\\" caused
|
||||
\\\"\\\\\\\"/var/lib/docker/overlay2/a6be5ae911bf19f8eecb23a295dec85be9a8ee8da66e9fb55b47c841d1e381b7/merged/proc\\\\\\\"
|
||||
cannot be mounted because it is not of type proc\\\"\"": unknown.
|
||||
As well as the following still-in-review patches:
|
||||
|
||||
> sudo docker run --rm -v /proc:/proc apparmor
|
||||
|
||||
docker-default (enforce) root 18989 0.9 0.0 1288 4 ?
|
||||
Ss 16:47 0:00 sleep 20
|
||||
```
|
||||
* ("apparmor: verify that writes to /proc/... are on procfs")
|
||||
* ("selinux: verify that writes to /proc/... are on procfs")
|
||||
|
||||
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
---
|
||||
libcontainer/container_linux.go | 4 +--
|
||||
libcontainer/rootfs_linux.go | 50 +++++++++++++++++++++++--------
|
||||
libcontainer/rootfs_linux_test.go | 8 ++---
|
||||
3 files changed, 43 insertions(+), 19 deletions(-)
|
||||
libcontainer/apparmor/apparmor.go | 18 ++++++-
|
||||
libcontainer/container_linux.go | 4 +-
|
||||
libcontainer/rootfs_linux.go | 50 ++++++++++++++-----
|
||||
libcontainer/rootfs_linux_test.go | 8 +--
|
||||
.../selinux/go-selinux/selinux_linux.go | 20 ++++++++
|
||||
5 files changed, 79 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/apparmor/apparmor.go b/libcontainer/apparmor/apparmor.go
|
||||
index 7fff0627fa1b..3504b80d8643 100644
|
||||
--- a/libcontainer/apparmor/apparmor.go
|
||||
+++ b/libcontainer/apparmor/apparmor.go
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
+
|
||||
+ "golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// IsEnabled returns true if apparmor is enabled for the host.
|
||||
@@ -19,7 +21,13 @@ func IsEnabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
-func setprocattr(attr, value string) error {
|
||||
+func isProcHandle(fh *os.File) (bool, error) {
|
||||
+ var buf unix.Statfs_t
|
||||
+ err := unix.Fstatfs(int(fh.Fd()), &buf)
|
||||
+ return buf.Type == unix.PROC_SUPER_MAGIC, err
|
||||
+}
|
||||
+
|
||||
+func setProcAttr(attr, value string) error {
|
||||
// Under AppArmor you can only change your own attr, so use /proc/self/
|
||||
// instead of /proc/<tid>/ like libapparmor does
|
||||
path := fmt.Sprintf("/proc/self/attr/%s", attr)
|
||||
@@ -30,6 +38,12 @@ func setprocattr(attr, value string) error {
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
+ if ok, err := isProcHandle(f); err != nil {
|
||||
+ return err
|
||||
+ } else if !ok {
|
||||
+ return fmt.Errorf("/proc path not on procfs: %s", path)
|
||||
+ }
|
||||
+
|
||||
_, err = fmt.Fprintf(f, "%s", value)
|
||||
return err
|
||||
}
|
||||
@@ -37,7 +51,7 @@ func setprocattr(attr, value string) error {
|
||||
// changeOnExec reimplements aa_change_onexec from libapparmor in Go
|
||||
func changeOnExec(name string) error {
|
||||
value := "exec " + name
|
||||
- if err := setprocattr("exec", value); err != nil {
|
||||
+ if err := setProcAttr("exec", value); err != nil {
|
||||
return fmt.Errorf("apparmor failed to apply profile: %s", err)
|
||||
}
|
||||
return nil
|
||||
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||
index 092792040f5b..6ff4d96a5f55 100644
|
||||
index 7e58e5e00824..d51e35dffb93 100644
|
||||
--- a/libcontainer/container_linux.go
|
||||
+++ b/libcontainer/container_linux.go
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
@ -46,7 +85,7 @@ index 092792040f5b..6ff4d96a5f55 100644
|
||||
"github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
"github.com/opencontainers/runc/libcontainer/configs"
|
||||
"github.com/opencontainers/runc/libcontainer/intelrdt"
|
||||
@@ -1176,7 +1176,7 @@ func (c *linuxContainer) makeCriuRestoreMountpoints(m *configs.Mount) error {
|
||||
@@ -1160,7 +1160,7 @@ func (c *linuxContainer) makeCriuRestoreMountpoints(m *configs.Mount) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -56,7 +95,7 @@ index 092792040f5b..6ff4d96a5f55 100644
|
||||
}
|
||||
m.Destination = dest
|
||||
diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go
|
||||
index 1513c1d94b63..10888b499beb 100644
|
||||
index f13b226e444e..5650b0acbca8 100644
|
||||
--- a/libcontainer/rootfs_linux.go
|
||||
+++ b/libcontainer/rootfs_linux.go
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
@ -77,7 +116,7 @@ index 1513c1d94b63..10888b499beb 100644
|
||||
return err
|
||||
}
|
||||
// update the mount with the correct dest after symlinks are resolved.
|
||||
@@ -414,7 +414,7 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string, enableCgroupns b
|
||||
@@ -388,7 +388,7 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string, enableCgroupns b
|
||||
if dest, err = securejoin.SecureJoin(rootfs, m.Destination); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -86,7 +125,7 @@ index 1513c1d94b63..10888b499beb 100644
|
||||
return err
|
||||
}
|
||||
// update the mount with the correct dest after symlinks are resolved.
|
||||
@@ -461,12 +461,12 @@ func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) {
|
||||
@@ -435,12 +435,12 @@ func getCgroupMounts(m *configs.Mount) ([]*configs.Mount, error) {
|
||||
return binds, nil
|
||||
}
|
||||
|
||||
@ -104,7 +143,7 @@ index 1513c1d94b63..10888b499beb 100644
|
||||
// White list, it should be sub directories of invalid destinations
|
||||
validDestinations := []string{
|
||||
// These entries can be bind mounted by files emulated by fuse,
|
||||
@@ -489,16 +489,40 @@ func checkMountDestination(rootfs, dest string) error {
|
||||
@@ -463,16 +463,40 @@ func checkMountDestination(rootfs, dest string) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -190,6 +229,58 @@ index d755984bc0f9..1bfe7c663225 100644
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
|
||||
index d7786c33c197..611df8f9b3b0 100644
|
||||
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
|
||||
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
|
||||
@@ -18,6 +18,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
+
|
||||
+ "golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -252,6 +254,12 @@ func getSELinuxPolicyRoot() string {
|
||||
return filepath.Join(selinuxDir, readConfig(selinuxTypeTag))
|
||||
}
|
||||
|
||||
+func isProcHandle(fh *os.File) (bool, error) {
|
||||
+ var buf unix.Statfs_t
|
||||
+ err := unix.Fstatfs(int(fh.Fd()), &buf)
|
||||
+ return buf.Type == unix.PROC_SUPER_MAGIC, err
|
||||
+}
|
||||
+
|
||||
func readCon(fpath string) (string, error) {
|
||||
if fpath == "" {
|
||||
return "", ErrEmptyPath
|
||||
@@ -263,6 +271,12 @@ func readCon(fpath string) (string, error) {
|
||||
}
|
||||
defer in.Close()
|
||||
|
||||
+ if ok, err := isProcHandle(in); err != nil {
|
||||
+ return "", err
|
||||
+ } else if !ok {
|
||||
+ return "", fmt.Errorf("/proc path not on procfs: %s", fpath)
|
||||
+ }
|
||||
+
|
||||
var retval string
|
||||
if _, err := fmt.Fscanf(in, "%s", &retval); err != nil {
|
||||
return "", err
|
||||
@@ -345,6 +359,12 @@ func writeCon(fpath string, val string) error {
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
+ if ok, err := isProcHandle(out); err != nil {
|
||||
+ return err
|
||||
+ } else if !ok {
|
||||
+ return fmt.Errorf("/proc path not on procfs: %s", fpath)
|
||||
+ }
|
||||
+
|
||||
if val != "" {
|
||||
_, err = out.Write([]byte(val))
|
||||
} else {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
|
10
runc.spec
10
runc.spec
@ -51,7 +51,9 @@ Source0: https://github.com/opencontainers/runc/releases/download/v%{_ver
|
||||
Source1: https://github.com/opencontainers/runc/releases/download/v%{_version}/runc.tar.xz.asc#/runc-%{_version}.tar.xz.asc
|
||||
Source2: runc.keyring
|
||||
Source3: runc-rpmlintrc
|
||||
# FIX-UPSTREAM: Backport of https://github.com/opencontainers/runc/pull/2129. CVE-2019-16884
|
||||
# FIX-UPSTREAM: Backport of https://github.com/opencontainers/runc/pull/2129.
|
||||
# https://github.com/opencontainers/selinux/pull/59.
|
||||
# https://github.com/opencontainers/runc/pull/2130. CVE-2019-16884
|
||||
Patch1: CVE-2019-16884.patch
|
||||
BuildRequires: fdupes
|
||||
BuildRequires: go-go-md2man
|
||||
@ -95,9 +97,9 @@ Test package for runc. It contains the source code and the tests.
|
||||
# some point during the build and you need to directly use go list directly it
|
||||
# will get confused by symlinks.
|
||||
export GOPATH=${HOME}/go
|
||||
mkdir -pv $HOME/go/src/%project
|
||||
mkdir -p $HOME/go/src/%project
|
||||
rm -rf $HOME/go/src/%project/*
|
||||
cp -av * $HOME/go/src/%project
|
||||
cp -a * $HOME/go/src/%project
|
||||
|
||||
# Additionally enable seccomp.
|
||||
%if 0%{?with_libseccomp}
|
||||
@ -118,7 +120,7 @@ EOF
|
||||
source ./.runc_build_env
|
||||
|
||||
# Build runc.
|
||||
make -C "$HOME/go/src/%project" EXTRA_FLAGS="-x $BUILDFLAGS" BUILDTAGS="$BUILDTAGS" COMMIT_NO="%{git_version}" runc
|
||||
make -C "$HOME/go/src/%project" EXTRA_FLAGS="$BUILDFLAGS" BUILDTAGS="$BUILDTAGS" COMMIT_NO="%{git_version}" runc
|
||||
mv "$HOME/go/src/%project/runc" %{name}-%{version}
|
||||
|
||||
# Build man pages, this can only be done on arches where we can build go-md2man.
|
||||
|
Loading…
Reference in New Issue
Block a user