Messages in this thread | | | Date | Wed, 7 Dec 2011 16:52:18 -0800 | From | "Paul E. McKenney" <> | Subject | Re: [PATCH] sys_getppid: add missing rcu_dereference |
| |
On Wed, Dec 07, 2011 at 04:24:20PM -0800, Mandeep Singh Baines wrote: > Kees Cook (keescook@chromium.org) wrote: > > On Tue, Dec 6, 2011 at 6:45 PM, Mandeep Singh Baines <msb@chromium.org> wrote: > > > In order to safely dereference current->real_parent inside an > > > rcu_read_lock, we need an rcu_dereference. > > > > > > Signed-off-by: Mandeep Singh Baines <msb@chromium.org> > > > Cc: Thomas Gleixner <tglx@linutronix.de> > > > Cc: Pavel Emelyanov <xemul@openvz.org> > > > Cc: Oleg Nesterov <oleg@redhat.com> > > > Cc: Andrew Morton <akpm@linux-foundation.org> > > > Cc: Kees Cook <keescook@chromium.org> > > > --- > > > kernel/timer.c | 2 +- > > > 1 files changed, 1 insertions(+), 1 deletions(-) > > > > > > diff --git a/kernel/timer.c b/kernel/timer.c > > > index dbaa624..9c3c62b 100644 > > > --- a/kernel/timer.c > > > +++ b/kernel/timer.c > > > @@ -1368,7 +1368,7 @@ SYSCALL_DEFINE0(getppid) > > > int pid; > > > > > > rcu_read_lock(); > > > - pid = task_tgid_vnr(current->real_parent); > > > + pid = task_tgid_vnr(rcu_dereference(current->real_parent)); > > > rcu_read_unlock(); > > > > > > return pid; > > > > Should parent and real_parent also be marked in sched.h with __rcu so > > sparse can find other missing rcu_dereference()s? And if not, why? > > (tasklist lock?) > > > > Good idea. I was thinking the same thing. There's gotta be some way of > finding these bugs via lockdep or sparse.
Indeed there is! There is a CONFIG_SPARSE_RCU_POINTER kernel parameter that tells sparse to check for proper use of RCU-protected pointers. For this to work, the RCU-protected pointer in question must be marked with "__rcu". Sparse will then complain if the pointer is accessed without using one of the rcu_dereference() family of functions.
> One idea I had was to create a ->real_parent accessor and insert an > rcu_dereference_check there. That way lockdep could catch these bugs. > > static inline struct task_struct *task_real_parent(struct task_struct *task) > { > return rcu_dereference_check(task->real_parent, > lockdep_is_held(&tasklist_lock)); > }
The above is useful for common code that might be called from both RCU readers (where rcu_read_lock() is in effect) and updaters (which hold tasklist_lock). But although a task_real_parent()-style function can be extremely useful, it will not catch cases where rcu_dereference() was not used but should have been. For that, as noted above, we have CONFIG_SPARSE_RCU_POINTER. __rcu, and sparse.
Thanx, Paul
> > I think I see at least are few other users (security/apparmor/audit.c, > > security/tomoyo/common.h, kernel/sched.c) that need rcu_dereference() > > when accessing real_parent, there are probably more. > > > > -Kees > > > > -- > > Kees Cook > > ChromeOS Security >
-- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |