Re: [patch 1/9] sys: Fix missing rcu protection for __task_cred()access

From: Paul E. McKenney
Date: Wed Dec 09 2009 - 20:25:33 EST


On Thu, Dec 10, 2009 at 12:52:51AM -0000, Thomas Gleixner wrote:
> commit c69e8d9 (CRED: Use RCU to access another task's creds and to
> release a task's own creds) added non rcu_read_lock() protected access
> to task creds of the target task in set_prio_one().
>
> The comment above the function says:
> * - the caller must hold the RCU read lock
>
> The calling code in sys_setpriority does read_lock(&tasklist_lock) but
> not rcu_read_lock(). This works only when CONFIG_TREE_PREEMPT_RCU=n.
> With CONFIG_TREE_PREEMPT_RCU=y the rcu_callbacks can run in the tick
> interrupt when they see no read side critical section.

And this is called out in Documentation/RCU/checklist.txt, item #2:

2. Do the RCU read-side critical sections make proper use of
rcu_read_lock() and friends? These primitives are needed
to prevent grace periods from ending prematurely, which
could result in data being unceremoniously freed out from
under your read-side code, which can greatly increase the
actuarial risk of your kernel.

As a rough rule of thumb, any dereference of an RCU-protected
pointer must be covered by rcu_read_lock() or rcu_read_lock_bh()
or by the appropriate update-side lock.

> There is another instance of __task_cred() in sys_setpriority() itself
> which is equally unprotected.
>
> Wrap the whole code section into a rcu read side critical section to
> fix this quick and dirty.
>
> Will be revisited in course of the read_lock(&tasklist_lock) -> rcu
> crusade.

Good catch!

Acked-by: Paul E. McKenney <paulmck@xxxxxxxxxxxxxxxxxx>

> Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
> Cc: David Howells <dhowells@xxxxxxxxxx>
> Cc: James Morris <jmorris@xxxxxxxxx>
> Cc: linux-security-module@xxxxxxxxxxxxxxx
> ---
> kernel/sys.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> Index: linux-2.6-tip/kernel/sys.c
> ===================================================================
> --- linux-2.6-tip.orig/kernel/sys.c
> +++ linux-2.6-tip/kernel/sys.c
> @@ -163,6 +163,7 @@ SYSCALL_DEFINE3(setpriority, int, which,
> if (niceval > 19)
> niceval = 19;
>
> + rcu_read_lock();
> read_lock(&tasklist_lock);
> switch (which) {
> case PRIO_PROCESS:
> @@ -200,6 +201,7 @@ SYSCALL_DEFINE3(setpriority, int, which,
> }
> out_unlock:
> read_unlock(&tasklist_lock);
> + rcu_read_unlock();
> out:
> return error;
> }
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/