From patchwork Tue Aug 9 13:46:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roberto Sassu X-Patchwork-Id: 12939646 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3B44C3F6B0 for ; Tue, 9 Aug 2022 13:49:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239519AbiHINtk (ORCPT ); Tue, 9 Aug 2022 09:49:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244351AbiHINsB (ORCPT ); Tue, 9 Aug 2022 09:48:01 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C6D63193C9; Tue, 9 Aug 2022 06:48:00 -0700 (PDT) Received: from fraeml714-chm.china.huawei.com (unknown [172.18.147.207]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4M2Dph5fjRz687XH; Tue, 9 Aug 2022 21:45:16 +0800 (CST) Received: from roberto-ThinkStation-P620.huawei.com (10.204.63.22) by fraeml714-chm.china.huawei.com (10.206.15.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Tue, 9 Aug 2022 15:47:57 +0200 From: Roberto Sassu To: , , , , , , , , , , , , , , , , , , , CC: , , , , , , Roberto Sassu Subject: [PATCH v9 07/10] bpf: Add bpf_verify_pkcs7_signature() kfunc Date: Tue, 9 Aug 2022 15:46:00 +0200 Message-ID: <20220809134603.1769279-8-roberto.sassu@huawei.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809134603.1769279-1-roberto.sassu@huawei.com> References: <20220809134603.1769279-1-roberto.sassu@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.204.63.22] X-ClientProxiedBy: lhrpeml500006.china.huawei.com (7.191.161.198) To fraeml714-chm.china.huawei.com (10.206.15.33) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net 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 --- kernel/trace/bpf_trace.c | 56 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 33ca4cfe6e26..79ba8c96735a 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -1290,6 +1291,47 @@ noinline __weak void bpf_key_put(struct bpf_key *bkey) kfree(bkey); } +#ifdef CONFIG_SYSTEM_DATA_VERIFICATION +/** + * bpf_verify_pkcs7_signature - verify a PKCS#7 signature + * @data_ptr: data to verify + * @sig_ptr: signature of the data + * @trusted_keyring: keyring with keys trusted for signature verification + * + * Verify the PKCS#7 signature *sig_ptr* against the supplied *data_ptr* + * with keys in a keyring referenced by *trusted_keyring*. + * + * Return: 0 on success, a negative value on error. + */ +noinline __weak int bpf_verify_pkcs7_signature(struct bpf_dynptr_kern *data_ptr, + struct bpf_dynptr_kern *sig_ptr, + struct bpf_key *trusted_keyring) +{ + int ret; + + if (trusted_keyring->valid_ptr) { + /* + * Do the permission check deferred in bpf_lookup_user_key(). + * + * A call to key_task_permission() here would be redundant, as + * it is already done by keyring_search() called by + * find_asymmetric_key(). + */ + ret = key_validate(trusted_keyring->key); + if (ret < 0) + return ret; + } + + return verify_pkcs7_signature(data_ptr->data, + bpf_dynptr_get_size(data_ptr), + sig_ptr->data, + bpf_dynptr_get_size(sig_ptr), + trusted_keyring->key, + VERIFYING_UNSPECIFIED_SIGNATURE, NULL, + NULL); +} +#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */ + __diag_pop(); BTF_SET8_START(key_kfunc_set) @@ -1303,11 +1345,25 @@ static const struct btf_kfunc_id_set bpf_key_kfunc_set = { .owner = THIS_MODULE, .set = &key_kfunc_set, }; + +#ifdef CONFIG_SYSTEM_DATA_VERIFICATION +BTF_SET8_START(verify_sig_kfunc_set) +BTF_ID_FLAGS(func, bpf_verify_pkcs7_signature, KF_SLEEPABLE) +BTF_SET8_END(verify_sig_kfunc_set) + +static const struct btf_kfunc_id_set bpf_verify_sig_kfunc_set = { + .owner = THIS_MODULE, + .set = &verify_sig_kfunc_set, +}; +#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */ #endif /* CONFIG_KEYS */ const struct btf_kfunc_id_set *kfunc_sets[] = { #ifdef CONFIG_KEYS &bpf_key_kfunc_set, +#ifdef CONFIG_SYSTEM_DATA_VERIFICATION + &bpf_verify_sig_kfunc_set, +#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */ #endif /* CONFIG_KEYS */ };