diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/keys/key.c | 4 | ||||
-rw-r--r-- | security/keys/keyring.c | 1 | ||||
-rw-r--r-- | security/keys/process_keys.c | 41 | ||||
-rw-r--r-- | security/selinux/xfrm.c | 4 |
4 files changed, 27 insertions, 23 deletions
diff --git a/security/keys/key.c b/security/keys/key.c index a057e3311aad..b6061fa29da7 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -785,6 +785,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, key_check(keyring); + key_ref = ERR_PTR(-ENOTDIR); + if (keyring->type != &key_type_keyring) + goto error_2; + down_write(&keyring->sem); /* if we're going to allocate a new key, we're going to have diff --git a/security/keys/keyring.c b/security/keys/keyring.c index d65a180f888d..bffa924c1f88 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -437,6 +437,7 @@ EXPORT_SYMBOL(keyring_search); /* * search the given keyring only (no recursion) * - keyring must be locked by caller + * - caller must guarantee that the keyring is a keyring */ key_ref_t __keyring_search_one(key_ref_t keyring_ref, const struct key_type *ktype, diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index f6940618e345..217a0bef3c82 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c @@ -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); diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index dfab6c886698..abe99d881376 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c @@ -281,7 +281,7 @@ u32 selinux_socket_getpeer_dgram(struct sk_buff *skb) int i; for (i = sp->len-1; i >= 0; i--) { - struct xfrm_state *x = sp->x[i].xvec; + struct xfrm_state *x = sp->xvec[i]; if (selinux_authorizable_xfrm(x)) { struct xfrm_sec_ctx *ctx = x->security; return ctx->ctx_sid; @@ -314,7 +314,7 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb) * Only need to verify the existence of an authorizable sp. */ for (i = 0; i < sp->len; i++) { - struct xfrm_state *x = sp->x[i].xvec; + struct xfrm_state *x = sp->xvec[i]; if (x && selinux_authorizable_xfrm(x)) goto accept; |