Commit 1bc82070 authored by Aleksa Sarai's avatar Aleksa Sarai Committed by Al Viro
Browse files

namei: allow nd_jump_link() to produce errors



In preparation for LOOKUP_NO_MAGICLINKS, it's necessary to add the
ability for nd_jump_link() to return an error which the corresponding
get_link() caller must propogate back up to the VFS.

Suggested-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarAleksa Sarai <cyphar@cyphar.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent ce623f89
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -859,7 +859,7 @@ static int nd_jump_root(struct nameidata *nd)
 * Helper to directly jump to a known parsed path from ->get_link,
 * caller must have taken a reference to path beforehand.
 */
void nd_jump_link(struct path *path)
int nd_jump_link(struct path *path)
{
	struct nameidata *nd = current->nameidata;
	path_put(&nd->path);
@@ -867,6 +867,7 @@ void nd_jump_link(struct path *path)
	nd->path = *path;
	nd->inode = nd->path.dentry->d_inode;
	nd->flags |= LOOKUP_JUMPED;
	return 0;
}

static inline void put_link(struct nameidata *nd)
+1 −2
Original line number Diff line number Diff line
@@ -1626,8 +1626,7 @@ static const char *proc_pid_get_link(struct dentry *dentry,
	if (error)
		goto out;

	nd_jump_link(&path);
	return NULL;
	error = nd_jump_link(&path);
out:
	return ERR_PTR(error);
}
+9 −5
Original line number Diff line number Diff line
@@ -51,11 +51,15 @@ static const char *proc_ns_get_link(struct dentry *dentry,
	if (!task)
		return ERR_PTR(-EACCES);

	if (ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
		goto out;

	error = ns_get_path(&ns_path, task, ns_ops);
		if (!error)
			nd_jump_link(&ns_path);
	}
	if (error)
		goto out;

	error = nd_jump_link(&ns_path);
out:
	put_task_struct(task);
	return ERR_PTR(error);
}
+1 −1
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ extern int follow_up(struct path *);
extern struct dentry *lock_rename(struct dentry *, struct dentry *);
extern void unlock_rename(struct dentry *, struct dentry *);

extern void nd_jump_link(struct path *path);
extern int __must_check nd_jump_link(struct path *path);

static inline void nd_terminate_link(void *name, size_t len, size_t maxlen)
{
+4 −2
Original line number Diff line number Diff line
@@ -2573,16 +2573,18 @@ static const char *policy_get_link(struct dentry *dentry,
{
	struct aa_ns *ns;
	struct path path;
	int error;

	if (!dentry)
		return ERR_PTR(-ECHILD);

	ns = aa_get_current_ns();
	path.mnt = mntget(aafs_mnt);
	path.dentry = dget(ns_dir(ns));
	nd_jump_link(&path);
	error = nd_jump_link(&path);
	aa_put_ns(ns);

	return NULL;
	return ERR_PTR(error);
}

static int policy_readlink(struct dentry *dentry, char __user *buffer,