Skip to content

Commit dcf49db

Browse files
committed
keys: Add a 'recurse' flag for keyring searches
Add a 'recurse' flag for keyring searches so that the flag can be omitted and recursion disabled, thereby allowing just the nominated keyring to be searched and none of the children. Signed-off-by: David Howells <[email protected]>
1 parent 355ef8e commit dcf49db

File tree

14 files changed

+34
-18
lines changed

14 files changed

+34
-18
lines changed

Documentation/security/keys/core.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,11 +1162,13 @@ payload contents" for more information.
11621162

11631163
key_ref_t keyring_search(key_ref_t keyring_ref,
11641164
const struct key_type *type,
1165-
const char *description)
1165+
const char *description,
1166+
bool recurse)
11661167
1167-
This searches the keyring tree specified for a matching key. Error ENOKEY
1168-
is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful,
1169-
the returned key will need to be released.
1168+
This searches the specified keyring only (recurse == false) or keyring tree
1169+
(recurse == true) specified for a matching key. Error ENOKEY is returned
1170+
upon failure (use IS_ERR/PTR_ERR to determine). If successful, the returned
1171+
key will need to be released.
11701172

11711173
The possession attribute from the keyring reference is used to control
11721174
access through the permissions mask and is propagated to the returned key

certs/blacklist.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ int is_hash_blacklisted(const u8 *hash, size_t hash_len, const char *type)
128128
*p = 0;
129129

130130
kref = keyring_search(make_key_ref(blacklist_keyring, true),
131-
&key_type_blacklist, buffer);
131+
&key_type_blacklist, buffer, false);
132132
if (!IS_ERR(kref)) {
133133
key_ref_put(kref);
134134
ret = -EKEYREJECTED;

crypto/asymmetric_keys/asymmetric_type.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ struct key *find_asymmetric_key(struct key *keyring,
8787
pr_debug("Look up: \"%s\"\n", req);
8888

8989
ref = keyring_search(make_key_ref(keyring, 1),
90-
&key_type_asymmetric, req);
90+
&key_type_asymmetric, req, true);
9191
if (IS_ERR(ref))
9292
pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));
9393
kfree(req);

include/linux/key.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,8 @@ extern int keyring_clear(struct key *keyring);
341341

342342
extern key_ref_t keyring_search(key_ref_t keyring,
343343
struct key_type *type,
344-
const char *description);
344+
const char *description,
345+
bool recurse);
345346

346347
extern int keyring_add_key(struct key *keyring,
347348
struct key *key);

lib/digsig.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ int digsig_verify(struct key *keyring, const char *sig, int siglen,
221221
/* search in specific keyring */
222222
key_ref_t kref;
223223
kref = keyring_search(make_key_ref(keyring, 1UL),
224-
&key_type_user, name);
224+
&key_type_user, name, true);
225225
if (IS_ERR(kref))
226226
key = ERR_CAST(kref);
227227
else

net/rxrpc/security.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
148148

149149
/* look through the service's keyring */
150150
kref = keyring_search(make_key_ref(rx->securities, 1UL),
151-
&key_type_rxrpc_s, kdesc);
151+
&key_type_rxrpc_s, kdesc, true);
152152
if (IS_ERR(kref)) {
153153
read_unlock(&local->services_lock);
154154
_leave(" = %ld [search]", PTR_ERR(kref));

security/integrity/digsig_asymmetric.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
3939
key_ref_t kref;
4040

4141
kref = keyring_search(make_key_ref(key, 1),
42-
&key_type_asymmetric, name);
42+
&key_type_asymmetric, name, true);
4343
if (!IS_ERR(kref)) {
4444
pr_err("Key '%s' is in ima_blacklist_keyring\n", name);
4545
return ERR_PTR(-EKEYREJECTED);
@@ -51,7 +51,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
5151
key_ref_t kref;
5252

5353
kref = keyring_search(make_key_ref(keyring, 1),
54-
&key_type_asymmetric, name);
54+
&key_type_asymmetric, name, true);
5555
if (IS_ERR(kref))
5656
key = ERR_CAST(kref);
5757
else

security/keys/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ struct keyring_search_context {
127127
#define KEYRING_SEARCH_NO_CHECK_PERM 0x0008 /* Don't check permissions */
128128
#define KEYRING_SEARCH_DETECT_TOO_DEEP 0x0010 /* Give an error on excessive depth */
129129
#define KEYRING_SEARCH_SKIP_EXPIRED 0x0020 /* Ignore expired keys (intention to replace) */
130+
#define KEYRING_SEARCH_RECURSE 0x0040 /* Search child keyrings also */
130131

131132
int (*iterator)(const void *object, void *iterator_data);
132133

security/keys/keyctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ long keyctl_keyring_search(key_serial_t ringid,
762762
}
763763

764764
/* do the search */
765-
key_ref = keyring_search(keyring_ref, ktype, description);
765+
key_ref = keyring_search(keyring_ref, ktype, description, true);
766766
if (IS_ERR(key_ref)) {
767767
ret = PTR_ERR(key_ref);
768768

security/keys/keyring.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,9 @@ static bool search_nested_keyrings(struct key *keyring,
685685
* Non-keyrings avoid the leftmost branch of the root entirely (root
686686
* slots 1-15).
687687
*/
688+
if (!(ctx->flags & KEYRING_SEARCH_RECURSE))
689+
goto not_this_keyring;
690+
688691
ptr = READ_ONCE(keyring->keys.root);
689692
if (!ptr)
690693
goto not_this_keyring;
@@ -885,13 +888,15 @@ key_ref_t keyring_search_rcu(key_ref_t keyring_ref,
885888
* @keyring: The root of the keyring tree to be searched.
886889
* @type: The type of keyring we want to find.
887890
* @description: The name of the keyring we want to find.
891+
* @recurse: True to search the children of @keyring also
888892
*
889893
* As keyring_search_rcu() above, but using the current task's credentials and
890894
* type's default matching function and preferred search method.
891895
*/
892896
key_ref_t keyring_search(key_ref_t keyring,
893897
struct key_type *type,
894-
const char *description)
898+
const char *description,
899+
bool recurse)
895900
{
896901
struct keyring_search_context ctx = {
897902
.index_key.type = type,
@@ -906,6 +911,8 @@ key_ref_t keyring_search(key_ref_t keyring,
906911
key_ref_t key;
907912
int ret;
908913

914+
if (recurse)
915+
ctx.flags |= KEYRING_SEARCH_RECURSE;
909916
if (type->match_preparse) {
910917
ret = type->match_preparse(&ctx.match_data);
911918
if (ret < 0)
@@ -1176,7 +1183,8 @@ static int keyring_detect_cycle(struct key *A, struct key *B)
11761183
.flags = (KEYRING_SEARCH_NO_STATE_CHECK |
11771184
KEYRING_SEARCH_NO_UPDATE_TIME |
11781185
KEYRING_SEARCH_NO_CHECK_PERM |
1179-
KEYRING_SEARCH_DETECT_TOO_DEEP),
1186+
KEYRING_SEARCH_DETECT_TOO_DEEP |
1187+
KEYRING_SEARCH_RECURSE),
11801188
};
11811189

11821190
rcu_read_lock();

security/keys/proc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ static int proc_keys_show(struct seq_file *m, void *v)
170170
.match_data.cmp = lookup_user_key_possessed,
171171
.match_data.raw_data = key,
172172
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
173-
.flags = KEYRING_SEARCH_NO_STATE_CHECK,
173+
.flags = (KEYRING_SEARCH_NO_STATE_CHECK |
174+
KEYRING_SEARCH_RECURSE),
174175
};
175176

176177
key_ref = make_key_ref(key, 0);

security/keys/process_keys.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,8 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
531531
struct keyring_search_context ctx = {
532532
.match_data.cmp = lookup_user_key_possessed,
533533
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
534-
.flags = KEYRING_SEARCH_NO_STATE_CHECK,
534+
.flags = (KEYRING_SEARCH_NO_STATE_CHECK |
535+
KEYRING_SEARCH_RECURSE),
535536
};
536537
struct request_key_auth *rka;
537538
struct key *key;

security/keys/request_key.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,8 @@ struct key *request_key_and_link(struct key_type *type,
569569
.match_data.raw_data = description,
570570
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
571571
.flags = (KEYRING_SEARCH_DO_STATE_CHECK |
572-
KEYRING_SEARCH_SKIP_EXPIRED),
572+
KEYRING_SEARCH_SKIP_EXPIRED |
573+
KEYRING_SEARCH_RECURSE),
573574
};
574575
struct key *key;
575576
key_ref_t key_ref;

security/keys/request_key_auth.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,8 @@ struct key *key_get_instantiation_authkey(key_serial_t target_id)
252252
.match_data.cmp = key_default_cmp,
253253
.match_data.raw_data = description,
254254
.match_data.lookup_type = KEYRING_SEARCH_LOOKUP_DIRECT,
255-
.flags = KEYRING_SEARCH_DO_STATE_CHECK,
255+
.flags = (KEYRING_SEARCH_DO_STATE_CHECK |
256+
KEYRING_SEARCH_RECURSE),
256257
};
257258
struct key *authkey;
258259
key_ref_t authkey_ref;

0 commit comments

Comments
 (0)