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

Commit bc77daa7 authored by Al Viro's avatar Al Viro
Browse files

do_last(): fix missing checks for LAST_BIND case



/proc/self/cwd with O_CREAT should fail with EISDIR.  /proc/self/exe, OTOH,
should fail with ENOTDIR when opened with O_DIRECTORY.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 0888c321
Loading
Loading
Loading
Loading
+3 −21
Original line number Diff line number Diff line
@@ -2690,28 +2690,10 @@ static int do_last(struct nameidata *nd, struct path *path,
	nd->flags &= ~LOOKUP_PARENT;
	nd->flags |= op->intent;

	switch (nd->last_type) {
	case LAST_DOTDOT:
	case LAST_DOT:
	if (nd->last_type != LAST_NORM) {
		error = handle_dots(nd, nd->last_type);
		if (error)
			return error;
		/* fallthrough */
	case LAST_ROOT:
		error = complete_walk(nd);
		if (error)
			return error;
		audit_inode(name, nd->path.dentry, 0);
		if (open_flag & O_CREAT) {
			error = -EISDIR;
			goto out;
		}
		goto finish_open;
	case LAST_BIND:
		error = complete_walk(nd);
		if (error)
			return error;
		audit_inode(name, dir, 0);
		goto finish_open;
	}

@@ -2841,19 +2823,19 @@ static int do_last(struct nameidata *nd, struct path *path,
	}
	nd->inode = inode;
	/* Why this, you ask?  _Now_ we might have grown LOOKUP_JUMPED... */
finish_open:
	error = complete_walk(nd);
	if (error) {
		path_put(&save_parent);
		return error;
	}
	audit_inode(name, nd->path.dentry, 0);
	error = -EISDIR;
	if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode))
		goto out;
	error = -ENOTDIR;
	if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode))
		goto out;
	audit_inode(name, nd->path.dentry, 0);
finish_open:
	if (!S_ISREG(nd->inode->i_mode))
		will_truncate = false;