All of lore.kernel.org
 help / color / mirror / Atom feed
From: Cong Wang <xiyou.wangcong@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Cong Wang <xiyou.wangcong@gmail.com>,
	Oleg Nesterov <oleg@redhat.com>,
	Alexey Dobriyan <adobriyan@gmail.com>,
	Al Viro <viro@zeniv.linux.org.uk>,
	Vasiliy Kulikov <segoon@openwall.com>,
	David Rientjes <rientjes@google.com>
Subject: [PATCH 5/6] proc: use task_access_lock() instead of ptrace_may_access()
Date: Wed, 11 Apr 2012 13:59:26 +0800	[thread overview]
Message-ID: <1334123976-11681-5-git-send-email-xiyou.wangcong@gmail.com> (raw)
In-Reply-To: <1334123976-11681-1-git-send-email-xiyou.wangcong@gmail.com>

There are several places in fs/proc/base.c still use ptrace_may_access()
directly to check the permission, actually this just gets a snapshot of
the permission, nothing prevents the target task from raising the priviledges
itself, it is better to use task_access_lock() for these places, to hold
the priviledges.

Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
---
 fs/proc/base.c |   74 +++++++++++++++++++++++++-------------------------------
 1 files changed, 33 insertions(+), 41 deletions(-)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index f1d18fc..2dff86b 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -253,6 +253,23 @@ static int proc_pid_auxv(struct task_struct *task, char *buffer)
 	return res;
 }
 
+static int task_access_lock(struct task_struct *task, unsigned int mode)
+
+{
+	int err = mutex_lock_killable(&task->signal->cred_guard_mutex);
+	if (err)
+		return err;
+	if (!ptrace_may_access(task, mode)) {
+		mutex_unlock(&task->signal->cred_guard_mutex);
+		return -EPERM;
+	}
+	return 0;
+}
+
+static void task_access_unlock(struct task_struct *task)
+{
+	mutex_unlock(&task->signal->cred_guard_mutex);
+}
 
 #ifdef CONFIG_KALLSYMS
 /*
@@ -264,35 +281,18 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer)
 	unsigned long wchan;
 	char symname[KSYM_NAME_LEN];
 
+	if (task_access_lock(task, PTRACE_MODE_READ))
+		return 0;
 	wchan = get_wchan(task);
 
+	task_access_unlock(task);
 	if (lookup_symbol_name(wchan, symname) < 0)
-		if (!ptrace_may_access(task, PTRACE_MODE_READ))
-			return 0;
-		else
-			return sprintf(buffer, "%lu", wchan);
+		return sprintf(buffer, "%lu", wchan);
 	else
 		return sprintf(buffer, "%s", symname);
 }
 #endif /* CONFIG_KALLSYMS */
 
-static int task_access_lock(struct task_struct *task, unsigned int mode)
-{
-	int err = mutex_lock_killable(&task->signal->cred_guard_mutex);
-	if (err)
-		return err;
-	if (!ptrace_may_access(task, mode)) {
-		mutex_unlock(&task->signal->cred_guard_mutex);
-		return -EPERM;
-	}
-	return 0;
-}
-
-static void task_access_unlock(struct task_struct *task)
-{
-	mutex_unlock(&task->signal->cred_guard_mutex);
-}
-
 #ifdef CONFIG_STACKTRACE
 
 #define MAX_STACK_TRACE_DEPTH	64
@@ -512,23 +512,6 @@ static int proc_pid_syscall(struct task_struct *task, char *buffer)
 /*                       Here the fs part begins                        */
 /************************************************************************/
 
-/* permission checks */
-static int proc_fd_access_allowed(struct inode *inode)
-{
-	struct task_struct *task;
-	int allowed = 0;
-	/* Allow access to a task's file descriptors if it is us or we
-	 * may use ptrace attach to the process and find out that
-	 * information.
-	 */
-	task = get_proc_task(inode);
-	if (task) {
-		allowed = ptrace_may_access(task, PTRACE_MODE_READ);
-		put_task_struct(task);
-	}
-	return allowed;
-}
-
 int proc_setattr(struct dentry *dentry, struct iattr *attr)
 {
 	int error;
@@ -1425,17 +1408,21 @@ static int proc_exe_link(struct dentry *dentry, struct path *exe_path)
 static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
 	struct inode *inode = dentry->d_inode;
+	struct task_struct *task = get_proc_task(inode);
 	int error = -EACCES;
 
 	/* We don't need a base pointer in the /proc filesystem */
 	path_put(&nd->path);
 
 	/* Are we allowed to snoop on the tasks file descriptors? */
-	if (!proc_fd_access_allowed(inode))
+	error = task_access_lock(task, PTRACE_MODE_READ);
+	if (error)
 		goto out;
 
 	error = PROC_I(inode)->op.proc_get_link(dentry, &nd->path);
+	task_access_unlock(task);
 out:
+	put_task_struct(task);
 	return ERR_PTR(error);
 }
 
@@ -1467,19 +1454,24 @@ static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int b
 {
 	int error = -EACCES;
 	struct inode *inode = dentry->d_inode;
+	struct task_struct *task = get_proc_task(inode);
 	struct path path;
 
 	/* Are we allowed to snoop on the tasks file descriptors? */
-	if (!proc_fd_access_allowed(inode))
+	error = task_access_lock(task, PTRACE_MODE_READ);
+	if (error)
 		goto out;
 
 	error = PROC_I(inode)->op.proc_get_link(dentry, &path);
 	if (error)
-		goto out;
+		goto out_unlock;
 
 	error = do_proc_readlink(&path, buffer, buflen);
 	path_put(&path);
+out_unlock:
+	task_access_unlock(task);
 out:
+	put_task_struct(task);
 	return error;
 }
 
-- 
1.7.7.6


  parent reply	other threads:[~2012-04-11  6:01 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-11  5:59 [PATCH 1/6 v3] proc: clean up /proc/<pid>/environ handling Cong Wang
2012-04-11  5:59 ` [PATCH 2/6] proc: unify ptrace_may_access locking code Cong Wang
2012-04-11  5:59 ` [PATCH 3/6] proc: remove mm_for_maps() Cong Wang
2012-04-12  0:38   ` Hugh Dickins
2012-04-11  5:59 ` [PATCH 4/6] proc: use mm_access() instead of ptrace_may_access() Cong Wang
2012-04-11  5:59 ` Cong Wang [this message]
2012-04-12 13:22   ` [PATCH 5/6] proc: use task_access_lock() " Cong Wang
2012-04-12 15:29     ` Djalal Harouni
2012-04-11  5:59 ` [PATCH 6/6] proc: use IS_ERR_OR_NULL() Cong Wang
2012-04-12  0:41   ` Hugh Dickins
2012-04-12 13:17     ` Cong Wang
2012-04-12 13:23   ` Alexey Dobriyan
2012-04-12 18:46     ` KOSAKI Motohiro
2012-04-12 19:26       ` Hugh Dickins
2012-04-12 19:31         ` Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1334123976-11681-5-git-send-email-xiyou.wangcong@gmail.com \
    --to=xiyou.wangcong@gmail.com \
    --cc=adobriyan@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleg@redhat.com \
    --cc=rientjes@google.com \
    --cc=segoon@openwall.com \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.