Skip to content

Commit 865b056

Browse files
robertosassuAlexei Starovoitov
authored andcommitted
bpf: Add bpf_verify_pkcs7_signature() kfunc
Add the bpf_verify_pkcs7_signature() kfunc, to give eBPF security modules the ability to check the validity of a signature against supplied data, by using user-provided or system-provided keys as trust anchor. The new kfunc makes it possible to enforce mandatory policies, as eBPF programs might be allowed to make security decisions only based on data sources the system administrator approves. The caller should provide the data to be verified and the signature as eBPF dynamic pointers (to minimize the number of parameters) and a bpf_key structure containing a reference to the keyring with keys trusted for signature verification, obtained from bpf_lookup_user_key() or bpf_lookup_system_key(). For bpf_key structures obtained from the former lookup function, bpf_verify_pkcs7_signature() completes the permission check deferred by that function by calling key_validate(). key_task_permission() is already called by the PKCS#7 code. Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Acked-by: KP Singh <kpsingh@kernel.org> Acked-by: Song Liu <song@kernel.org> Link: https://lore.kernel.org/r/20220920075951.929132-9-roberto.sassu@huaweicloud.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent f3cf413 commit 865b056

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

kernel/trace/bpf_trace.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,12 +1294,57 @@ void bpf_key_put(struct bpf_key *bkey)
12941294
kfree(bkey);
12951295
}
12961296

1297+
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
1298+
/**
1299+
* bpf_verify_pkcs7_signature - verify a PKCS#7 signature
1300+
* @data_ptr: data to verify
1301+
* @sig_ptr: signature of the data
1302+
* @trusted_keyring: keyring with keys trusted for signature verification
1303+
*
1304+
* Verify the PKCS#7 signature *sig_ptr* against the supplied *data_ptr*
1305+
* with keys in a keyring referenced by *trusted_keyring*.
1306+
*
1307+
* Return: 0 on success, a negative value on error.
1308+
*/
1309+
int bpf_verify_pkcs7_signature(struct bpf_dynptr_kern *data_ptr,
1310+
struct bpf_dynptr_kern *sig_ptr,
1311+
struct bpf_key *trusted_keyring)
1312+
{
1313+
int ret;
1314+
1315+
if (trusted_keyring->has_ref) {
1316+
/*
1317+
* Do the permission check deferred in bpf_lookup_user_key().
1318+
* See bpf_lookup_user_key() for more details.
1319+
*
1320+
* A call to key_task_permission() here would be redundant, as
1321+
* it is already done by keyring_search() called by
1322+
* find_asymmetric_key().
1323+
*/
1324+
ret = key_validate(trusted_keyring->key);
1325+
if (ret < 0)
1326+
return ret;
1327+
}
1328+
1329+
return verify_pkcs7_signature(data_ptr->data,
1330+
bpf_dynptr_get_size(data_ptr),
1331+
sig_ptr->data,
1332+
bpf_dynptr_get_size(sig_ptr),
1333+
trusted_keyring->key,
1334+
VERIFYING_UNSPECIFIED_SIGNATURE, NULL,
1335+
NULL);
1336+
}
1337+
#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
1338+
12971339
__diag_pop();
12981340

12991341
BTF_SET8_START(key_sig_kfunc_set)
13001342
BTF_ID_FLAGS(func, bpf_lookup_user_key, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE)
13011343
BTF_ID_FLAGS(func, bpf_lookup_system_key, KF_ACQUIRE | KF_RET_NULL)
13021344
BTF_ID_FLAGS(func, bpf_key_put, KF_RELEASE)
1345+
#ifdef CONFIG_SYSTEM_DATA_VERIFICATION
1346+
BTF_ID_FLAGS(func, bpf_verify_pkcs7_signature, KF_SLEEPABLE)
1347+
#endif
13031348
BTF_SET8_END(key_sig_kfunc_set)
13041349

13051350
static const struct btf_kfunc_id_set bpf_key_sig_kfunc_set = {

0 commit comments

Comments
 (0)