All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] KEYS: Fix RCU handling in key_gc_keyring()
@ 2010-05-04 13:16 David Howells
  2010-05-04 15:46 ` Serge E. Hallyn
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: David Howells @ 2010-05-04 13:16 UTC (permalink / raw)
  To: torvalds, akpm, serue, paulmck
  Cc: dhowells, keyrings, linux-security-module, linux-kernel

key_gc_keyring() needs to either hold the RCU read lock or hold the keyring
semaphore if it's going to scan the keyring's list.  Given that it only needs
to read the key list, and it's doing so under a spinlock, the RCU read lock is
the thing to use.

Furthermore, the RCU check added in e7b0a61b7929632d36cf052d9e2820ef0a9c1bfe is
incorrect as holding the spinlock on key_serial_lock is not grounds for
assuming a keyring's pointer list can be read safely.  Instead, a simple
rcu_dereference() inside of the previously mentioned RCU read lock is what we
want.

Reported-by: Serge E. Hallyn <serue@us.ibm.com>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 security/keys/gc.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/security/keys/gc.c b/security/keys/gc.c
index 1990231..a46e825 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -77,10 +77,10 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
 		goto dont_gc;
 
 	/* scan the keyring looking for dead keys */
-	klist = rcu_dereference_check(keyring->payload.subscriptions,
-				      lockdep_is_held(&key_serial_lock));
+	rcu_read_lock();
+	klist = rcu_dereference(keyring->payload.subscriptions);
 	if (!klist)
-		goto dont_gc;
+		goto unlock_dont_gc;
 
 	for (loop = klist->nkeys - 1; loop >= 0; loop--) {
 		key = klist->keys[loop];
@@ -89,11 +89,14 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
 			goto do_gc;
 	}
 
+unlock_dont_gc:
+	rcu_read_unlock();
 dont_gc:
 	kleave(" = false");
 	return false;
 
 do_gc:
+	rcu_read_unlock();
 	key_gc_cursor = keyring->serial;
 	key_get(keyring);
 	spin_unlock(&key_serial_lock);


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] KEYS: Fix RCU handling in key_gc_keyring()
  2010-05-04 13:16 [PATCH] KEYS: Fix RCU handling in key_gc_keyring() David Howells
@ 2010-05-04 15:46 ` Serge E. Hallyn
  2010-05-04 15:58 ` David Howells
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Serge E. Hallyn @ 2010-05-04 15:46 UTC (permalink / raw)
  To: David Howells
  Cc: torvalds, akpm, paulmck, keyrings, linux-security-module, linux-kernel

Quoting David Howells (dhowells@redhat.com):
> key_gc_keyring() needs to either hold the RCU read lock or hold the keyring
> semaphore if it's going to scan the keyring's list.  Given that it only needs
> to read the key list, and it's doing so under a spinlock, the RCU read lock is
> the thing to use.
> 
> Furthermore, the RCU check added in e7b0a61b7929632d36cf052d9e2820ef0a9c1bfe is
> incorrect as holding the spinlock on key_serial_lock is not grounds for
> assuming a keyring's pointer list can be read safely.  Instead, a simple
> rcu_dereference() inside of the previously mentioned RCU read lock is what we
> want.
> 
> Reported-by: Serge E. Hallyn <serue@us.ibm.com>

You're obviously being far too kind.  In apparent trend for last night
I missed the lack of locking here.

> Signed-off-by: David Howells <dhowells@redhat.com>

Acked-by: Serge Hallyn <serue@us.ibm.com>

thanks,
-serge

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] KEYS: Fix RCU handling in key_gc_keyring()
  2010-05-04 13:16 [PATCH] KEYS: Fix RCU handling in key_gc_keyring() David Howells
  2010-05-04 15:46 ` Serge E. Hallyn
@ 2010-05-04 15:58 ` David Howells
  2010-05-05  0:59 ` Paul E. McKenney
  2010-05-05  9:31 ` David Howells
  3 siblings, 0 replies; 5+ messages in thread
From: David Howells @ 2010-05-04 15:58 UTC (permalink / raw)
  To: Serge E. Hallyn
  Cc: dhowells, torvalds, akpm, paulmck, keyrings,
	linux-security-module, linux-kernel

Serge E. Hallyn <serue@us.ibm.com> wrote:

> You're obviously being far too kind.  In apparent trend for last night
> I missed the lack of locking here.

You pointed out the wrongness of it - it just wasn't in the way you thought.

David

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] KEYS: Fix RCU handling in key_gc_keyring()
  2010-05-04 13:16 [PATCH] KEYS: Fix RCU handling in key_gc_keyring() David Howells
  2010-05-04 15:46 ` Serge E. Hallyn
  2010-05-04 15:58 ` David Howells
@ 2010-05-05  0:59 ` Paul E. McKenney
  2010-05-05  9:31 ` David Howells
  3 siblings, 0 replies; 5+ messages in thread
From: Paul E. McKenney @ 2010-05-05  0:59 UTC (permalink / raw)
  To: David Howells
  Cc: torvalds, akpm, serue, keyrings, linux-security-module, linux-kernel

On Tue, May 04, 2010 at 02:16:10PM +0100, David Howells wrote:
> key_gc_keyring() needs to either hold the RCU read lock or hold the keyring
> semaphore if it's going to scan the keyring's list.  Given that it only needs
> to read the key list, and it's doing so under a spinlock, the RCU read lock is
> the thing to use.
> 
> Furthermore, the RCU check added in e7b0a61b7929632d36cf052d9e2820ef0a9c1bfe is
> incorrect as holding the spinlock on key_serial_lock is not grounds for
> assuming a keyring's pointer list can be read safely.  Instead, a simple
> rcu_dereference() inside of the previously mentioned RCU read lock is what we
> want.

As the guilty party in e7b0a61b7929632d36cf052d9e2820ef0a9c1bfe...  ;-)

Acked-by: "Paul E. McKenney" <paulmck@linux.vnet.ibm.com>

> Reported-by: Serge E. Hallyn <serue@us.ibm.com>
> Signed-off-by: David Howells <dhowells@redhat.com>
> ---
> 
>  security/keys/gc.c |    9 ++++++---
>  1 files changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/security/keys/gc.c b/security/keys/gc.c
> index 1990231..a46e825 100644
> --- a/security/keys/gc.c
> +++ b/security/keys/gc.c
> @@ -77,10 +77,10 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
>  		goto dont_gc;
> 
>  	/* scan the keyring looking for dead keys */
> -	klist = rcu_dereference_check(keyring->payload.subscriptions,
> -				      lockdep_is_held(&key_serial_lock));
> +	rcu_read_lock();
> +	klist = rcu_dereference(keyring->payload.subscriptions);
>  	if (!klist)
> -		goto dont_gc;
> +		goto unlock_dont_gc;
> 
>  	for (loop = klist->nkeys - 1; loop >= 0; loop--) {
>  		key = klist->keys[loop];
> @@ -89,11 +89,14 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
>  			goto do_gc;
>  	}
> 
> +unlock_dont_gc:
> +	rcu_read_unlock();
>  dont_gc:
>  	kleave(" = false");
>  	return false;
> 
>  do_gc:
> +	rcu_read_unlock();
>  	key_gc_cursor = keyring->serial;
>  	key_get(keyring);
>  	spin_unlock(&key_serial_lock);
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] KEYS: Fix RCU handling in key_gc_keyring()
  2010-05-04 13:16 [PATCH] KEYS: Fix RCU handling in key_gc_keyring() David Howells
                   ` (2 preceding siblings ...)
  2010-05-05  0:59 ` Paul E. McKenney
@ 2010-05-05  9:31 ` David Howells
  3 siblings, 0 replies; 5+ messages in thread
From: David Howells @ 2010-05-05  9:31 UTC (permalink / raw)
  To: paulmck
  Cc: dhowells, torvalds, akpm, serue, keyrings, linux-security-module,
	linux-kernel

Paul E. McKenney <paulmck@linux.vnet.ibm.com> wrote:

> As the guilty party in e7b0a61b7929632d36cf052d9e2820ef0a9c1bfe...  ;-)

Only partially guilty;-)

David

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-05-05  9:32 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-04 13:16 [PATCH] KEYS: Fix RCU handling in key_gc_keyring() David Howells
2010-05-04 15:46 ` Serge E. Hallyn
2010-05-04 15:58 ` David Howells
2010-05-05  0:59 ` Paul E. McKenney
2010-05-05  9:31 ` David Howells

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.