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

Commit ba6bed10 authored by Al Viro's avatar Al Viro Committed by TARKZiM
Browse files

allow build_open_flags() to return an error



Change-Id: I6e900fc3facf5a3febefe138fea7db493bc383d8
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent ec26fc60
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -110,13 +110,14 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
	static const struct open_flags uselib_flags = {
		.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
		.acc_mode = MAY_READ | MAY_EXEC | MAY_OPEN,
		.intent = LOOKUP_OPEN
		.intent = LOOKUP_OPEN,
		.lookup_flags = LOOKUP_FOLLOW,
	};

	if (IS_ERR(tmp))
		goto out;

	file = do_filp_open(AT_FDCWD, tmp, &uselib_flags, LOOKUP_FOLLOW);
	file = do_filp_open(AT_FDCWD, tmp, &uselib_flags);
	putname(tmp);
	error = PTR_ERR(file);
	if (IS_ERR(file))
@@ -776,10 +777,11 @@ struct file *open_exec(const char *name)
	static const struct open_flags open_exec_flags = {
		.open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
		.acc_mode = MAY_EXEC | MAY_OPEN,
		.intent = LOOKUP_OPEN
		.intent = LOOKUP_OPEN,
		.lookup_flags = LOOKUP_FOLLOW,
	};

	file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags, LOOKUP_FOLLOW);
	file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags);
	if (IS_ERR(file))
		goto out;

+3 −2
Original line number Diff line number Diff line
@@ -95,11 +95,12 @@ struct open_flags {
	umode_t mode;
	int acc_mode;
	int intent;
	int lookup_flags;
};
extern struct file *do_filp_open(int dfd, struct filename *pathname,
		const struct open_flags *op, int flags);
		const struct open_flags *op);
extern struct file *do_file_open_root(struct dentry *, struct vfsmount *,
		const char *, const struct open_flags *, int lookup_flags);
		const char *, const struct open_flags *);

extern long do_handle_open(int mountdirfd,
			   struct file_handle __user *ufh, int open_flag);
+4 −4
Original line number Diff line number Diff line
@@ -3023,9 +3023,10 @@ out:
}

struct file *do_filp_open(int dfd, struct filename *pathname,
		const struct open_flags *op, int flags)
		const struct open_flags *op)
{
	struct nameidata nd;
	int flags = op->lookup_flags;
	struct file *filp;

	filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU);
@@ -3037,17 +3038,16 @@ struct file *do_filp_open(int dfd, struct filename *pathname,
}

struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
		const char *name, const struct open_flags *op, int flags)
		const char *name, const struct open_flags *op)
{
	struct nameidata nd;
	struct file *file;
	struct filename filename = { .name = name };
	int flags = op->lookup_flags | LOOKUP_ROOT;

	nd.root.mnt = mnt;
	nd.root.dentry = dentry;

	flags |= LOOKUP_ROOT;

	if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN)
		return ERR_PTR(-ELOOP);

+27 −21
Original line number Diff line number Diff line
@@ -879,7 +879,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
		lookup_flags |= LOOKUP_DIRECTORY;
	if (!(flags & O_NOFOLLOW))
		lookup_flags |= LOOKUP_FOLLOW;
	return lookup_flags;
	op->lookup_flags = lookup_flags;
	return 0;
}

/**
@@ -896,8 +897,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o
struct file *file_open_name(struct filename *name, int flags, umode_t mode)
{
	struct open_flags op;
	int lookup = build_open_flags(flags, mode, &op);
	return do_filp_open(AT_FDCWD, name, &op, lookup);
	int err = build_open_flags(flags, mode, &op);
	return err ? ERR_PTR(err) : do_filp_open(AT_FDCWD, name, &op);
}

/**
@@ -922,27 +923,34 @@ struct file *file_open_root(struct dentry *dentry, struct vfsmount *mnt,
			    const char *filename, int flags)
{
	struct open_flags op;
	int lookup = build_open_flags(flags, 0, &op);
	int err = build_open_flags(flags, 0, &op);
	if (err)
		return ERR_PTR(err);
	if (flags & O_CREAT)
		return ERR_PTR(-EINVAL);
	if (!filename && (flags & O_DIRECTORY))
		if (!dentry->d_inode->i_op->lookup)
			return ERR_PTR(-ENOTDIR);
	return do_file_open_root(dentry, mnt, filename, &op, lookup);
	return do_file_open_root(dentry, mnt, filename, &op);
}
EXPORT_SYMBOL(file_open_root);

long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
	struct open_flags op;
	int lookup = build_open_flags(flags, mode, &op);
	struct filename *tmp = getname(filename);
	int fd = PTR_ERR(tmp);
	int fd = build_open_flags(flags, mode, &op);
	struct filename *tmp;

	if (fd)
		return fd;

	tmp = getname(filename);
	if (IS_ERR(tmp))
		return PTR_ERR(tmp);

	if (!IS_ERR(tmp)) {
	fd = get_unused_fd_flags(flags);
	if (fd >= 0) {
			struct file *f = do_filp_open(dfd, tmp, &op, lookup);
		struct file *f = do_filp_open(dfd, tmp, &op);
		if (IS_ERR(f)) {
			put_unused_fd(fd);
			fd = PTR_ERR(f);
@@ -951,8 +959,6 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
			fd_install(fd, f);
		}
	}
		putname(tmp);
	}
	return fd;
}