Skip to content

Commit 3291d66

Browse files
committed
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 <[email protected]>
1 parent 7496a96 commit 3291d66

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

libcontainer/rootfs_linux.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,18 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string, enableCgroupns b
299299

300300
switch m.Device {
301301
case "proc", "sysfs":
302+
// If the destination already exists and is not a directory, we bail
303+
// out This is to avoid mounting through a symlink or similar -- which
304+
// has been a "fun" attack scenario in the past.
305+
// TODO: This won't be necessary once we switch to libpathrs and we can
306+
// stop all of these symlink-exchange attacks.
307+
if fi, err := os.Lstat(dest); err != nil {
308+
if !os.IsNotExist(err) {
309+
return err
310+
}
311+
} else if fi.Mode()&os.ModeDir == 0 {
312+
return fmt.Errorf("filesystem %q must be mounted on ordinary directory", m.Device)
313+
}
302314
if err := os.MkdirAll(dest, 0755); err != nil {
303315
return err
304316
}

0 commit comments

Comments
 (0)