Skip to content

Commit 16feef4

Browse files
committed
KEYS: Consolidate the concept of an 'index key' for key access
Consolidate the concept of an 'index key' for accessing keys. The index key is the search term needed to find a key directly - basically the key type and the key description. We can add to that the description length. This will be useful when turning a keyring into an associative array rather than just a pointer block. Signed-off-by: David Howells <dhowells@redhat.com>
1 parent 7e55ca6 commit 16feef4

File tree

5 files changed

+83
-67
lines changed

5 files changed

+83
-67
lines changed

include/linux/key.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ struct key_owner;
8282
struct keyring_list;
8383
struct keyring_name;
8484

85+
struct keyring_index_key {
86+
struct key_type *type;
87+
const char *description;
88+
size_t desc_len;
89+
};
90+
8591
/*****************************************************************************/
8692
/*
8793
* key reference with possession attribute handling
@@ -129,7 +135,6 @@ struct key {
129135
struct list_head graveyard_link;
130136
struct rb_node serial_node;
131137
};
132-
struct key_type *type; /* type of key */
133138
struct rw_semaphore sem; /* change vs change sem */
134139
struct key_user *user; /* owner of this key */
135140
void *security; /* security data for this key */
@@ -163,12 +168,18 @@ struct key {
163168
#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */
164169
#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */
165170

166-
/* the description string
167-
* - this is used to match a key against search criteria
168-
* - this should be a printable string
171+
/* the key type and key description string
172+
* - the desc is used to match a key against search criteria
173+
* - it should be a printable string
169174
* - eg: for krb5 AFS, this might be "afs@REDHAT.COM"
170175
*/
171-
char *description;
176+
union {
177+
struct keyring_index_key index_key;
178+
struct {
179+
struct key_type *type; /* type of key */
180+
char *description;
181+
};
182+
};
172183

173184
/* type specific data
174185
* - this is used by the keyring type to index the name

security/keys/internal.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,17 @@ extern struct key_type *key_type_lookup(const char *type);
8989
extern void key_type_put(struct key_type *ktype);
9090

9191
extern int __key_link_begin(struct key *keyring,
92-
const struct key_type *type,
93-
const char *description,
92+
const struct keyring_index_key *index_key,
9493
unsigned long *_prealloc);
9594
extern int __key_link_check_live_key(struct key *keyring, struct key *key);
9695
extern void __key_link(struct key *keyring, struct key *key,
9796
unsigned long *_prealloc);
9897
extern void __key_link_end(struct key *keyring,
99-
struct key_type *type,
98+
const struct keyring_index_key *index_key,
10099
unsigned long prealloc);
101100

102101
extern key_ref_t __keyring_search_one(key_ref_t keyring_ref,
103-
const struct key_type *type,
104-
const char *description,
102+
const struct keyring_index_key *index_key,
105103
key_perm_t perm);
106104

107105
extern struct key *keyring_search_instkey(struct key *keyring,

security/keys/key.c

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
242242
}
243243
}
244244

245-
desclen = strlen(desc) + 1;
246-
quotalen = desclen + type->def_datalen;
245+
desclen = strlen(desc);
246+
quotalen = desclen + 1 + type->def_datalen;
247247

248248
/* get hold of the key tracking for this user */
249249
user = key_user_lookup(uid);
@@ -277,15 +277,16 @@ struct key *key_alloc(struct key_type *type, const char *desc,
277277
goto no_memory_2;
278278

279279
if (desc) {
280-
key->description = kmemdup(desc, desclen, GFP_KERNEL);
280+
key->index_key.desc_len = desclen;
281+
key->index_key.description = kmemdup(desc, desclen + 1, GFP_KERNEL);
281282
if (!key->description)
282283
goto no_memory_3;
283284
}
284285

285286
atomic_set(&key->usage, 1);
286287
init_rwsem(&key->sem);
287288
lockdep_set_class(&key->sem, &type->lock_class);
288-
key->type = type;
289+
key->index_key.type = type;
289290
key->user = user;
290291
key->quotalen = quotalen;
291292
key->datalen = type->def_datalen;
@@ -489,8 +490,7 @@ int key_instantiate_and_link(struct key *key,
489490
}
490491

491492
if (keyring) {
492-
ret = __key_link_begin(keyring, key->type, key->description,
493-
&prealloc);
493+
ret = __key_link_begin(keyring, &key->index_key, &prealloc);
494494
if (ret < 0)
495495
goto error_free_preparse;
496496
}
@@ -499,7 +499,7 @@ int key_instantiate_and_link(struct key *key,
499499
&prealloc);
500500

501501
if (keyring)
502-
__key_link_end(keyring, key->type, prealloc);
502+
__key_link_end(keyring, &key->index_key, prealloc);
503503

504504
error_free_preparse:
505505
if (key->type->preparse)
@@ -548,8 +548,7 @@ int key_reject_and_link(struct key *key,
548548
ret = -EBUSY;
549549

550550
if (keyring)
551-
link_ret = __key_link_begin(keyring, key->type,
552-
key->description, &prealloc);
551+
link_ret = __key_link_begin(keyring, &key->index_key, &prealloc);
553552

554553
mutex_lock(&key_construction_mutex);
555554

@@ -581,7 +580,7 @@ int key_reject_and_link(struct key *key,
581580
mutex_unlock(&key_construction_mutex);
582581

583582
if (keyring)
584-
__key_link_end(keyring, key->type, prealloc);
583+
__key_link_end(keyring, &key->index_key, prealloc);
585584

586585
/* wake up anyone waiting for a key to be constructed */
587586
if (awaken)
@@ -780,25 +779,27 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
780779
key_perm_t perm,
781780
unsigned long flags)
782781
{
783-
unsigned long prealloc;
782+
struct keyring_index_key index_key = {
783+
.description = description,
784+
};
784785
struct key_preparsed_payload prep;
785786
const struct cred *cred = current_cred();
786-
struct key_type *ktype;
787+
unsigned long prealloc;
787788
struct key *keyring, *key = NULL;
788789
key_ref_t key_ref;
789790
int ret;
790791

791792
/* look up the key type to see if it's one of the registered kernel
792793
* types */
793-
ktype = key_type_lookup(type);
794-
if (IS_ERR(ktype)) {
794+
index_key.type = key_type_lookup(type);
795+
if (IS_ERR(index_key.type)) {
795796
key_ref = ERR_PTR(-ENODEV);
796797
goto error;
797798
}
798799

799800
key_ref = ERR_PTR(-EINVAL);
800-
if (!ktype->match || !ktype->instantiate ||
801-
(!description && !ktype->preparse))
801+
if (!index_key.type->match || !index_key.type->instantiate ||
802+
(!index_key.description && !index_key.type->preparse))
802803
goto error_put_type;
803804

804805
keyring = key_ref_to_ptr(keyring_ref);
@@ -812,21 +813,22 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
812813
memset(&prep, 0, sizeof(prep));
813814
prep.data = payload;
814815
prep.datalen = plen;
815-
prep.quotalen = ktype->def_datalen;
816-
if (ktype->preparse) {
817-
ret = ktype->preparse(&prep);
816+
prep.quotalen = index_key.type->def_datalen;
817+
if (index_key.type->preparse) {
818+
ret = index_key.type->preparse(&prep);
818819
if (ret < 0) {
819820
key_ref = ERR_PTR(ret);
820821
goto error_put_type;
821822
}
822-
if (!description)
823-
description = prep.description;
823+
if (!index_key.description)
824+
index_key.description = prep.description;
824825
key_ref = ERR_PTR(-EINVAL);
825-
if (!description)
826+
if (!index_key.description)
826827
goto error_free_prep;
827828
}
829+
index_key.desc_len = strlen(index_key.description);
828830

829-
ret = __key_link_begin(keyring, ktype, description, &prealloc);
831+
ret = __key_link_begin(keyring, &index_key, &prealloc);
830832
if (ret < 0) {
831833
key_ref = ERR_PTR(ret);
832834
goto error_free_prep;
@@ -844,9 +846,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
844846
* key of the same type and description in the destination keyring and
845847
* update that instead if possible
846848
*/
847-
if (ktype->update) {
848-
key_ref = __keyring_search_one(keyring_ref, ktype, description,
849-
0);
849+
if (index_key.type->update) {
850+
key_ref = __keyring_search_one(keyring_ref, &index_key, 0);
850851
if (!IS_ERR(key_ref))
851852
goto found_matching_key;
852853
}
@@ -856,16 +857,17 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
856857
perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
857858
perm |= KEY_USR_VIEW;
858859

859-
if (ktype->read)
860+
if (index_key.type->read)
860861
perm |= KEY_POS_READ;
861862

862-
if (ktype == &key_type_keyring || ktype->update)
863+
if (index_key.type == &key_type_keyring ||
864+
index_key.type->update)
863865
perm |= KEY_POS_WRITE;
864866
}
865867

866868
/* allocate a new key */
867-
key = key_alloc(ktype, description, cred->fsuid, cred->fsgid, cred,
868-
perm, flags);
869+
key = key_alloc(index_key.type, index_key.description,
870+
cred->fsuid, cred->fsgid, cred, perm, flags);
869871
if (IS_ERR(key)) {
870872
key_ref = ERR_CAST(key);
871873
goto error_link_end;
@@ -882,20 +884,20 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
882884
key_ref = make_key_ref(key, is_key_possessed(keyring_ref));
883885

884886
error_link_end:
885-
__key_link_end(keyring, ktype, prealloc);
887+
__key_link_end(keyring, &index_key, prealloc);
886888
error_free_prep:
887-
if (ktype->preparse)
888-
ktype->free_preparse(&prep);
889+
if (index_key.type->preparse)
890+
index_key.type->free_preparse(&prep);
889891
error_put_type:
890-
key_type_put(ktype);
892+
key_type_put(index_key.type);
891893
error:
892894
return key_ref;
893895

894896
found_matching_key:
895897
/* we found a matching key, so we're going to try to update it
896898
* - we can drop the locks first as we have the key pinned
897899
*/
898-
__key_link_end(keyring, ktype, prealloc);
900+
__key_link_end(keyring, &index_key, prealloc);
899901

900902
key_ref = __key_update(key_ref, &prep);
901903
goto error_free_prep;

security/keys/keyring.c

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,7 @@ EXPORT_SYMBOL(keyring_search);
538538
* to the returned key reference.
539539
*/
540540
key_ref_t __keyring_search_one(key_ref_t keyring_ref,
541-
const struct key_type *ktype,
542-
const char *description,
541+
const struct keyring_index_key *index_key,
543542
key_perm_t perm)
544543
{
545544
struct keyring_list *klist;
@@ -558,9 +557,9 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
558557
smp_rmb();
559558
for (loop = 0; loop < nkeys ; loop++) {
560559
key = rcu_dereference(klist->keys[loop]);
561-
if (key->type == ktype &&
560+
if (key->type == index_key->type &&
562561
(!key->type->match ||
563-
key->type->match(key, description)) &&
562+
key->type->match(key, index_key->description)) &&
564563
key_permission(make_key_ref(key, possessed),
565564
perm) == 0 &&
566565
!(key->flags & ((1 << KEY_FLAG_INVALIDATED) |
@@ -747,8 +746,8 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
747746
/*
748747
* Preallocate memory so that a key can be linked into to a keyring.
749748
*/
750-
int __key_link_begin(struct key *keyring, const struct key_type *type,
751-
const char *description, unsigned long *_prealloc)
749+
int __key_link_begin(struct key *keyring, const struct keyring_index_key *index_key,
750+
unsigned long *_prealloc)
752751
__acquires(&keyring->sem)
753752
__acquires(&keyring_serialise_link_sem)
754753
{
@@ -759,7 +758,8 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
759758
size_t size;
760759
int loop, lru, ret;
761760

762-
kenter("%d,%s,%s,", key_serial(keyring), type->name, description);
761+
kenter("%d,%s,%s,",
762+
key_serial(keyring), index_key->type->name, index_key->description);
763763

764764
if (keyring->type != &key_type_keyring)
765765
return -ENOTDIR;
@@ -772,7 +772,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
772772

773773
/* serialise link/link calls to prevent parallel calls causing a cycle
774774
* when linking two keyring in opposite orders */
775-
if (type == &key_type_keyring)
775+
if (index_key->type == &key_type_keyring)
776776
down_write(&keyring_serialise_link_sem);
777777

778778
klist = rcu_dereference_locked_keyring(keyring);
@@ -784,8 +784,8 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
784784
for (loop = klist->nkeys - 1; loop >= 0; loop--) {
785785
struct key *key = rcu_deref_link_locked(klist, loop,
786786
keyring);
787-
if (key->type == type &&
788-
strcmp(key->description, description) == 0) {
787+
if (key->type == index_key->type &&
788+
strcmp(key->description, index_key->description) == 0) {
789789
/* Found a match - we'll replace the link with
790790
* one to the new key. We record the slot
791791
* position.
@@ -865,7 +865,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
865865
key_payload_reserve(keyring,
866866
keyring->datalen - KEYQUOTA_LINK_BYTES);
867867
error_sem:
868-
if (type == &key_type_keyring)
868+
if (index_key->type == &key_type_keyring)
869869
up_write(&keyring_serialise_link_sem);
870870
error_krsem:
871871
up_write(&keyring->sem);
@@ -957,16 +957,17 @@ void __key_link(struct key *keyring, struct key *key,
957957
*
958958
* Must be called with __key_link_begin() having being called.
959959
*/
960-
void __key_link_end(struct key *keyring, struct key_type *type,
960+
void __key_link_end(struct key *keyring,
961+
const struct keyring_index_key *index_key,
961962
unsigned long prealloc)
962963
__releases(&keyring->sem)
963964
__releases(&keyring_serialise_link_sem)
964965
{
965-
BUG_ON(type == NULL);
966-
BUG_ON(type->name == NULL);
967-
kenter("%d,%s,%lx", keyring->serial, type->name, prealloc);
966+
BUG_ON(index_key->type == NULL);
967+
BUG_ON(index_key->type->name == NULL);
968+
kenter("%d,%s,%lx", keyring->serial, index_key->type->name, prealloc);
968969

969-
if (type == &key_type_keyring)
970+
if (index_key->type == &key_type_keyring)
970971
up_write(&keyring_serialise_link_sem);
971972

972973
if (prealloc) {
@@ -1007,12 +1008,12 @@ int key_link(struct key *keyring, struct key *key)
10071008
key_check(keyring);
10081009
key_check(key);
10091010

1010-
ret = __key_link_begin(keyring, key->type, key->description, &prealloc);
1011+
ret = __key_link_begin(keyring, &key->index_key, &prealloc);
10111012
if (ret == 0) {
10121013
ret = __key_link_check_live_key(keyring, key);
10131014
if (ret == 0)
10141015
__key_link(keyring, key, &prealloc);
1015-
__key_link_end(keyring, key->type, prealloc);
1016+
__key_link_end(keyring, &key->index_key, prealloc);
10161017
}
10171018

10181019
return ret;

0 commit comments

Comments
 (0)