[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 <[email protected]>
Cc: Stephen Smalley <[email protected]>
Cc: Chris Wright <[email protected]>
Cc: James Morris <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
Eric W. Biederman 2006-06-26 00:25:59 -07:00 • committed by Linus Torvalds
commit df26c40e56
2 changed files with 23 additions and 23 deletions

View file

@ -536,29 +536,15 @@ 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 either we may
* use ptrace attach to the process and find out that
* information, or if the task cannot possibly be ptraced
* allow access if we have the proper capability.
/* 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 == current)
allowed = 1;
if (task && !allowed) {
int alive;
task_lock(task);
alive = !!task->mm;
task_unlock(task);
if (alive)
/* For a living task obey ptrace_may_attach */
allowed = ptrace_may_attach(task);
else
/* For a special task simply check the capability */
allowed = capable(CAP_SYS_PTRACE);
}
if (task)
if (task) {
allowed = ptrace_may_attach(task);
put_task_struct(task);
}
return allowed;
}