From: ebiederm@xmission.com (Eric W. Biederman)
To: Andrew Morton <akpm@osdl.org>
Cc: Mike Galbraith <efault@gmx.de>,
Nick Piggin <nickpiggin@yahoo.com.au>,
laurent.riffard@free.fr, jesper.juhl@gmail.com,
linux-kernel@vger.kernel.org, rjw@sisk.pl, mbligh@mbligh.org,
clameter@engr.sgi.com, Paul Jackson <pj@sgi.com>
Subject: [PATCH] proc: Use sane permission checks on the /proc/<pid>/fd/ symlinks.
Date: Thu, 02 Mar 2006 09:37:34 -0700 [thread overview]
Message-ID: <m1u0agkdkh.fsf_-_@ebiederm.dsl.xmission.com> (raw)
In-Reply-To: <20060301121218.68fb3f76.akpm@osdl.org> (Andrew Morton's message of "Wed, 1 Mar 2006 12:12:18 -0800")
Since 2.2 we have been doing a chroot check to see if it is appropriate
to return a read or follow one of these magic symlinks. The chroot
check was asking a question about the visibility of files to the
calling process and it was actually checking the destination process,
and not the files themselves. That test was clearly bogus.
In my first pass through I simply fixed the test to check the visibility
of the files themselves. That naive approach to fixing the permissions
was too strict and resulted in cases where a task could not even see
all of it's file descriptors.
What has disturbed me about relaxing this check is that file descriptors are
per-process private things, and they are occasionaly used a user space
capability tokens. Looking a little farther into the symlink path on
/proc I did find userid checks and a check for capability (CAP_DAC_OVERRIDE)
so there were permissions checking this.
But I was still concerned about privacy. Besides /proc there is only one
other way to find out this kind of information, and that is ptrace. ptrace
has been around for a long time and it has a well established security
model.
So after thinking about it I finally realized that the permission checks
that make sense are the permission checks applied to ptrace_attach.
The checks are simple per process, and won't cause nasty surprises for
people coming from less capable unices.
Unfortunately there is one case that the current ptrace_attach test
does not cover: Zombies and kernel threads. Single stepping those
kinds of processes is impossible. Being able to see which file
descriptors are open on these tasks is important to lsof, fuser and
friends. So for these special processes I made the rule you can't
find out unless you have CAP_SYS_PTRACE.
These proc permission checks should now conform to the principle of
least surprise. As well as using much less code to implement :)
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
fs/proc/base.c | 123 ++++++++++++--------------------------------------------
1 files changed, 27 insertions(+), 96 deletions(-)
64ea648d12af9f8bc0556ec118b27fbfcbe17722
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 6a26847..d9be807 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -508,44 +508,33 @@ static int proc_oom_score(struct task_st
/************************************************************************/
/* permission checks */
-
-/* If the process being read is separated by chroot from the reading process,
- * don't let the reader access the threads.
- */
-static int proc_check_chroot(struct dentry *de, struct vfsmount *mnt)
+static int proc_fd_access_allowed(struct inode *inode)
{
- struct dentry *base;
- struct vfsmount *our_vfsmnt;
- int res = 0;
-
- read_lock(¤t->fs->lock);
- our_vfsmnt = mntget(current->fs->rootmnt);
- base = dget(current->fs->root);
- read_unlock(¤t->fs->lock);
-
- spin_lock(&vfsmount_lock);
-
- while (mnt != our_vfsmnt) {
- if (mnt == mnt->mnt_parent)
- goto out;
- de = mnt->mnt_mountpoint;
- mnt = mnt->mnt_parent;
+ 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.
+ */
+ task = get_proc_task(inode);
+ if (task) {
+ 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 (!is_subdir(de, base))
- goto out;
- spin_unlock(&vfsmount_lock);
-
-exit:
- dput(base);
- mntput(our_vfsmnt);
- return res;
-out:
- spin_unlock(&vfsmount_lock);
- res = -EACCES;
- goto exit;
+ put_task_struct(task);
+ return allowed;
}
+
extern struct seq_operations mounts_op;
struct proc_mounts {
struct seq_file m;
@@ -1001,52 +990,6 @@ static struct file_operations proc_secco
};
#endif /* CONFIG_SECCOMP */
-static int proc_check_dentry_visible(struct inode *inode,
- struct dentry *dentry, struct vfsmount *mnt)
-{
- /* Verify that the current process can already see the
- * file pointed at by the file descriptor.
- * This prevents /proc from being an accidental information leak.
- *
- * This prevents access to files that are not visible do to
- * being on the otherside of a chroot, in a different
- * namespace, or are simply process local (like pipes).
- */
- struct task_struct *task;
- int error = -EACCES;
-
- /* See if the the two tasks share a commone set of
- * file descriptors. If so everything is visible.
- */
- 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;
- }
- rcu_read_unlock();
- if (!error)
- goto out;
-
- /* If the two tasks don't share a common set of file
- * descriptors see if the destination dentry is already
- * visible in the current tasks filesystem namespace.
- */
- error = proc_check_chroot(dentry, mnt);
-out:
- return error;
-
-}
-
static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct inode *inode = dentry->d_inode;
@@ -1055,18 +998,12 @@ static void *proc_pid_follow_link(struct
/* We don't need a base pointer in the /proc filesystem */
path_release(nd);
- if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
+ /* Are we allowed to snoop on the tasks file descriptors? */
+ if (!proc_fd_access_allowed(inode))
goto out;
error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt);
nd->last_type = LAST_BIND;
- if (error)
- goto out;
-
- /* Only return files this task can already see */
- error = proc_check_dentry_visible(inode, nd->dentry, nd->mnt);
- if (error)
- path_release(nd);
out:
return ERR_PTR(error);
}
@@ -1104,21 +1041,15 @@ static int proc_pid_readlink(struct dent
struct dentry *de;
struct vfsmount *mnt = NULL;
-
- if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE))
+ /* Are we allowed to snoop on the tasks file descriptors? */
+ if (!proc_fd_access_allowed(inode))
goto out;
error = PROC_I(inode)->op.proc_get_link(inode, &de, &mnt);
if (error)
goto out;
- /* Only return files this task can already see */
- error = proc_check_dentry_visible(inode, de, mnt);
- if (error)
- goto out_put;
-
error = do_proc_readlink(de, mnt, buffer, buflen);
-out_put:
dput(de);
mntput(mnt);
out:
--
1.2.2.g709a-dirty
next prev parent reply other threads:[~2006-03-02 16:39 UTC|newest]
Thread overview: 76+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-02-28 12:24 2.6.16-rc5-mm1 Andrew Morton
2006-02-28 14:41 ` 2.6.16-rc5-mm1 Cornelia Huck
2006-02-28 14:55 ` 2.6.16-rc5-mm1 Martin Schwidefsky
2006-02-28 15:08 ` 2.6.16-rc5-mm1 gsmith
2006-02-28 15:01 ` 2.6.16-rc5-mm1 Michal Piotrowski
2006-02-28 16:20 ` 2.6.16-rc5-mm1 Michal Piotrowski
2006-03-01 2:16 ` 2.6.16-rc5-mm1 Nick Piggin
2006-03-01 2:44 ` 2.6.16-rc5-mm1 Andrew Morton
2006-03-01 3:10 ` 2.6.16-rc5-mm1 Nick Piggin
2006-03-01 3:21 ` 2.6.16-rc5-mm1 Andrew Morton
2006-03-01 3:30 ` 2.6.16-rc5-mm1 Nick Piggin
2006-03-01 3:42 ` 2.6.16-rc5-mm1 Andrew Morton
2006-02-28 19:40 ` usb usb5: Manufacturer: Linux 2.6.16-rc5-mm1 ehci_hcd Alexey Dobriyan
2006-02-28 20:48 ` [linux-usb-devel] " Alan Stern
2006-02-28 20:48 ` 2.6.16-rc5-mm1 Mattia Dongili
2006-02-28 23:49 ` 2.6.16-rc5-mm1 Alessandro Zummo
2006-02-28 21:13 ` 2.6.16-rc5-mm1 Jesper Juhl
2006-02-28 22:27 ` 2.6.16-rc5-mm1 Jiri Slaby
2006-02-28 22:30 ` 2.6.16-rc5-mm1 Jesper Juhl
2006-02-28 23:18 ` 2.6.16-rc5-mm1 Laurent Riffard
2006-02-28 23:57 ` 2.6.16-rc5-mm1 Jesper Juhl
2006-03-01 0:21 ` 2.6.16-rc5-mm1 Andrew Morton
2006-03-01 0:33 ` 2.6.16-rc5-mm1 Jesper Juhl
2006-03-01 3:05 ` 2.6.16-rc5-mm1 Paul Jackson
2006-03-01 3:20 ` 2.6.16-rc5-mm1 Paul Jackson
2006-03-01 4:15 ` 2.6.16-rc5-mm1 Eric W. Biederman
2006-03-01 4:26 ` 2.6.16-rc5-mm1 Paul Jackson
2006-03-01 4:57 ` 2.6.16-rc5-mm1 Eric W. Biederman
2006-03-01 10:06 ` 2.6.16-rc5-mm1 Laurent Riffard
2006-03-01 10:32 ` 2.6.16-rc5-mm1 Andrew Morton
2006-03-01 11:25 ` 2.6.16-rc5-mm1 Andrew Morton
2006-03-01 18:14 ` 2.6.16-rc5-mm1 Ashok Raj
2006-03-01 18:48 ` 2.6.16-rc5-mm1 Andrew Morton
2006-03-01 19:31 ` 2.6.16-rc5-mm1 Ashok Raj
2006-03-01 13:58 ` 2.6.16-rc5-mm1 Mike Galbraith
2006-03-01 14:50 ` 2.6.16-rc5-mm1 Laurent Riffard
2006-03-01 15:33 ` 2.6.16-rc5-mm1 Mike Galbraith
2006-03-01 20:12 ` 2.6.16-rc5-mm1 Andrew Morton
2006-03-01 20:19 ` 2.6.16-rc5-mm1 Andrew Morton
2006-03-01 20:35 ` 2.6.16-rc5-mm1 Peter Staubach
2006-03-01 20:43 ` 2.6.16-rc5-mm1 Eric W. Biederman
2006-03-02 4:52 ` 2.6.16-rc5-mm1 Nick Piggin
2006-03-02 16:37 ` Eric W. Biederman [this message]
2006-03-03 8:49 ` [PATCH] proc: Use sane permission checks on the /proc/<pid>/fd/ symlinks Andrew Morton
2006-03-03 12:00 ` Eric W. Biederman
2006-03-01 14:22 ` 2.6.16-rc5-mm1 J.A. Magallon
2006-03-02 4:51 ` 2.6.16-rc5-mm1 Andrew Morton
2006-03-02 21:11 ` 2.6.16-rc5-mm1 J.A. Magallon
2006-03-02 22:31 ` 2.6.16-rc5-mm1 Andrew Morton
2006-03-02 3:10 ` 2.6.16-rc5-mm1 Paul Jackson
2006-03-01 10:35 ` 2.6.16-rc5-mm1 Laurent Riffard
2006-03-01 10:47 ` 2.6.16-rc5-mm1 Andrew Morton
2006-03-02 1:41 ` 2.6.16-rc5-mm1 Jesper Juhl
2006-03-02 20:16 ` 2.6.16-rc5-mm1 Jesper Juhl
2006-03-02 22:34 ` 2.6.16-rc5-mm1 Eric W. Biederman
2006-03-06 0:05 ` 2.6.16-rc5-mm1 Jesper Juhl
2006-02-28 23:15 ` 2.6.16-rc5-mm1 Andrew Morton
2006-02-28 23:33 ` 2.6.16-rc5-mm1 Jesper Juhl
2006-02-28 22:34 ` 2.6.16-rc5-mm1 Rafael J. Wysocki
2006-02-28 23:48 ` 2.6.16-rc5-mm1 Andrew Morton
2006-03-01 0:52 ` 2.6.16-rc5-mm1 Eric W. Biederman
2006-03-01 11:42 ` 2.6.16-rc5-mm1 Rafael J. Wysocki
2006-02-28 23:56 ` 2.6.16-rc5-mm1 Martin Bligh
2006-03-01 16:45 ` [PATCH] Fix powerpc bad_page_fault output (Re: 2.6.16-rc5-mm1) Olof Johansson
2006-03-02 0:09 ` Paul E. McKenney
2006-03-02 0:35 ` Paul Mackerras
2006-03-02 1:14 ` Martin Bligh
2006-03-02 2:22 ` Olof Johansson
2006-03-02 5:24 ` Anton Blanchard
2006-03-02 5:16 ` Paul Mackerras
2006-03-02 10:27 ` 2.6.16-rc5-mm1 -- strange load balancing problems Peter Williams
2006-03-02 22:23 ` Peter Williams
2006-03-13 4:46 ` Peter Williams
2006-03-03 15:32 ` 2.6.16-rc5-mm1: USB compile errors Adrian Bunk
2006-03-02 21:38 [PATCH] proc: Use sane permission checks on the /proc/<pid>/fd/ symlinks Sam Vilain
2006-03-02 23:18 ` Eric W. Biederman
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=m1u0agkdkh.fsf_-_@ebiederm.dsl.xmission.com \
--to=ebiederm@xmission.com \
--cc=akpm@osdl.org \
--cc=clameter@engr.sgi.com \
--cc=efault@gmx.de \
--cc=jesper.juhl@gmail.com \
--cc=laurent.riffard@free.fr \
--cc=linux-kernel@vger.kernel.org \
--cc=mbligh@mbligh.org \
--cc=nickpiggin@yahoo.com.au \
--cc=pj@sgi.com \
--cc=rjw@sisk.pl \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome