diff options
-rw-r--r-- | include/linux/key.h | 2 | ||||
-rw-r--r-- | security/keys/internal.h | 2 | ||||
-rw-r--r-- | security/keys/key.c | 2 | ||||
-rw-r--r-- | security/keys/keyring.c | 23 | ||||
-rw-r--r-- | security/keys/process_keys.c | 6 |
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 | ||
247 | extern void key_revoke(struct key *key); | 249 | extern void key_revoke(struct key *key); |
248 | extern void key_invalidate(struct key *key); | 250 | extern 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, | |||
141 | extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx); | 141 | extern key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx); |
142 | extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx); | 142 | extern key_ref_t search_process_keyrings(struct keyring_search_context *ctx); |
143 | 143 | ||
144 | extern struct key *find_keyring_by_name(const char *name, bool skip_perm_check); | 144 | extern struct key *find_keyring_by_name(const char *name, bool uid_keyring); |
145 | 145 | ||
146 | extern int install_user_keyrings(void); | 146 | extern int install_user_keyrings(void); |
147 | extern int install_thread_keyring_to_cred(struct cred *); | 147 | extern 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 | */ |
1108 | struct key *find_keyring_by_name(const char *name, bool skip_perm_check) | 1108 | struct 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); |