diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/integrity/ima/ima_policy.c | 3 | ||||
-rw-r--r-- | security/keys/internal.h | 1 | ||||
-rw-r--r-- | security/keys/key.c | 1 | ||||
-rw-r--r-- | security/keys/user_defined.c | 43 |
4 files changed, 44 insertions, 4 deletions
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index d661afbe474c..d45061d02fee 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -99,6 +99,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule, struct inode *inode, enum ima_hooks func, int mask) { struct task_struct *tsk = current; + const struct cred *cred = current_cred(); int i; if ((rule->flags & IMA_FUNC) && rule->func != func) @@ -108,7 +109,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule, if ((rule->flags & IMA_FSMAGIC) && rule->fsmagic != inode->i_sb->s_magic) return false; - if ((rule->flags & IMA_UID) && rule->uid != tsk->cred->uid) + if ((rule->flags & IMA_UID) && rule->uid != cred->uid) return false; for (i = 0; i < MAX_LSM_RULES; i++) { int rc = 0; diff --git a/security/keys/internal.h b/security/keys/internal.h index c7a7caec4830..65647f825584 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -33,6 +33,7 @@ extern struct key_type key_type_dead; extern struct key_type key_type_user; +extern struct key_type key_type_logon; /*****************************************************************************/ /* diff --git a/security/keys/key.c b/security/keys/key.c index 4f64c7267afb..7ada8019be1f 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -999,6 +999,7 @@ void __init key_init(void) list_add_tail(&key_type_keyring.link, &key_types_list); list_add_tail(&key_type_dead.link, &key_types_list); list_add_tail(&key_type_user.link, &key_types_list); + list_add_tail(&key_type_logon.link, &key_types_list); /* record the root user tracking */ rb_link_node(&root_key_user.node, diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c index 69ff52c08e97..c7660a25a3e4 100644 --- a/security/keys/user_defined.c +++ b/security/keys/user_defined.c @@ -18,6 +18,8 @@ #include <asm/uaccess.h> #include "internal.h" +static int logon_vet_description(const char *desc); + /* * user defined keys take an arbitrary string as the description and an * arbitrary blob of data as the payload @@ -36,6 +38,24 @@ struct key_type key_type_user = { EXPORT_SYMBOL_GPL(key_type_user); /* + * This key type is essentially the same as key_type_user, but it does + * not define a .read op. This is suitable for storing username and + * password pairs in the keyring that you do not want to be readable + * from userspace. + */ +struct key_type key_type_logon = { + .name = "logon", + .instantiate = user_instantiate, + .update = user_update, + .match = user_match, + .revoke = user_revoke, + .destroy = user_destroy, + .describe = user_describe, + .vet_description = logon_vet_description, +}; +EXPORT_SYMBOL_GPL(key_type_logon); + +/* * instantiate a user defined key */ int user_instantiate(struct key *key, const void *data, size_t datalen) @@ -59,7 +79,7 @@ int user_instantiate(struct key *key, const void *data, size_t datalen) /* attach the data */ upayload->datalen = datalen; memcpy(upayload->data, data, datalen); - rcu_assign_pointer(key->payload.data, upayload); + rcu_assign_keypointer(key, upayload); ret = 0; error: @@ -98,7 +118,7 @@ int user_update(struct key *key, const void *data, size_t datalen) if (ret == 0) { /* attach the new data, displacing the old */ zap = key->payload.data; - rcu_assign_pointer(key->payload.data, upayload); + rcu_assign_keypointer(key, upayload); key->expiry = 0; } @@ -133,7 +153,7 @@ void user_revoke(struct key *key) key_payload_reserve(key, 0); if (upayload) { - rcu_assign_pointer(key->payload.data, NULL); + rcu_assign_keypointer(key, NULL); kfree_rcu(upayload, rcu); } } @@ -189,3 +209,20 @@ long user_read(const struct key *key, char __user *buffer, size_t buflen) } EXPORT_SYMBOL_GPL(user_read); + +/* Vet the description for a "logon" key */ +static int logon_vet_description(const char *desc) +{ + char *p; + + /* require a "qualified" description string */ + p = strchr(desc, ':'); + if (!p) + return -EINVAL; + + /* also reject description with ':' as first char */ + if (p == desc) + return -EINVAL; + + return 0; +} |