aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/key.h2
-rw-r--r--security/keys/internal.h2
-rw-r--r--security/keys/key.c2
-rw-r--r--security/keys/keyring.c23
-rw-r--r--security/keys/process_keys.c6
5 files changed, 23 insertions, 12 deletions
diff --git a/include/linux/key.h b/include/linux/key.h
index 044114185120..e315e16b6ff8 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -187,6 +187,7 @@ struct key {
187#define KEY_FLAG_BUILTIN 8 /* set if key is built in to the kernel */ 187#define KEY_FLAG_BUILTIN 8 /* set if key is built in to the kernel */
188#define KEY_FLAG_ROOT_CAN_INVAL 9 /* set if key can be invalidated by root without permission */ 188#define KEY_FLAG_ROOT_CAN_INVAL 9 /* set if key can be invalidated by root without permission */
189#define KEY_FLAG_KEEP 10 /* set if key should not be removed */ 189#define KEY_FLAG_KEEP 10 /* set if key should not be removed */
190#define KEY_FLAG_UID_KEYRING 11 /* set if key is a user or user session keyring */
190 191
191 /* the key type and key description string 192 /* the key type and key description string
192 * - the desc is used to match a key against search criteria 193 * - the desc is used to match a key against search criteria
@@ -243,6 +244,7 @@ extern struct key *key_alloc(struct key_type *type,
243#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */ 244#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */
244#define KEY_ALLOC_BUILT_IN 0x0004 /* Key is built into kernel */ 245#define KEY_ALLOC_BUILT_IN 0x0004 /* Key is built into kernel */
245#define KEY_ALLOC_BYPASS_RESTRICTION 0x0008 /* Override the check on restricted keyrings */ 246#define KEY_ALLOC_BYPASS_RESTRICTION 0x0008 /* Override the check on restricted keyrings */
247#define KEY_ALLOC_UID_KEYRING 0x0010 /* allocating a user or user session keyring */
246 248
247extern void key_revoke(struct key *key); 249extern void key_revoke(struct key *key);
248extern void key_invalidate(struct key *key); 250extern void key_invalidate(struct key *key);
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 1c02c6547038..503adbae7b0d 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -141,7 +141,7 @@ extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
141extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx); 141extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx);
142extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx); 142extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx);
143 143
144extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); 144extern struct key *find_keyring_by_name(const char *name, bool uid_keyring);
145 145
146extern int install_user_keyrings(void); 146extern int install_user_keyrings(void);
147extern int install_thread_keyring_to_cred(struct cred *); 147extern int install_thread_keyring_to_cred(struct cred *);
diff --git a/security/keys/key.c b/security/keys/key.c
index 83da68d98b40..e5c0896c3a8f 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -302,6 +302,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
302 key->flags |= 1 << KEY_FLAG_IN_QUOTA; 302 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
303 if (flags & KEY_ALLOC_BUILT_IN) 303 if (flags & KEY_ALLOC_BUILT_IN)
304 key->flags |= 1 << KEY_FLAG_BUILTIN; 304 key->flags |= 1 << KEY_FLAG_BUILTIN;
305 if (flags & KEY_ALLOC_UID_KEYRING)
306 key->flags |= 1 << KEY_FLAG_UID_KEYRING;
305 307
306#ifdef KEY_DEBUGGING 308#ifdef KEY_DEBUGGING
307 key->magic = KEY_DEBUG_MAGIC; 309 key->magic = KEY_DEBUG_MAGIC;
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 94f038967c17..4fa82a8a9c0e 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -1097,15 +1097,15 @@ found:
1097/* 1097/*
1098 * Find a keyring with the specified name. 1098 * Find a keyring with the specified name.
1099 * 1099 *
1100 * All named keyrings in the current user namespace are searched, provided they 1100 * Only keyrings that have nonzero refcount, are not revoked, and are owned by a
1101 * grant Search permission directly to the caller (unless this check is 1101 * user in the current user namespace are considered. If @uid_keyring is %true,
1102 * skipped). Keyrings whose usage points have reached zero or who have been 1102 * the keyring additionally must have been allocated as a user or user session
1103 * revoked are skipped. 1103 * keyring; otherwise, it must grant Search permission directly to the caller.
1104 * 1104 *
1105 * Returns a pointer to the keyring with the keyring's refcount having being 1105 * Returns a pointer to the keyring with the keyring's refcount having being
1106 * incremented on success. -ENOKEY is returned if a key could not be found. 1106 * incremented on success. -ENOKEY is returned if a key could not be found.
1107 */ 1107 */
1108struct key *find_keyring_by_name(const char *name, bool skip_perm_check) 1108struct key *find_keyring_by_name(const char *name, bool uid_keyring)
1109{ 1109{
1110 struct key *keyring; 1110 struct key *keyring;
1111 int bucket; 1111 int bucket;
@@ -1133,10 +1133,15 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
1133 if (strcmp(keyring->description, name) != 0) 1133 if (strcmp(keyring->description, name) != 0)
1134 continue; 1134 continue;
1135 1135
1136 if (!skip_perm_check && 1136 if (uid_keyring) {
1137 key_permission(make_key_ref(keyring, 0), 1137 if (!test_bit(KEY_FLAG_UID_KEYRING,
1138 KEY_NEED_SEARCH) < 0) 1138 &keyring->flags))
1139 continue; 1139 continue;
1140 } else {
1141 if (key_permission(make_key_ref(keyring, 0),
1142 KEY_NEED_SEARCH) < 0)
1143 continue;
1144 }
1140 1145
1141 /* we've got a match but we might end up racing with 1146 /* we've got a match but we might end up racing with
1142 * key_cleanup() if the keyring is currently 'dead' 1147 * key_cleanup() if the keyring is currently 'dead'
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 86bced9fdbdf..293d3598153b 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -77,7 +77,8 @@ int install_user_keyrings(void)
77 if (IS_ERR(uid_keyring)) { 77 if (IS_ERR(uid_keyring)) {
78 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID, 78 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID,
79 cred, user_keyring_perm, 79 cred, user_keyring_perm,
80 KEY_ALLOC_IN_QUOTA, 80 KEY_ALLOC_UID_KEYRING |
81 KEY_ALLOC_IN_QUOTA,
81 NULL, NULL); 82 NULL, NULL);
82 if (IS_ERR(uid_keyring)) { 83 if (IS_ERR(uid_keyring)) {
83 ret = PTR_ERR(uid_keyring); 84 ret = PTR_ERR(uid_keyring);
@@ -94,7 +95,8 @@ int install_user_keyrings(void)
94 session_keyring = 95 session_keyring =
95 keyring_alloc(buf, user->uid, INVALID_GID, 96 keyring_alloc(buf, user->uid, INVALID_GID,
96 cred, user_keyring_perm, 97 cred, user_keyring_perm,
97 KEY_ALLOC_IN_QUOTA, 98 KEY_ALLOC_UID_KEYRING |
99 KEY_ALLOC_IN_QUOTA,
98 NULL, NULL); 100 NULL, NULL);
99 if (IS_ERR(session_keyring)) { 101 if (IS_ERR(session_keyring)) {
100 ret = PTR_ERR(session_keyring); 102 ret = PTR_ERR(session_keyring);