Commit 5b0c1dd3 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Linus Torvalds

[PATCH] proc: optimize proc_check_dentry_visible

The code doesn't need to sleep to when making this check so I can just do the
comparison and not worry about the reference counts.

TODO: While looking at this I realized that my original cleanup did not push
the permission check far enough down into the stack.  The call of
proc_check_dentry_visible needs to move out of the generic proc
readlink/follow link code and into the individual get_link instances.
Otherwise the shared resources checks are not quite correct (shared
files_struct does not require a shared fs_struct), and there are races with
unshare.
Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 13b41b09
...@@ -1074,24 +1074,27 @@ static int proc_check_dentry_visible(struct inode *inode, ...@@ -1074,24 +1074,27 @@ static int proc_check_dentry_visible(struct inode *inode,
* namespace, or are simply process local (like pipes). * namespace, or are simply process local (like pipes).
*/ */
struct task_struct *task; struct task_struct *task;
struct files_struct *task_files, *files;
int error = -EACCES; int error = -EACCES;
/* See if the the two tasks share a commone set of /* See if the the two tasks share a commone set of
* file descriptors. If so everything is visible. * file descriptors. If so everything is visible.
*/ */
task = get_proc_task(inode); rcu_read_lock();
if (!task) task = tref_task(proc_tref(inode));
goto out; if (task) {
files = get_files_struct(current); struct files_struct *task_files, *files;
task_files = get_files_struct(task); /* This test answeres the question:
if (files && task_files && (files == task_files)) * Is there a point in time since we looked up the
* file descriptor where the two tasks share the
* same files struct?
*/
rmb();
files = current->files;
task_files = task->files;
if (files && (files == task_files))
error = 0; error = 0;
if (task_files) }
put_files_struct(task_files); rcu_read_unlock();
if (files)
put_files_struct(files);
put_task_struct(task);
if (!error) if (!error)
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment