diff mbox

[Lucid,CVE,2014-0203] fix autofs/afs/etc. magic mountpoint breakage

Message ID 53BA9FDE.3040800@canonical.com
State New
Headers show

Commit Message

Maarten Lankhorst July 7, 2014, 1:25 p.m. UTC
We end up trying to kfree() nd.last.name on open("/mnt/tmp", O_CREAT)
if /mnt/tmp is an autofs direct mount.  The reason is that nd.last_type
is bogus here; we want LAST_BIND for everything of that kind and we
get LAST_NORM left over from finding parent directory.

So make sure that it *is* set properly; set to LAST_BIND before
doing ->follow_link() - for normal symlinks it will be changed
by __vfs_follow_link() and everything else needs it set that way.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
(cherry picked from commit 86acdca1b63e6890540fa19495cfc708beff3d8b)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
---
This is a straight cherry pick, and I confirmed that I can create a dumb test program
according to the commit which gets into a loop of oopses fairly quickly.

// CVE 2014-0203

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
        while (1) close(open("/mnt/i386", O_CREAT));

        return 0;
}

/etc/auto.master contents:
/- /etc/auto.data

/etc/auto.data contents:
/mnt/i386 nfsserver:/srv/nfsdir

 fs/namei.c     | 1 +
 fs/proc/base.c | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

Comments

Tim Gardner July 8, 2014, 10:04 a.m. UTC | #1

diff mbox

Patch

diff --git a/fs/namei.c b/fs/namei.c
index 42e9526..3faeb3c 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -636,6 +636,7 @@  static __always_inline int __do_follow_link(struct path *path, struct nameidata
 		dget(dentry);
 	}
 	mntget(path->mnt);
+	nd->last_type = LAST_BIND;
 	cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
 	error = PTR_ERR(cookie);
 	if (!IS_ERR(cookie)) {
diff --git a/fs/proc/base.c b/fs/proc/base.c
index b1d020e..689af59 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1381,7 +1381,6 @@  static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
 		goto out;
 
 	error = PROC_I(inode)->op.proc_get_link(inode, &nd->path);
-	nd->last_type = LAST_BIND;
 out:
 	return ERR_PTR(error);
 }