aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-06-26 03:25:59 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:26 -0400
commitdf26c40e567356caeefe2861311e19c54444d917 (patch)
tree415527677e85e8b612b916f6fda1645a6207d8e2
parent778c1144771f0064b6f51bee865cceb0d996f2f9 (diff)
[PATCH] proc: Cleanup proc_fd_access_allowed
In process of getting proc_fd_access_allowed to work it has developed a few warts. In particular the special case that always allows introspection and the special case to allow inspection of kernel threads. The special case for introspection is needed for /proc/self/mem. The special case for kernel threads really should be overridable by security modules. So consolidate these checks into ptrace.c:may_attach(). The check to always allow introspection is trivial. The check to allow access to kernel threads, and zombies is a little trickier. mem_read and mem_write already verify an mm exists so it isn't needed twice. proc_fd_access_allowed only doesn't want a check to verify task->mm exits, s it prevents all access to kernel threads. So just move the task->mm check into ptrace_attach where it is needed for practical reasons. I did a quick audit and none of the security modules in the kernel seem to care if they are passed a task without an mm into security_ptrace. So the above move should be safe and it allows security modules to come up with more restrictive policy. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Cc: Stephen Smalley <sds@tycho.nsa.gov> Cc: Chris Wright <chrisw@sous-sol.org> Cc: James Morris <jmorris@namei.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--fs/proc/base.c26
-rw-r--r--kernel/ptrace.c20
2 files changed, 23 insertions, 23 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index f38da6bda269..773469703c62 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -536,29 +536,15 @@ static int proc_fd_access_allowed(struct inode *inode)
536{ 536{
537 struct task_struct *task; 537 struct task_struct *task;
538 int allowed = 0; 538 int allowed = 0;
539 /* Allow access to a task's file descriptors if either we may 539 /* Allow access to a task's file descriptors if it is us or we
540 * use ptrace attach to the process and find out that 540 * may use ptrace attach to the process and find out that
541 * information, or if the task cannot possibly be ptraced 541 * information.
542 * allow access if we have the proper capability.
543 */ 542 */
544 task = get_proc_task(inode); 543 task = get_proc_task(inode);
545 if (task == current) 544 if (task) {
546 allowed = 1; 545 allowed = ptrace_may_attach(task);
547 if (task && !allowed) {
548 int alive;
549
550 task_lock(task);
551 alive = !!task->mm;
552 task_unlock(task);
553 if (alive)
554 /* For a living task obey ptrace_may_attach */
555 allowed = ptrace_may_attach(task);
556 else
557 /* For a special task simply check the capability */
558 allowed = capable(CAP_SYS_PTRACE);
559 }
560 if (task)
561 put_task_struct(task); 546 put_task_struct(task);
547 }
562 return allowed; 548 return allowed;
563} 549}
564 550
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 921c22ad16e4..6252d2fa2bf3 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -120,8 +120,18 @@ int ptrace_check_attach(struct task_struct *child, int kill)
120 120
121static int may_attach(struct task_struct *task) 121static int may_attach(struct task_struct *task)
122{ 122{
123 if (!task->mm) 123 /* May we inspect the given task?
124 return -EPERM; 124 * This check is used both for attaching with ptrace
125 * and for allowing access to sensitive information in /proc.
126 *
127 * ptrace_attach denies several cases that /proc allows
128 * because setting up the necessary parent/child relationship
129 * or halting the specified task is impossible.
130 */
131 int dumpable = 0;
132 /* Don't let security modules deny introspection */
133 if (task == current)
134 return 0;
125 if (((current->uid != task->euid) || 135 if (((current->uid != task->euid) ||
126 (current->uid != task->suid) || 136 (current->uid != task->suid) ||
127 (current->uid != task->uid) || 137 (current->uid != task->uid) ||
@@ -130,7 +140,9 @@ static int may_attach(struct task_struct *task)
130 (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE)) 140 (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
131 return -EPERM; 141 return -EPERM;
132 smp_rmb(); 142 smp_rmb();
133 if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE)) 143 if (task->mm)
144 dumpable = task->mm->dumpable;
145 if (!dumpable && !capable(CAP_SYS_PTRACE))
134 return -EPERM; 146 return -EPERM;
135 147
136 return security_ptrace(current, task); 148 return security_ptrace(current, task);
@@ -176,6 +188,8 @@ repeat:
176 goto repeat; 188 goto repeat;
177 } 189 }
178 190
191 if (!task->mm)
192 goto bad;
179 /* the same process cannot be attached many times */ 193 /* the same process cannot be attached many times */
180 if (task->ptrace & PT_PTRACED) 194 if (task->ptrace & PT_PTRACED)
181 goto bad; 195 goto bad;