From b77b0646ef4efe31a7449bb3d9360fd00f95433d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 17 Jul 2008 09:37:02 -0400 Subject: [PATCH] pass MAY_OPEN to vfs_permission() explicitly ... and get rid of the last "let's deduce mask from nameidata->flags" bit. Signed-off-by: Al Viro --- fs/exec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/exec.c') diff --git a/fs/exec.c b/fs/exec.c index b8792a131533..0ba5d355c5a1 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -118,7 +118,7 @@ asmlinkage long sys_uselib(const char __user * library) if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) goto exit; - error = vfs_permission(&nd, MAY_READ | MAY_EXEC); + error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN); if (error) goto exit; @@ -666,7 +666,7 @@ struct file *open_exec(const char *name) struct inode *inode = nd.path.dentry->d_inode; file = ERR_PTR(-EACCES); if (S_ISREG(inode->i_mode)) { - int err = vfs_permission(&nd, MAY_EXEC); + int err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); file = ERR_PTR(err); if (!err) { file = nameidata_to_filp(&nd, -- cgit v1.2.2 From e56b6a5dda1a36ffaa532df6f975ea324298fa4d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 May 2008 07:53:34 +0200 Subject: Re: [PATCH 3/6] vfs: open_exec cleanup On Mon, May 19, 2008 at 12:01:49AM +0200, Marcin Slusarz wrote: > open_exec is needlessly indented, calls ERR_PTR with 0 argument > (which is not valid errno) and jumps into middle of function > just to return value. > So clean it up a bit. Still looks rather messy. See below for a better version. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- fs/exec.c | 58 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 30 insertions(+), 28 deletions(-) (limited to 'fs/exec.c') diff --git a/fs/exec.c b/fs/exec.c index 0ba5d355c5a1..346e3f69c6e0 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -656,38 +656,40 @@ EXPORT_SYMBOL(setup_arg_pages); struct file *open_exec(const char *name) { struct nameidata nd; - int err; struct file *file; + int err; - err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC); - file = ERR_PTR(err); - - if (!err) { - struct inode *inode = nd.path.dentry->d_inode; - file = ERR_PTR(-EACCES); - if (S_ISREG(inode->i_mode)) { - int err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); - file = ERR_PTR(err); - if (!err) { - file = nameidata_to_filp(&nd, - O_RDONLY|O_LARGEFILE); - if (!IS_ERR(file)) { - err = deny_write_access(file); - if (err) { - fput(file); - file = ERR_PTR(err); - } - } -out: - return file; - } - } - release_open_intent(&nd); - path_put(&nd.path); + err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, + FMODE_READ|FMODE_EXEC); + if (err) + goto out; + + err = -EACCES; + if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) + goto out_path_put; + + err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); + if (err) + goto out_path_put; + + file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE); + if (IS_ERR(file)) + return file; + + err = deny_write_access(file); + if (err) { + fput(file); + goto out; } - goto out; -} + return file; + + out_path_put: + release_open_intent(&nd); + path_put(&nd.path); + out: + return ERR_PTR(err); +} EXPORT_SYMBOL(open_exec); int kernel_read(struct file *file, unsigned long offset, -- cgit v1.2.2 From 30524472c2f728c20d6bf35191042a5d455c0a64 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 22 Jul 2008 00:02:33 -0400 Subject: [PATCH] take noexec checks to very few callers that care Signed-off-by: Al Viro --- fs/exec.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'fs/exec.c') diff --git a/fs/exec.c b/fs/exec.c index 346e3f69c6e0..eca58c29eded 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -118,6 +118,10 @@ asmlinkage long sys_uselib(const char __user * library) if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) goto exit; + error = -EACCES; + if (nd.path.mnt->mnt_flags & MNT_NOEXEC) + goto exit; + error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN); if (error) goto exit; @@ -668,6 +672,9 @@ struct file *open_exec(const char *name) if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) goto out_path_put; + if (nd.path.mnt->mnt_flags & MNT_NOEXEC) + goto out_path_put; + err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN); if (err) goto out_path_put; -- cgit v1.2.2 From 964bd183624c03680796b63b4ab97ee3905a806a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 26 Jul 2008 03:33:14 -0400 Subject: [PATCH] get rid of __user_path_lookup_open Signed-off-by: Al Viro --- fs/exec.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'fs/exec.c') diff --git a/fs/exec.c b/fs/exec.c index eca58c29eded..9696bbf0f0b1 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -106,11 +106,17 @@ static inline void put_binfmt(struct linux_binfmt * fmt) */ asmlinkage long sys_uselib(const char __user * library) { - struct file * file; + struct file *file; struct nameidata nd; - int error; - - error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC); + char *tmp = getname(library); + int error = PTR_ERR(tmp); + + if (!IS_ERR(tmp)) { + error = path_lookup_open(AT_FDCWD, tmp, + LOOKUP_FOLLOW, &nd, + FMODE_READ|FMODE_EXEC); + putname(tmp); + } if (error) goto out; -- cgit v1.2.2