Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e8341a1 authored by Al Viro's avatar Al Viro
Browse files

Switch open_exec() and sys_uselib() to do_open_filp()



... and make path_lookup_open() static

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent a44ddbb6
Loading
Loading
Loading
Loading
+25 −47
Original line number Diff line number Diff line
@@ -105,36 +105,28 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
SYSCALL_DEFINE1(uselib, const char __user *, library)
{
	struct file *file;
	struct nameidata nd;
	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);
	if (IS_ERR(tmp))
		goto out;

	file = do_filp_open(AT_FDCWD, tmp,
				O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
				MAY_READ | MAY_EXEC | MAY_OPEN);
	putname(tmp);
	}
	if (error)
	error = PTR_ERR(file);
	if (IS_ERR(file))
		goto out;

	error = -EINVAL;
	if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
	if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
		goto exit;

	error = -EACCES;
	if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
		goto exit;

	error = may_open(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN, 0);
	if (error)
	if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
		goto exit;

	file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
	error = PTR_ERR(file);
	if (IS_ERR(file))
		goto out;

	fsnotify_open(file->f_path.dentry);

	error = -ENOEXEC;
@@ -156,13 +148,10 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
		}
		read_unlock(&binfmt_lock);
	}
exit:
	fput(file);
out:
  	return error;
exit:
	release_open_intent(&nd);
	path_put(&nd.path);
	goto out;
}

#ifdef CONFIG_MMU
@@ -657,44 +646,33 @@ EXPORT_SYMBOL(setup_arg_pages);

struct file *open_exec(const char *name)
{
	struct nameidata nd;
	struct file *file;
	int err;

	err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd,
				FMODE_READ|FMODE_EXEC);
	if (err)
	file = do_filp_open(AT_FDCWD, name,
				O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
				MAY_EXEC | MAY_OPEN);
	if (IS_ERR(file))
		goto out;

	err = -EACCES;
	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 = may_open(&nd.path, MAY_EXEC | MAY_OPEN, 0);
	if (err)
		goto out_path_put;
	if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
		goto exit;

	file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
	if (IS_ERR(file))
		return file;
	if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
		goto exit;

	fsnotify_open(file->f_path.dentry);

	err = deny_write_access(file);
	if (err) {
		fput(file);
		goto out;
	}
	if (err)
		goto exit;

out:
	return file;

 out_path_put:
	release_open_intent(&nd);
	path_put(&nd.path);
 out:
exit:
	fput(file);
	return ERR_PTR(err);
}
EXPORT_SYMBOL(open_exec);
+7 −6
Original line number Diff line number Diff line
@@ -1130,8 +1130,8 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
 * @nd: pointer to nameidata
 * @open_flags: open intent flags
 */
int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
		struct nameidata *nd, int open_flags)
static int path_lookup_open(int dfd, const char *name,
		unsigned int lookup_flags, struct nameidata *nd, int open_flags)
{
	struct file *filp = get_empty_filp();
	int err;
@@ -1637,17 +1637,18 @@ static int open_will_write_to_fs(int flag, struct inode *inode)
 * open_to_namei_flags() for more details.
 */
struct file *do_filp_open(int dfd, const char *pathname,
		int open_flag, int mode)
		int open_flag, int mode, int acc_mode)
{
	struct file *filp;
	struct nameidata nd;
	int acc_mode, error;
	int error;
	struct path path;
	struct dentry *dir;
	int count = 0;
	int will_write;
	int flag = open_to_namei_flags(open_flag);

	if (!acc_mode)
		acc_mode = MAY_OPEN | ACC_MODE(flag);

	/* O_TRUNC implies we need access checks for write permissions */
@@ -1869,7 +1870,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
 */
struct file *filp_open(const char *filename, int flags, int mode)
{
	return do_filp_open(AT_FDCWD, filename, flags, mode);
	return do_filp_open(AT_FDCWD, filename, flags, mode, 0);
}
EXPORT_SYMBOL(filp_open);

+1 −1
Original line number Diff line number Diff line
@@ -1033,7 +1033,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
	if (!IS_ERR(tmp)) {
		fd = get_unused_fd_flags(flags);
		if (fd >= 0) {
			struct file *f = do_filp_open(dfd, tmp, flags, mode);
			struct file *f = do_filp_open(dfd, tmp, flags, mode, 0);
			if (IS_ERR(f)) {
				put_unused_fd(fd);
				fd = PTR_ERR(f);
+1 −1
Original line number Diff line number Diff line
@@ -2118,7 +2118,7 @@ extern struct file *create_write_pipe(int flags);
extern void free_write_pipe(struct file *);

extern struct file *do_filp_open(int dfd, const char *pathname,
		int open_flag, int mode);
		int open_flag, int mode, int acc_mode);
extern int may_open(struct path *, int, int);

extern int kernel_read(struct file *, unsigned long, char *, unsigned long);
+0 −1
Original line number Diff line number Diff line
@@ -69,7 +69,6 @@ extern int path_lookup(const char *, unsigned, struct nameidata *);
extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
			   const char *, unsigned int, struct nameidata *);

extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags);
extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
		int (*open)(struct inode *, struct file *));
extern struct file *nameidata_to_filp(struct nameidata *nd, int flags);