|
@@ -168,11 +168,12 @@ error:
|
|
|
*/
|
|
|
int install_process_keyring(struct task_struct *tsk)
|
|
|
{
|
|
|
- unsigned long flags;
|
|
|
struct key *keyring;
|
|
|
char buf[20];
|
|
|
int ret;
|
|
|
|
|
|
+ might_sleep();
|
|
|
+
|
|
|
if (!tsk->signal->process_keyring) {
|
|
|
sprintf(buf, "_pid.%u", tsk->tgid);
|
|
|
|
|
@@ -183,12 +184,12 @@ int install_process_keyring(struct task_struct *tsk)
|
|
|
}
|
|
|
|
|
|
/* attach keyring */
|
|
|
- spin_lock_irqsave(&tsk->sighand->siglock, flags);
|
|
|
+ spin_lock_irq(&tsk->sighand->siglock);
|
|
|
if (!tsk->signal->process_keyring) {
|
|
|
tsk->signal->process_keyring = keyring;
|
|
|
keyring = NULL;
|
|
|
}
|
|
|
- spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
|
|
|
+ spin_unlock_irq(&tsk->sighand->siglock);
|
|
|
|
|
|
key_put(keyring);
|
|
|
}
|
|
@@ -207,38 +208,37 @@ error:
|
|
|
static int install_session_keyring(struct task_struct *tsk,
|
|
|
struct key *keyring)
|
|
|
{
|
|
|
- unsigned long flags;
|
|
|
struct key *old;
|
|
|
char buf[20];
|
|
|
- int ret;
|
|
|
+
|
|
|
+ might_sleep();
|
|
|
|
|
|
/* create an empty session keyring */
|
|
|
if (!keyring) {
|
|
|
sprintf(buf, "_ses.%u", tsk->tgid);
|
|
|
|
|
|
keyring = keyring_alloc(buf, tsk->uid, tsk->gid, 1, NULL);
|
|
|
- if (IS_ERR(keyring)) {
|
|
|
- ret = PTR_ERR(keyring);
|
|
|
- goto error;
|
|
|
- }
|
|
|
+ if (IS_ERR(keyring))
|
|
|
+ return PTR_ERR(keyring);
|
|
|
}
|
|
|
else {
|
|
|
atomic_inc(&keyring->usage);
|
|
|
}
|
|
|
|
|
|
/* install the keyring */
|
|
|
- spin_lock_irqsave(&tsk->sighand->siglock, flags);
|
|
|
- old = rcu_dereference(tsk->signal->session_keyring);
|
|
|
+ spin_lock_irq(&tsk->sighand->siglock);
|
|
|
+ old = tsk->signal->session_keyring;
|
|
|
rcu_assign_pointer(tsk->signal->session_keyring, keyring);
|
|
|
- spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
|
|
|
+ spin_unlock_irq(&tsk->sighand->siglock);
|
|
|
|
|
|
- ret = 0;
|
|
|
+ /* we're using RCU on the pointer, but there's no point synchronising
|
|
|
+ * on it if it didn't previously point to anything */
|
|
|
+ if (old) {
|
|
|
+ synchronize_rcu();
|
|
|
+ key_put(old);
|
|
|
+ }
|
|
|
|
|
|
- /* we're using RCU on the pointer */
|
|
|
- synchronize_rcu();
|
|
|
- key_put(old);
|
|
|
-error:
|
|
|
- return ret;
|
|
|
+ return 0;
|
|
|
|
|
|
} /* end install_session_keyring() */
|
|
|
|
|
@@ -311,7 +311,6 @@ void exit_keys(struct task_struct *tsk)
|
|
|
*/
|
|
|
int exec_keys(struct task_struct *tsk)
|
|
|
{
|
|
|
- unsigned long flags;
|
|
|
struct key *old;
|
|
|
|
|
|
/* newly exec'd tasks don't get a thread keyring */
|
|
@@ -323,10 +322,10 @@ int exec_keys(struct task_struct *tsk)
|
|
|
key_put(old);
|
|
|
|
|
|
/* discard the process keyring from a newly exec'd task */
|
|
|
- spin_lock_irqsave(&tsk->sighand->siglock, flags);
|
|
|
+ spin_lock_irq(&tsk->sighand->siglock);
|
|
|
old = tsk->signal->process_keyring;
|
|
|
tsk->signal->process_keyring = NULL;
|
|
|
- spin_unlock_irqrestore(&tsk->sighand->siglock, flags);
|
|
|
+ spin_unlock_irq(&tsk->sighand->siglock);
|
|
|
|
|
|
key_put(old);
|
|
|
|