Skip to content

Commit 7a6378f

Browse files
jejbKernel Patches Daemon
authored andcommitted
bpf: eliminate the allocation of an intermediate struct bpf_key
Now that struct bpf_key is an opaque structure only containing a pointer to the key, make it an alias for the key itself and thus eliminate the need to allocate and free the container. Because the return value of bpf_lookup_system_key() is now overloaded with 0 being a legitimate built in key identifier being the same value as NULL indicating failure, key id 0 is swizzled to -1 to distinguish it again and swizzled back in bpf_key_put() and bpf_verify_pkcs7_signature() to ensure correctness. Signed-off-by: James Bottomley <[email protected]>
1 parent 6c83822 commit 7a6378f

File tree

1 file changed

+16
-27
lines changed

1 file changed

+16
-27
lines changed

kernel/trace/bpf_trace.c

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,9 +1242,11 @@ static const struct bpf_func_proto bpf_get_func_arg_cnt_proto = {
12421242
};
12431243

12441244
#ifdef CONFIG_KEYS
1245+
/* BTF requires this even if it serves no purpose */
12451246
struct bpf_key {
1246-
struct key *key;
12471247
};
1248+
/* conventional value to replace zero return which would become NULL */
1249+
const u64 BUILTIN_KEY = -1LL;
12481250

12491251
__bpf_kfunc_start_defs();
12501252

@@ -1276,7 +1278,6 @@ __bpf_kfunc_start_defs();
12761278
__bpf_kfunc struct bpf_key *bpf_lookup_user_key(s32 serial, u64 flags)
12771279
{
12781280
key_ref_t key_ref;
1279-
struct bpf_key *bkey;
12801281

12811282
if (flags & ~KEY_LOOKUP_ALL)
12821283
return NULL;
@@ -1289,15 +1290,7 @@ __bpf_kfunc struct bpf_key *bpf_lookup_user_key(s32 serial, u64 flags)
12891290
if (IS_ERR(key_ref))
12901291
return NULL;
12911292

1292-
bkey = kmalloc(sizeof(*bkey), GFP_KERNEL);
1293-
if (!bkey) {
1294-
key_put(key_ref_to_ptr(key_ref));
1295-
return NULL;
1296-
}
1297-
1298-
bkey->key = key_ref_to_ptr(key_ref);
1299-
1300-
return bkey;
1293+
return (struct bpf_key *)key_ref_to_ptr(key_ref);
13011294
}
13021295

13031296
/**
@@ -1323,18 +1316,10 @@ __bpf_kfunc struct bpf_key *bpf_lookup_user_key(s32 serial, u64 flags)
13231316
*/
13241317
__bpf_kfunc struct bpf_key *bpf_lookup_system_key(u64 id)
13251318
{
1326-
struct bpf_key *bkey;
1327-
13281319
if (system_keyring_id_check(id) < 0)
13291320
return NULL;
13301321

1331-
bkey = kmalloc(sizeof(*bkey), GFP_ATOMIC);
1332-
if (!bkey)
1333-
return NULL;
1334-
1335-
bkey->key = (struct key *)(unsigned long)id;
1336-
1337-
return bkey;
1322+
return (struct bpf_key *)(unsigned long)(id ? id : BUILTIN_KEY);
13381323
}
13391324

13401325
/**
@@ -1346,10 +1331,11 @@ __bpf_kfunc struct bpf_key *bpf_lookup_system_key(u64 id)
13461331
*/
13471332
__bpf_kfunc void bpf_key_put(struct bpf_key *bkey)
13481333
{
1349-
if (system_keyring_id_check((unsigned long)bkey->key) < 0)
1350-
key_put(bkey->key);
1334+
struct key *key = (struct key *)bkey;
13511335

1352-
kfree(bkey);
1336+
if (system_keyring_id_check((unsigned long)key) < 0 &&
1337+
(unsigned long)key != BUILTIN_KEY)
1338+
key_put(key);
13531339
}
13541340

13551341
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
@@ -1370,11 +1356,15 @@ __bpf_kfunc int bpf_verify_pkcs7_signature(struct bpf_dynptr *data_p,
13701356
{
13711357
struct bpf_dynptr_kern *data_ptr = (struct bpf_dynptr_kern *)data_p;
13721358
struct bpf_dynptr_kern *sig_ptr = (struct bpf_dynptr_kern *)sig_p;
1359+
struct key *key = (struct key *)trusted_keyring;
13731360
const void *data, *sig;
13741361
u32 data_len, sig_len;
13751362
int ret;
13761363

1377-
if (system_keyring_id_check((unsigned long)trusted_keyring->key) < 0) {
1364+
if ((unsigned long)key == BUILTIN_KEY)
1365+
key = NULL;
1366+
1367+
if (system_keyring_id_check((unsigned long)key) < 0) {
13781368
/*
13791369
* Do the permission check deferred in bpf_lookup_user_key().
13801370
* See bpf_lookup_user_key() for more details.
@@ -1383,7 +1373,7 @@ __bpf_kfunc int bpf_verify_pkcs7_signature(struct bpf_dynptr *data_p,
13831373
* it is already done by keyring_search() called by
13841374
* find_asymmetric_key().
13851375
*/
1386-
ret = key_validate(trusted_keyring->key);
1376+
ret = key_validate(key);
13871377
if (ret < 0)
13881378
return ret;
13891379
}
@@ -1393,8 +1383,7 @@ __bpf_kfunc int bpf_verify_pkcs7_signature(struct bpf_dynptr *data_p,
13931383
sig_len = __bpf_dynptr_size(sig_ptr);
13941384
sig = __bpf_dynptr_data(sig_ptr, sig_len);
13951385

1396-
return verify_pkcs7_signature(data, data_len, sig, sig_len,
1397-
trusted_keyring->key,
1386+
return verify_pkcs7_signature(data, data_len, sig, sig_len, key,
13981387
VERIFYING_UNSPECIFIED_SIGNATURE, NULL,
13991388
NULL);
14001389
}

0 commit comments

Comments
 (0)