File CVE-2019-19921.patch of Package docker-runc.13803
From 3291d66b98445bd7f7d02eac7f2bca2ac2c56942 Mon Sep 17 00:00:00 2001
From: Aleksa Sarai <asarai@suse.de>
Date: Sat, 21 Dec 2019 23:40:17 +1100
Subject: [PATCH] rootfs: do not permit /proc mounts to non-directories
mount(2) will blindly follow symlinks, which is a problem because it
allows a malicious container to trick runc into mounting /proc to an
entirely different location (and thus within the attacker's control for
a rename-exchange attack).
This is just a hotfix (to "stop the bleeding"), and the more complete
fix would be finish libpathrs and port runc to it (to avoid these types
of attacks entirely, and defend against a variety of other /proc-related
attacks). It can be bypased by someone having "/" be a volume controlled
by another container.
Fixes: CVE-2019-19921
Signed-off-by: Aleksa Sarai <asarai@suse.de>
---
libcontainer/rootfs_linux.go | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go
index 291021440a1a..106c4c2b98bf 100644
--- a/libcontainer/rootfs_linux.go
+++ b/libcontainer/rootfs_linux.go
@@ -299,6 +299,18 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string, enableCgroupns b
switch m.Device {
case "proc", "sysfs":
+ // If the destination already exists and is not a directory, we bail
+ // out This is to avoid mounting through a symlink or similar -- which
+ // has been a "fun" attack scenario in the past.
+ // TODO: This won't be necessary once we switch to libpathrs and we can
+ // stop all of these symlink-exchange attacks.
+ if fi, err := os.Lstat(dest); err != nil {
+ if !os.IsNotExist(err) {
+ return err
+ }
+ } else if fi.Mode()&os.ModeDir == 0 {
+ return fmt.Errorf("filesystem %q must be mounted on ordinary directory", m.Device)
+ }
if err := os.MkdirAll(dest, 0755); err != nil {
return err
}
--
2.24.1