From: David Howells <dhowells@redhat.com>
To: Linus Torvalds <torvalds@linux-foundation.org>,
Jiri Olsa <jolsa@redhat.com>
Cc: dhowells@redhat.com, Andrew Morton <akpm@linux-foundation.org>,
Eric Dumazet <eric.dumazet@gmail.com>,
linux-kernel@vger.kernel.org,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
linux-security-module@vger.kernel.org
Subject: Re: [PATCH] cred - synchronize rcu before releasing cred
Date: Wed, 28 Jul 2010 13:07:42 +0100 [thread overview]
Message-ID: <18537.1280318862@redhat.com> (raw)
In-Reply-To: <AANLkTikB9Msot4m_oaw+V+dvEg+SzyXHb0cqhKQqUtC2@mail.gmail.com>
Linus Torvalds <torvalds@linux-foundation.org> wrote:
> So it looks like the validation is simply wrong. The __task_cred()
> helper is buggy. It's used for two different cases, and they have
> totally different locking requirements.
I think part of my comment on __task_cred():
* The caller must make sure task doesn't go away, either by holding a
* ref on task or by holding tasklist_lock to prevent it from being
* unlinked.
may be obvious and perhaps unnecessary - anyone attempting to access a
task_struct should know that they need to prevent it from going away whilst
they do it - and I think this has led to Paul McKenny misunderstanding the
intent. What I was trying to convey is the destruction of the task_struct
involves discarding the credentials it points to.
Either I should insert the word 'also' into that comment after 'must' or just
get rid of it entirely.
I think I should remove lock_dep_tasklist_lock_is_held() from the stated
checks. It doesn't add anything, and someone calling __task_cred() on their
own process (perhaps indirectly) doesn't need the tasklist lock.
> Umm. In that case, get_task_cred() is actively misleading.
>
> What you are saying is that you cannot do
>
> rcu_read_lock()
> __cred = (struct cred *) __task_cred((task));
> get_cred(__cred);
> rcu_read_unlock();
Yeah. I think there are three alternatives:
(1) get_task_cred() could be done by doing { __task_cred(),
atomic_inc_not_zero() } in a loop until we manage to come up with the
goods. It probably wouldn't be all that inefficient as creds don't change
very often as a rule.
(2) Get a spinlock in commit_creds() around the point where we alter the cred
pointers.
(3) Try and get rid of get_task_cred() and use other means. I've gone through
all the users of get_task_cred() (see below) and this may be viable,
though restrictive, in places.
Any thoughts as to which is the best?
> So presumably Jiri's patch is correct, but the reason the bug happened
> in the first place is that all those accessor functions are totally
> confused about how they supposed to be used, with incorrect comments
> and incorrect access checks.
At some point in the past I think I discarded a lock from the code:-/
> That should get fixed. Who knows how many other buggy users there are
> due to the confusion?
Some.
warthog>grep get_task_cred `find . -name "*.[ch]"`
./kernel/auditsc.c: const struct cred *cred = get_task_cred(tsk);
This is audit_filter_rules() which is used by:
- audit_filter_task()
- audit_alloc() as called from copy_process() with the new process
- audit_filter_syscall()
- audit_get_context()
- audit_free() as called from copy_process() with the new, now dead process
- audit_free() as called from do_exit() with the dead process
- audit_syscall_exit() which passes current.
- audit_syscall_entry() which passes current.
- audit_filter_inodes()
- audit_update_watch() which passes current
- audit_get_context()
- see above.
which I think are all safe because when it's a new/dead process being accessed,
that process can't be modifying itself at that point, otherwise it's current
being accessed.
./kernel/cred.c: old = get_task_cred(daemon);
This is prepare_kernel_cred() which is used by:
- cachefiles_get_security_ID() which passes current.
so this is safe.
./include/linux/cred.h: * get_task_cred - Get another task's objective credentials
./include/linux/cred.h:#define get_task_cred(task) \
The header file stuff under discussion.
./security/security.c: cred = get_task_cred(tsk);
./security/security.c: cred = get_task_cred(tsk);
These are security_real_capable{,_noaudit}() if CONFIG_SECURITY=y, which could
be a problem since they're used by has_capability{,_noaudit}() and called by
things like the OOM killer with tasks other than current.
However, I'm not sure it's necessary for get_task_cred() to be used here (in
security/security.c) as it doesn't appear that the capable() LSM method sleeps
in the one LSM that implements it (SELinux) or in the commoncap code.
David
next prev parent reply other threads:[~2010-07-28 12:07 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-27 15:50 [PATCH] cred - synchronize rcu before releasing cred Jiri Olsa
2010-07-27 16:16 ` Linus Torvalds
2010-07-27 16:46 ` David Howells
2010-07-27 17:56 ` Linus Torvalds
2010-07-28 8:25 ` Jiri Olsa
2010-07-28 12:07 ` David Howells [this message]
2010-07-28 12:47 ` David Howells
2010-07-29 6:00 ` Paul E. McKenney
2010-07-29 8:34 ` David Howells
2010-07-30 21:32 ` Paul E. McKenney
2010-07-28 13:17 ` David Howells
2010-07-28 14:46 ` Jiri Olsa
2010-07-29 9:38 ` Jiri Olsa
2010-07-28 15:51 ` Linus Torvalds
-- strict thread matches above, loose matches on Subject: below --
2010-06-25 13:33 Jiri Olsa
2010-07-02 12:14 ` Jiri Olsa
2010-06-16 12:24 Jiri Olsa
2010-06-16 12:45 ` Eric Dumazet
2010-06-16 12:57 ` Jiri Olsa
2010-06-16 13:10 ` Eric Dumazet
2010-06-16 16:08 ` Jiri Olsa
2010-06-17 23:50 ` David Howells
2010-06-19 12:01 ` Jiri Olsa
2010-06-25 12:55 ` Jiri Olsa
2010-06-25 13:28 ` David Howells
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=18537.1280318862@redhat.com \
--to=dhowells@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=eric.dumazet@gmail.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=paulmck@linux.vnet.ibm.com \
--cc=torvalds@linux-foundation.org \
/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.