diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2013-03-09 03:14:45 -0500 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2013-03-09 03:14:45 -0500 |
commit | db04dc679bcc780ad6907943afe24a30de974a1b (patch) | |
tree | b90e13dc98a5217968a3035470d34744bf72d1c2 | |
parent | 9141770548d529b9d32d5b08d59b65ee65afe0d4 (diff) |
proc: Use nd_jump_link in proc_ns_follow_link
Update proc_ns_follow_link to use nd_jump_link instead of just
manually updating nd.path.dentry.
This fixes the BUG_ON(nd->inode != parent->d_inode) reported by Dave
Jones and reproduced trivially with mkdir /proc/self/ns/uts/a.
Sigh it looks like the VFS change to require use of nd_jump_link
happend while proc_ns_follow_link was baking and since the common case
of proc_ns_follow_link continued to work without problems the need for
making this change was overlooked.
Cc: stable@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
-rw-r--r-- | fs/proc/namespaces.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index b7a47196c8c3..66b51c0383da 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c | |||
@@ -118,7 +118,7 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
118 | struct super_block *sb = inode->i_sb; | 118 | struct super_block *sb = inode->i_sb; |
119 | struct proc_inode *ei = PROC_I(inode); | 119 | struct proc_inode *ei = PROC_I(inode); |
120 | struct task_struct *task; | 120 | struct task_struct *task; |
121 | struct dentry *ns_dentry; | 121 | struct path ns_path; |
122 | void *error = ERR_PTR(-EACCES); | 122 | void *error = ERR_PTR(-EACCES); |
123 | 123 | ||
124 | task = get_proc_task(inode); | 124 | task = get_proc_task(inode); |
@@ -128,14 +128,14 @@ static void *proc_ns_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
128 | if (!ptrace_may_access(task, PTRACE_MODE_READ)) | 128 | if (!ptrace_may_access(task, PTRACE_MODE_READ)) |
129 | goto out_put_task; | 129 | goto out_put_task; |
130 | 130 | ||
131 | ns_dentry = proc_ns_get_dentry(sb, task, ei->ns_ops); | 131 | ns_path.dentry = proc_ns_get_dentry(sb, task, ei->ns_ops); |
132 | if (IS_ERR(ns_dentry)) { | 132 | if (IS_ERR(ns_path.dentry)) { |
133 | error = ERR_CAST(ns_dentry); | 133 | error = ERR_CAST(ns_path.dentry); |
134 | goto out_put_task; | 134 | goto out_put_task; |
135 | } | 135 | } |
136 | 136 | ||
137 | dput(nd->path.dentry); | 137 | ns_path.mnt = mntget(nd->path.mnt); |
138 | nd->path.dentry = ns_dentry; | 138 | nd_jump_link(nd, &ns_path); |
139 | error = NULL; | 139 | error = NULL; |
140 | 140 | ||
141 | out_put_task: | 141 | out_put_task: |