rolffokkens / rpms / kernel

Forked from rpms/kernel 2 years ago
Clone
Chuck Ebbert b9c237f
From: David Howells <dhowells@redhat.com>
Chuck Ebbert b9c237f
Subject: [PATCH] KEYS: Fix RCU no-lock warning in keyctl_session_to_parent()
Chuck Ebbert b9c237f
Chuck Ebbert b9c237f
There's an protected access to the parent process's credentials in the middle
Chuck Ebbert b9c237f
of keyctl_session_to_parent().  This results in the following RCU warning:
Chuck Ebbert b9c237f
Chuck Ebbert b9c237f
===================================================
Chuck Ebbert b9c237f
[ INFO: suspicious rcu_dereference_check() usage. ]
Chuck Ebbert b9c237f
---------------------------------------------------
Chuck Ebbert b9c237f
security/keys/keyctl.c:1291 invoked rcu_dereference_check() without protection!
Chuck Ebbert b9c237f
Chuck Ebbert b9c237f
other info that might help us debug this:
Chuck Ebbert b9c237f
Chuck Ebbert b9c237f
rcu_scheduler_active = 1, debug_locks = 0
Chuck Ebbert b9c237f
1 lock held by keyctl-session-/2137:
Chuck Ebbert b9c237f
 #0:  (tasklist_lock){.+.+..}, at: [<ffffffff811ae2ec>] keyctl_session_to_parent+0x60/0x236
Chuck Ebbert b9c237f
Chuck Ebbert b9c237f
stack backtrace:
Chuck Ebbert b9c237f
Pid: 2137, comm: keyctl-session- Not tainted 2.6.36-rc2-cachefs+ #1
Chuck Ebbert b9c237f
Call Trace:
Chuck Ebbert b9c237f
 [<ffffffff8105606a>] lockdep_rcu_dereference+0xaa/0xb3
Chuck Ebbert b9c237f
 [<ffffffff811ae379>] keyctl_session_to_parent+0xed/0x236
Chuck Ebbert b9c237f
 [<ffffffff811af77e>] sys_keyctl+0xb4/0xb6
Chuck Ebbert b9c237f
 [<ffffffff81001eab>] system_call_fastpath+0x16/0x1b
Chuck Ebbert b9c237f
Chuck Ebbert b9c237f
The code should take the RCU read lock to make sure the parents credentials
Chuck Ebbert b9c237f
don't go away, even though it's holding a spinlock and has IRQ disabled.
Chuck Ebbert b9c237f
Chuck Ebbert b9c237f
Signed-off-by: David Howells <dhowells@redhat.com>
Chuck Ebbert b9c237f
---
Chuck Ebbert b9c237f
Chuck Ebbert b9c237f
 security/keys/keyctl.c |    3 +++
Chuck Ebbert b9c237f
 1 files changed, 3 insertions(+), 0 deletions(-)
Chuck Ebbert b9c237f
Chuck Ebbert b9c237f
Chuck Ebbert b9c237f
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
Chuck Ebbert b9c237f
index b2b0998..3868c67 100644
Chuck Ebbert b9c237f
--- a/security/keys/keyctl.c
Chuck Ebbert b9c237f
+++ b/security/keys/keyctl.c
Chuck Ebbert b9c237f
@@ -1272,6 +1272,7 @@ long keyctl_session_to_parent(void)
Chuck Ebbert b9c237f
 	keyring_r = NULL;
Chuck Ebbert b9c237f
 
Chuck Ebbert b9c237f
 	me = current;
Chuck Ebbert b9c237f
+	rcu_read_lock();
Chuck Ebbert b9c237f
 	write_lock_irq(&tasklist_lock);
Chuck Ebbert b9c237f
 
Chuck Ebbert b9c237f
 	parent = me->real_parent;
Chuck Ebbert b9c237f
@@ -1319,6 +1320,7 @@ long keyctl_session_to_parent(void)
Chuck Ebbert b9c237f
 	set_ti_thread_flag(task_thread_info(parent), TIF_NOTIFY_RESUME);
Chuck Ebbert b9c237f
 
Chuck Ebbert b9c237f
 	write_unlock_irq(&tasklist_lock);
Chuck Ebbert b9c237f
+	rcu_read_unlock();
Chuck Ebbert b9c237f
 	if (oldcred)
Chuck Ebbert b9c237f
 		put_cred(oldcred);
Chuck Ebbert b9c237f
 	return 0;
Chuck Ebbert b9c237f
@@ -1327,6 +1329,7 @@ already_same:
Chuck Ebbert b9c237f
 	ret = 0;
Chuck Ebbert b9c237f
 not_permitted:
Chuck Ebbert b9c237f
 	write_unlock_irq(&tasklist_lock);
Chuck Ebbert b9c237f
+	rcu_read_unlock();
Chuck Ebbert b9c237f
 	put_cred(cred);
Chuck Ebbert b9c237f
 	return ret;
Chuck Ebbert b9c237f
 
Chuck Ebbert b9c237f