[RFC] install_session_keyring

From: Suzanne Wood
Date: Sun Apr 02 2006 - 04:51:42 EST


Hello,
In a study of the control flow graph dumps to check that
an rcu_assign_pointer() with a given argument type has
preceded a call to rcu_dereference(), I've come across
install_session_keyring() of security/keys/process_keys.c.
We note that although no rcu_read_lock() is in place
locally or in the function's kernel callers, siglock
likely addresses that. While the rcu_dereference() would
indicate a desire for 'old' to persist, synchronize_rcu()
is called prior to key_put(old) which "disposes of
reference to a key." The order of events with a use of
the copy of the pointer following synchronize_rcu() is
what I question.

Thanks.
Suzanne

/******************************************************/
/*
* install a session keyring, discarding the old one
* - if a keyring is not supplied, an empty one is invented
*/
static int install_session_keyring(struct task_struct *tsk,
struct key *keyring)
{
unsigned long flags;
struct key *old;
char buf[20];
int ret;

/* 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;
}
}
else {
atomic_inc(&keyring->usage);
}

/* install the keyring */
spin_lock_irqsave(&tsk->sighand->siglock, flags);
old = rcu_dereference(tsk->signal->session_keyring);
rcu_assign_pointer(tsk->signal->session_keyring, keyring);
spin_unlock_irqrestore(&tsk->sighand->siglock, flags);

ret = 0;

/* we're using RCU on the pointer */
synchronize_rcu();
key_put(old);
error:
return ret;

} /* end install_session_keyring() */

-
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/