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

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

[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
Loading
Loading
Loading
Loading
+16 −13
Original line number Diff line number Diff line
@@ -1074,24 +1074,27 @@ static int proc_check_dentry_visible(struct inode *inode,
	 * namespace, or are simply process local (like pipes).
	 */
	struct task_struct *task;
	struct files_struct *task_files, *files;
	int error = -EACCES;

	/* See if the the two tasks share a commone set of
	 * file descriptors.  If so everything is visible.
	 */
	task = get_proc_task(inode);
	if (!task)
		goto out;
	files = get_files_struct(current);
	task_files = get_files_struct(task);
	if (files && task_files && (files == task_files))
	rcu_read_lock();
	task = tref_task(proc_tref(inode));
	if (task) {
		struct files_struct *task_files, *files;
		/* This test answeres the question:
		 * 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;
	if (task_files)
		put_files_struct(task_files);
	if (files)
		put_files_struct(files);
	put_task_struct(task);
	}
	rcu_read_unlock();
	if (!error)
		goto out;