From nobody Tue Dec 16 18:24:45 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8445F29E0E9; Thu, 11 Dec 2025 02:13:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419190; cv=none; b=nDp1EaNj3s1zzHzkVTCQ8F3eae9/AUuA6GUQFihNnn2X0+z1WA24R5ey+VFsOVHFBXfE2PM6c+ASz+u5ntChNyJxjze4FKMraFzAqHS7qK5tOt1B4N8cP+7fJ99wujwA4KZxDXJ0u+ns/QQm49c+JodcENW5gPws2IXBmP5sB8I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419190; c=relaxed/simple; bh=EnGiHEm9aGF2u/99xjps75HkgVTAf3Nk48cIKh8tNhQ=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GU/c72pRRPuB+NVFHNl0NLL3as6GHe3lsjr1M6ki7a6IFrjoU5SNmHX+AsI2JMCD9jrqPTbyXrbtqkRqj/gYGUOrftFloDIErlWVkcHNsKOHSAqEEZdnyUDd8J6a60hdT+2Q/ziVCQVTaTxsV1FPSjtgaEL5/3SADk48UtTo238= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=NB2GEFzR; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="NB2GEFzR" Received: from narnia.corp.microsoft.com (unknown [40.78.12.133]) by linux.microsoft.com (Postfix) with ESMTPSA id 6ABB82116046; Wed, 10 Dec 2025 18:13:06 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 6ABB82116046 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1765419187; bh=pBzf1U6ZcM688vxJ5/17BBJF3dIBqraUdIOtwoNeOGs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=NB2GEFzRFGNPoMukgjkk2PAV8AH6SZE2EncoJuKJSr9RDqIRtDNZtYpYB8Du7xQw2 0A4bmDNd9T2UcoIKbdXK49T96bYWSrLqB6HhRd+g4UZ+gu+Id4x3QQfZQ8KfqeKM8f FbhMBuKuuLSXl3cvGvNQfYbfSND35qZZOpxhCMbk= From: Blaise Boscaccy To: Blaise Boscaccy , Jonathan Corbet , Paul Moore , James Morris , "Serge E. Hallyn" , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , =?UTF-8?q?G=C3=BCnther=20Noack?= , "Dr. David Alan Gilbert" , Andrew Morton , James.Bottomley@HansenPartnership.com, dhowells@redhat.com, linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [RFC 01/11] lsm: framework for BPF integrity verification Date: Wed, 10 Dec 2025 18:11:56 -0800 Message-ID: <20251211021257.1208712-2-bboscaccy@linux.microsoft.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> References: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Paul Moore Add a new LSM hook and two new LSM hook callbacks to support LSMs that perform integrity verification, e.g. digital signature verification, of BPF programs. While the BPF subsystem does implement a signature verification scheme, it does not satisfy a number of existing requirements, adding support for BPF program integrity verification to the LSM framework allows administrators to select additional integrity verification mechanisms to meet these needs while also providing a mechanism for future expansion. Additional on why this is necessary can be found at the lore archive link below: https://lore.kernel.org/linux-security-module/CAHC9VhTQ_DR=3DANzoDBjcCtrimV= 7XcCZVUsANPt=3DTjcvM4d-vjg@mail.gmail.com/ The LSM-based BPF integrity verification mechanism works within the existing security_bpf_prog_load() hook called by the BPF subsystem. It adds an additional dedicated integrity callback and a new LSM hook/callback to be called from within LSMs implementing integrity verification. The first new callback, bpf_prog_load_integrity(), located within the security_bpf_prog_load() hook, is necessary to ensure that the integrity verification callbacks are executed before any of the existing LSMs are executed via the bpf_prog_load() callback. Reusing the existing bpf_prog_load() callback for integrity verification could result in LSMs not having access to the integrity verification results when asked to authorize the BPF program load in the bpf_prog_load() callback. The new LSM hook, security_bpf_prog_load_post_integrity(), is intended to be called from within LSMs performing BPF program integrity verification. It is used to report the verdict of the integrity verification to other LSMs enforcing access control policy on BPF program loads. LSMs enforcing such access controls should register a bpf_prog_load_post_integrity() callback to receive integrity verdicts. More information on these new callbacks and hook can be found in the code comments in this patch. Signed-off-by: Paul Moore --- include/linux/lsm_hook_defs.h | 5 +++ include/linux/security.h | 25 ++++++++++++ security/security.c | 75 +++++++++++++++++++++++++++++++++-- 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 8c42b4bde09c0..4971d3c36d5b4 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -434,6 +434,11 @@ LSM_HOOK(int, 0, bpf_prog, struct bpf_prog *prog) LSM_HOOK(int, 0, bpf_map_create, struct bpf_map *map, union bpf_attr *attr, struct bpf_token *token, bool kernel) LSM_HOOK(void, LSM_RET_VOID, bpf_map_free, struct bpf_map *map) +LSM_HOOK(int, 0, bpf_prog_load_post_integrity, struct bpf_prog *prog, + union bpf_attr *attr, struct bpf_token *token, bool kernel, + const struct lsm_id *lsmid, enum lsm_integrity_verdict verdict) +LSM_HOOK(int, 0, bpf_prog_load_integrity, struct bpf_prog *prog, + union bpf_attr *attr, struct bpf_token *token, bool kernel) LSM_HOOK(int, 0, bpf_prog_load, struct bpf_prog *prog, union bpf_attr *att= r, struct bpf_token *token, bool kernel) LSM_HOOK(void, LSM_RET_VOID, bpf_prog_free, struct bpf_prog *prog) diff --git a/include/linux/security.h b/include/linux/security.h index 92ac3f27b9733..86bb4337d6e81 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -67,6 +67,7 @@ enum fs_value_type; struct watch; struct watch_notification; struct lsm_ctx; +struct lsm_id; =20 /* Default (no) options for the capable function */ #define CAP_OPT_NONE 0x0 @@ -99,6 +100,14 @@ enum lsm_integrity_type { LSM_INT_FSVERITY_BUILTINSIG_VALID, }; =20 +enum lsm_integrity_verdict { + LSM_INT_VERDICT_NONE =3D 0, + LSM_INT_VERDICT_OK, + LSM_INT_VERDICT_UNSIGNED, + LSM_INT_VERDICT_PARTIALSIG, + LSM_INT_VERDICT_BADSIG, +}; + /* * These are reasons that can be passed to the security_locked_down() * LSM hook. Lockdown reasons that protect kernel integrity (ie, the @@ -2272,6 +2281,12 @@ extern int security_bpf_prog(struct bpf_prog *prog); extern int security_bpf_map_create(struct bpf_map *map, union bpf_attr *at= tr, struct bpf_token *token, bool kernel); extern void security_bpf_map_free(struct bpf_map *map); +extern int security_bpf_prog_load_post_integrity(struct bpf_prog *prog, + union bpf_attr *attr, + struct bpf_token *token, + bool kernel, + const struct lsm_id *lsmid, + enum lsm_integrity_verdict verdict); extern int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *a= ttr, struct bpf_token *token, bool kernel); extern void security_bpf_prog_free(struct bpf_prog *prog); @@ -2306,6 +2321,16 @@ static inline int security_bpf_map_create(struct bpf= _map *map, union bpf_attr *a static inline void security_bpf_map_free(struct bpf_map *map) { } =20 +static inline int security_bpf_prog_load_post_integrity(struct bpf_prog *p= rog, + union bpf_attr *attr, + struct bpf_token *token, + bool kernel, + const struct lsm_id *lsmid, + enum lsm_integrity_verdict verdict) +{ + return 0; +} + static inline int security_bpf_prog_load(struct bpf_prog *prog, union bpf_= attr *attr, struct bpf_token *token, bool kernel) { diff --git a/security/security.c b/security/security.c index 4d3c03a4524c5..e3f4ad45d24f0 100644 --- a/security/security.c +++ b/security/security.c @@ -5779,6 +5779,50 @@ int security_bpf_map_create(struct bpf_map *map, uni= on bpf_attr *attr, return rc; } =20 +/** + * security_bpf_prog_load_post_integrity() - Check if the BPF prog is allo= wed + * @prog: BPF program object + * @attr: BPF syscall attributes used to create BPF program + * @token: BPF token used to grant user access to BPF subsystem + * @kernel: whether or not call originated from kernel + * @lsmid: LSM ID of the LSM providing @verdict + * @verdict: result of the integrity verification + * + * See the comment block for the security_bpf_prog_load() LSM hook. + * + * This LSM hook is intended to be called from within the + * bpf_prog_load_integrity() callback that is part of the + * security_bpf_prog_load() hook; kernel subsystems outside the scope of t= he + * LSM framework should not call this hook directly. + * + * If the LSM calling into this hook receives a non-zero error code, it sh= ould + * return the same error code back to its caller. If this hook returns a = zero, + * it does not necessarily mean that all of the enabled LSMs have authoriz= ed + * the BPF program load, as there may be other LSMs implementing BPF integ= rity + * checks which have yet to execute. However, if a zero is returned, the = LSM + * calling into this hook should continue and return zero back to its call= er. + * + * LSMs which implement the bpf_prog_load_post_integrity() callback and + * determine that a particular BPF program load is not authorized may choo= se to + * either return an error code for immediate rejection, or store their dec= ision + * in their own LSM state attached to @prog, later returning an error code= in + * the bpf_prog_load() callback. An immediate error code return is in kee= ping + * with the "fail fast" practice, but waiting until the bpf_prog_load() + * callback allows the LSM to consider multiple different integrity verdic= ts. + * + * Return: Returns 0 on success, error on failure. + */ +int security_bpf_prog_load_post_integrity(struct bpf_prog *prog, + union bpf_attr *attr, + struct bpf_token *token, + bool kernel, + const struct lsm_id *lsmid, + enum lsm_integrity_verdict verdict) +{ + return call_int_hook(bpf_prog_load_post_integrity, prog, attr, token, + kernel, lsmid, verdict); +} + /** * security_bpf_prog_load() - Check if loading of BPF program is allowed * @prog: BPF program object @@ -5787,8 +5831,24 @@ int security_bpf_map_create(struct bpf_map *map, uni= on bpf_attr *attr, * @kernel: whether or not call originated from kernel * * Perform an access control check when the kernel loads a BPF program and - * allocates associated BPF program object. This hook is also responsible = for - * allocating any required LSM state for the BPF program. + * allocates the associated BPF program object. This hook is also responsi= ble + * for allocating any required LSM state for the BPF program. + * + * This hook calls two LSM callbacks: bpf_prog_load_integrity() and + * bpf_prog_load(). The bpf_prog_load_integrity() callback is for those L= SMs + * that wish to implement integrity verifications of BPF programs, e.g. + * signature verification, while the bpf_prog_load() callback is for gener= al + * authorization of the BPF program load. Performing both verification and + * authorization in a single callback, with arbitrary LSM ordering, would = be + * a challenge. + * + * LSMs which implement the bpf_prog_load_integrity() callback should call= into + * the security_bpf_prog_load_post_integrity() hook with their integrity + * verdict. LSMs which implement BPF program integrity policy can registe= r a + * callback for the security_bpf_prog_load_post_integrity() hook and + * either update their own internal state based on the verdict, or immedia= tely + * reject the BPF program load with an error code. See the comment block = for + * security_bpf_prog_load_post_integrity() for more information. * * Return: Returns 0 on success, error on failure. */ @@ -5801,9 +5861,18 @@ int security_bpf_prog_load(struct bpf_prog *prog, un= ion bpf_attr *attr, if (unlikely(rc)) return rc; =20 + rc =3D call_int_hook(bpf_prog_load_integrity, prog, attr, token, kernel); + if (unlikely(rc)) + goto err; + rc =3D call_int_hook(bpf_prog_load, prog, attr, token, kernel); if (unlikely(rc)) - security_bpf_prog_free(prog); + goto err; + + return rc; + +err: + security_bpf_prog_free(prog); return rc; } =20 --=20 2.52.0 From nobody Tue Dec 16 18:24:45 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7C9112BF3CA; Thu, 11 Dec 2025 02:13:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419192; cv=none; b=JbjWzVTtwO/swDRo6MChFDSnLwr/tSSwDmsjqKAeixBzOOL9cPOUOcb1Fcv+2u5/r6btaHaM98kHRjPFw3G6oLKtIUsysLxvvNKwVqrEUp5IvHd89Qg8Ah8PUBJumCN4qJCF/fzcni2rnrV7523Uo9jXLn6rjxtxCGWVmZNGHic= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419192; c=relaxed/simple; bh=Dqc8agm8gURJma6ClOZJYRfjbrKP4jFtpJg3r3rg1jc=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HfLy9aMLrUtVT1XSx83uPbG5InxjI3TOjd2+EScrtnfXy6WiGWZnDATyo7vOcSytCA3M9waxUOXWFACw1Y95x2fL+l077yDLjNtkM7hA8bYNABp0BkOmJb+kOB9X7F4/h48C/GVykNzBMb0Uafj/KNixGTQl/P1Qov9Zkt4yWR8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=mGmASbiz; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="mGmASbiz" Received: from narnia.corp.microsoft.com (unknown [40.78.12.133]) by linux.microsoft.com (Postfix) with ESMTPSA id 9C9752116049; Wed, 10 Dec 2025 18:13:08 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 9C9752116049 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1765419189; bh=sGawIizX9EcFfZvX74eliwpwV9cGLLP4TSAKVsWNDnQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=mGmASbizNb3JewyGTx+YCgfhaCkgTnrt7aqqU5tlQUMMEUT0zXd0+OzGiI/ds0meX eGnGnUdk2zN2eDfHdfiExvIzOqMKFQ/IB68StwTqTyXxNCyu20YAvTsGePrWYVZlty BQGD30ZLGc2HDSblOjqpZzN2EeYjnhFGULUfpMjc= From: Blaise Boscaccy To: Blaise Boscaccy , Jonathan Corbet , Paul Moore , James Morris , "Serge E. Hallyn" , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , =?UTF-8?q?G=C3=BCnther=20Noack?= , "Dr. David Alan Gilbert" , Andrew Morton , James.Bottomley@HansenPartnership.com, dhowells@redhat.com, linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [RFC 02/11] oid_registry: allow arbitrary size OIDs Date: Wed, 10 Dec 2025 18:11:57 -0800 Message-ID: <20251211021257.1208712-3-bboscaccy@linux.microsoft.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> References: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: James Bottomley The current OID registry parser uses 64 bit arithmetic which limits us to supporting 64 bit or smaller OIDs. This isn't usually a problem except that it prevents us from representing the 2.25. prefix OIDs which are the OID representation of UUIDs and have a 128 bit number following the prefix. Rather than import not often used perl arithmetic modules, replace the current perl 64 bit arithmetic with a callout to bc, which is arbitrary precision, for decimal to base 2 conversion, then do pure string operations on the base 2 number. Signed-off-by: James Bottomley --- lib/build_OID_registry | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/lib/build_OID_registry b/lib/build_OID_registry index 8267e8d71338b..30493ac190c0c 100755 --- a/lib/build_OID_registry +++ b/lib/build_OID_registry @@ -60,10 +60,12 @@ for (my $i =3D 0; $i <=3D $#names; $i++) { # Determine the encoded length of this OID my $size =3D $#components; for (my $loop =3D 2; $loop <=3D $#components; $loop++) { - my $c =3D $components[$loop]; + $ENV{'BC_LINE_LENGTH'} =3D "0"; + my $c =3D `echo "ibase=3D10; obase=3D2; $components[$loop]" | bc`; + chomp($c); =20 # We will base128 encode the number - my $tmp =3D ($c =3D=3D 0) ? 0 : int(log($c)/log(2)); + my $tmp =3D length($c) - 1; $tmp =3D int($tmp / 7); $size +=3D $tmp; } @@ -100,16 +102,24 @@ for (my $i =3D 0; $i <=3D $#names; $i++) { push @octets, $components[0] * 40 + $components[1]; =20 for (my $loop =3D 2; $loop <=3D $#components; $loop++) { - my $c =3D $components[$loop]; + # get the base 2 representation of the component + $ENV{'BC_LINE_LENGTH'} =3D "0"; + my $c =3D `echo "ibase=3D10; obase=3D2; $components[$loop]" | bc`; + chomp($c); =20 - # Base128 encode the number - my $tmp =3D ($c =3D=3D 0) ? 0 : int(log($c)/log(2)); + my $tmp =3D length($c) - 1; $tmp =3D int($tmp / 7); =20 - for (; $tmp > 0; $tmp--) { - push @octets, (($c >> $tmp * 7) & 0x7f) | 0x80; + # zero pad upto length multiple of 7 + $c =3D substr("0000000", 0, ($tmp + 1) * 7 - length($c)).$c; + + # Base128 encode the number + for (my $j =3D 0; $j < $tmp; $j++) { + my $b =3D oct("0b".substr($c, $j * 7, 7)); + + push @octets, $b | 0x80; } - push @octets, $c & 0x7f; + push @octets, oct("0b".substr($c, $tmp * 7, 7)); } =20 push @encoded_oids, \@octets; --=20 2.52.0 From nobody Tue Dec 16 18:24:45 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C35D62D8364; Thu, 11 Dec 2025 02:13:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419194; cv=none; b=qXXVqKjmMo9QDkcxQErCpQOPs9+HJkMsEgnDl4MKQyzkBi9DPY/klrNoQKQwqt6I64kVUbVsoZF2OddzAs6hD7c8CaHc0Jc+Vuhc3FGTFUYOSFSR4Y3DTxHcoDpaBIsO9szNr1V6/7QQzgOWo4nKTOdAkjntgBx/Avm/2sDoTJU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419194; c=relaxed/simple; bh=JdRHlwoj2ekW+YizjrNg1K6XKl5v6vm6K00XxhLHug0=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NDGVnzucxBJbttCdf9AyRM41Df+O3xjQqptlTJoa5ATz2DU3ZzUjohOhIvXjWxzE+9Er84t75ubQ+ly4YpYi7TIb9t0FFY0NRm/yYfGJR0O8/q5+VOwIqdhFsrT6mzCYMTm4GmLUrRn5XrUxlP0lEa8m4jtuH4Fg0X74AHuLlYw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=lInPFTOn; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="lInPFTOn" Received: from narnia.corp.microsoft.com (unknown [40.78.12.133]) by linux.microsoft.com (Postfix) with ESMTPSA id 7E9742116043; Wed, 10 Dec 2025 18:13:10 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 7E9742116043 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1765419191; bh=+cUv2YDEFdHJCABGsGpyw43sJvYTINrg6wV3aMZO9tA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=lInPFTOn4wx3xXJvPmVHSA+UW+dfQ8jMkTogn8fpkrSKOKbgyaEiWFeYjLofv1lIW uoR1wD28HDfE90fhOQSVcOmDkj8o55b37kTLPoaJwjy65DwQ5aBLtfdtZGCkGpRs1k 61IajokQEKz1bL9VS82K3CJrOWKzIXzd87QtY+y8= From: Blaise Boscaccy To: Blaise Boscaccy , Jonathan Corbet , Paul Moore , James Morris , "Serge E. Hallyn" , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , =?UTF-8?q?G=C3=BCnther=20Noack?= , "Dr. David Alan Gilbert" , Andrew Morton , James.Bottomley@HansenPartnership.com, dhowells@redhat.com, linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [RFC 03/11] certs: break out pkcs7 check into its own function Date: Wed, 10 Dec 2025 18:11:58 -0800 Message-ID: <20251211021257.1208712-4-bboscaccy@linux.microsoft.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> References: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: James Bottomley Add new validate_pkcs7_trust() function which can operate on the system keyrings and is simply some of the innards of verify_pkcs7_message_sig(). Signed-off-by: James Bottomley --- certs/system_keyring.c | 76 +++++++++++++++++++++--------------- include/linux/verification.h | 2 + 2 files changed, 47 insertions(+), 31 deletions(-) diff --git a/certs/system_keyring.c b/certs/system_keyring.c index 9de610bf1f4b2..807ab4a6fc7ea 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@ -298,42 +298,19 @@ late_initcall(load_system_certificate_list); #ifdef CONFIG_SYSTEM_DATA_VERIFICATION =20 /** - * verify_pkcs7_message_sig - Verify a PKCS#7-based signature on system da= ta. - * @data: The data to be verified (NULL if expecting internal data). - * @len: Size of @data. + * validate_pkcs7_trust - add trust markers based on keyring * @pkcs7: The PKCS#7 message that is the signature. * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only, * (void *)1UL for all trusted keys). - * @usage: The use to which the key is being put. - * @view_content: Callback to gain access to content. - * @ctx: Context for callback. */ -int verify_pkcs7_message_sig(const void *data, size_t len, - struct pkcs7_message *pkcs7, - struct key *trusted_keys, - enum key_being_used_for usage, - int (*view_content)(void *ctx, - const void *data, size_t len, - size_t asn1hdrlen), - void *ctx) +int validate_pkcs7_trust(struct pkcs7_message *pkcs7, struct key *trusted_= keys) { int ret; =20 - /* The data should be detached - so we need to supply it. */ - if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) { - pr_err("PKCS#7 signature with non-detached data\n"); - ret =3D -EBADMSG; - goto error; - } - - ret =3D pkcs7_verify(pkcs7, usage); - if (ret < 0) - goto error; - ret =3D is_key_on_revocation_list(pkcs7); if (ret !=3D -ENOKEY) { pr_devel("PKCS#7 key is on revocation list\n"); - goto error; + return ret; } =20 if (!trusted_keys) { @@ -351,18 +328,55 @@ int verify_pkcs7_message_sig(const void *data, size_t= len, trusted_keys =3D NULL; #endif if (!trusted_keys) { - ret =3D -ENOKEY; pr_devel("PKCS#7 platform keyring is not available\n"); - goto error; + return -ENOKEY; } } ret =3D pkcs7_validate_trust(pkcs7, trusted_keys); - if (ret < 0) { - if (ret =3D=3D -ENOKEY) - pr_devel("PKCS#7 signature not signed with a trusted key\n"); + if (ret =3D=3D -ENOKEY) + pr_devel("PKCS#7 signature not signed with a trusted key\n"); + + return ret; +} +EXPORT_SYMBOL_GPL(validate_pkcs7_trust); + +/** + * verify_pkcs7_message_sig - Verify a PKCS#7-based signature on system da= ta. + * @data: The data to be verified (NULL if expecting internal data). + * @len: Size of @data. + * @pkcs7: The PKCS#7 message that is the signature. + * @trusted_keys: Trusted keys to use (NULL for builtin trusted keys only, + * (void *)1UL for all trusted keys). + * @usage: The use to which the key is being put. + * @view_content: Callback to gain access to content. + * @ctx: Context for callback. + */ +int verify_pkcs7_message_sig(const void *data, size_t len, + struct pkcs7_message *pkcs7, + struct key *trusted_keys, + enum key_being_used_for usage, + int (*view_content)(void *ctx, + const void *data, size_t len, + size_t asn1hdrlen), + void *ctx) +{ + int ret; + + /* The data should be detached - so we need to supply it. */ + if (data && pkcs7_supply_detached_data(pkcs7, data, len) < 0) { + pr_err("PKCS#7 signature with non-detached data\n"); + ret =3D -EBADMSG; goto error; } =20 + ret =3D pkcs7_verify(pkcs7, usage); + if (ret < 0) + goto error; + + ret =3D validate_pkcs7_trust(pkcs7, trusted_keys); + if (ret < 0) + goto error; + if (view_content) { size_t asn1hdrlen; =20 diff --git a/include/linux/verification.h b/include/linux/verification.h index dec7f2beabfd4..57f1460d36f13 100644 --- a/include/linux/verification.h +++ b/include/linux/verification.h @@ -44,6 +44,8 @@ enum key_being_used_for { struct key; struct pkcs7_message; =20 +extern int validate_pkcs7_trust(struct pkcs7_message *pkcs7, + struct key *trusted_keys); extern int verify_pkcs7_signature(const void *data, size_t len, const void *raw_pkcs7, size_t pkcs7_len, struct key *trusted_keys, --=20 2.52.0 From nobody Tue Dec 16 18:24:45 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 89CAA29E0E9; Thu, 11 Dec 2025 02:13:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419198; cv=none; b=GNLUgVgpmLPph1XnsdvyMCjJ4F1yzZQzg/M2RwJ9p4eP3mVLHH6aNLyM0DAxJL3Ixzr6uLe5U/qTBlOmDYh+c/3vDnvBzY/69GvYb6bprQq0b4Rz+YNod+hgwUC+cxU/a9JHqFRSPoDkF+GxEgKDtrD0nbfJqOtRC4xcNytULFU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419198; c=relaxed/simple; bh=A630HQfYPlZd5vfIXx3I+uZEiMWeX6QVi0xVneqndmI=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ojp6XYil/cBol2QUg/yg11F4xCbEJSqSWAO7EfU0uLo2gaXgVP+NSyvWVxzoVAzr0zio8p5Z4n4ygfgLVBpJ1zSqwVK6F3AkmQ8lhwRn0nCt7RlyiJeaFqaHlb0BxnA6ujqlTB0ebPdVvZhCBld1UCNTvnwhIeK0o/2XuGp1A4o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=AAHUNN3n; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="AAHUNN3n" Received: from narnia.corp.microsoft.com (unknown [40.78.12.133]) by linux.microsoft.com (Postfix) with ESMTPSA id 6093B2116048; Wed, 10 Dec 2025 18:13:12 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 6093B2116048 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1765419194; bh=gjqGNKnlJX8Kw8HH66jlxD/mVg+TXmoYb3hAeCnM2+M=; h=From:To:Subject:Date:In-Reply-To:References:From; b=AAHUNN3n4MpVwTJFBQ1qsmqZMiVGtxLLTkZFKp4Z5pZZwB5s6kxgoL31pyNRvFfFg TRVk46ShXn2ZggzadmU/ooz5n1Gb4ttGTu1q5UZwjsFC7N6yAIK5BSLrzjsVNpgkg3 1MLcljf7GIPRJmeMOOA/ibuwXWH8rMxVx4vgQfTA= From: Blaise Boscaccy To: Blaise Boscaccy , Jonathan Corbet , Paul Moore , James Morris , "Serge E. Hallyn" , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , =?UTF-8?q?G=C3=BCnther=20Noack?= , "Dr. David Alan Gilbert" , Andrew Morton , James.Bottomley@HansenPartnership.com, dhowells@redhat.com, linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [RFC 04/11] crypto: pkcs7: add flag for validated trust on a signed info block Date: Wed, 10 Dec 2025 18:11:59 -0800 Message-ID: <20251211021257.1208712-5-bboscaccy@linux.microsoft.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> References: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: James Bottomley Allow consumers of struct pkcs7_message to tell if any of the sinfo fields has passed a trust validation. Note that this does not happen in parsing, pkcs7_validate_trust() must be explicitly called or called via validate_pkcs7_trust(). Signed-off-by: James Bottomley --- crypto/asymmetric_keys/pkcs7_parser.h | 1 + crypto/asymmetric_keys/pkcs7_trust.c | 1 + 2 files changed, 2 insertions(+) diff --git a/crypto/asymmetric_keys/pkcs7_parser.h b/crypto/asymmetric_keys= /pkcs7_parser.h index e17f7ce4fb434..344340cfa6c13 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.h +++ b/crypto/asymmetric_keys/pkcs7_parser.h @@ -20,6 +20,7 @@ struct pkcs7_signed_info { unsigned index; bool unsupported_crypto; /* T if not usable due to missing crypto */ bool blacklisted; + bool verified; /* T if this signer has validated trust */ =20 /* Message digest - the digest of the Content Data (or NULL) */ const void *msgdigest; diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/= pkcs7_trust.c index 9a87c34ed1733..78ebfb6373b61 100644 --- a/crypto/asymmetric_keys/pkcs7_trust.c +++ b/crypto/asymmetric_keys/pkcs7_trust.c @@ -127,6 +127,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_messag= e *pkcs7, for (p =3D sinfo->signer; p !=3D x509; p =3D p->signer) p->verified =3D true; } + sinfo->verified =3D true; kleave(" =3D 0"); return 0; } --=20 2.52.0 From nobody Tue Dec 16 18:24:45 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6CFC12BEFEB; Thu, 11 Dec 2025 02:13:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419199; cv=none; b=SMlJk/o/7U9HI/7LnAyglomxshoxUhzF/WR2ehNcKdM6umHI18G36TEBLabL650ZTjOE74NPDd29Whql7e5v9noN9EpOXBQHKzRmE4j4kAql6Hcapd6s65yfbNr4EXcDLrhBdhFQmVO8VcMwiW7Ie+pZWi4JWQcEdD+idG66T4Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419199; c=relaxed/simple; bh=DKeu+qTEIr2iRtbwN3hwjCcXwv2PM3N3C/GTGIjIVlQ=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HEbVr2bAHkjhsphBJkQ0LRHCMCNtZEUBPiNtTbLPdTdMgkSzIedt8v1cMgU65AgqOM5QAGnuQQaUxe3HEWzOtyd1Qxcy8KRsmu/O/snl5b1Qe3l7X7g2hEY51k4KLoParfShTOlWAQWP0KWL2FtYlGNtmJRRkNIwiy0YCNDuxW0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=WdM0Sw7Q; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="WdM0Sw7Q" Received: from narnia.corp.microsoft.com (unknown [40.78.12.133]) by linux.microsoft.com (Postfix) with ESMTPSA id A68B02116046; Wed, 10 Dec 2025 18:13:15 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com A68B02116046 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1765419196; bh=4ifvqlY9jJPeiFBANJpL6uEefFDnll7LXYcCLrNqepU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=WdM0Sw7Qtg6sVKXeOC5de4kfwuHDuu7EIBUHc09vKwL9Qtr+h18vfunrqICjs8zYr f2pyGlhQHZmAZ+Zdtxvp2jvmH1cJne4k0ff90VgQ4n1TjUtt00+JwKuuGfnmwqq/LA 4mhORMX3fQMW5/DPyQn8vhN4SbPSVmU7ImacRsQA= From: Blaise Boscaccy To: Blaise Boscaccy , Jonathan Corbet , Paul Moore , James Morris , "Serge E. Hallyn" , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , =?UTF-8?q?G=C3=BCnther=20Noack?= , "Dr. David Alan Gilbert" , Andrew Morton , James.Bottomley@HansenPartnership.com, dhowells@redhat.com, linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [RFC 05/11] crypto: pkcs7: allow pkcs7_digest() to be called from pkcs7_trust Date: Wed, 10 Dec 2025 18:12:00 -0800 Message-ID: <20251211021257.1208712-6-bboscaccy@linux.microsoft.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> References: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: James Bottomley Trying to run pkcs7_validate_trust() on something that parsed correctly but is not verified doesn't work because the signature digest hasn't been calculated. Fix this by adding a digest calclation in to pkcs7_validate_one(). This is almost a nop if the digest exists. Additionally, the trust validation doesn't know the data payload, so adjust the digest calculator to skip checking the data digest if pkcs7->data is NULL. A check is added in pkcs7_verify() for pkcs7->data being null (returning -EBADMSG) to guard against someone forgetting to supply data and getting an invalid success return. Signed-off-by: James Bottomley --- crypto/asymmetric_keys/pkcs7_parser.h | 3 +++ crypto/asymmetric_keys/pkcs7_trust.c | 8 ++++++++ crypto/asymmetric_keys/pkcs7_verify.c | 13 +++++++++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/crypto/asymmetric_keys/pkcs7_parser.h b/crypto/asymmetric_keys= /pkcs7_parser.h index 344340cfa6c13..179cd1cdbe22d 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.h +++ b/crypto/asymmetric_keys/pkcs7_parser.h @@ -63,3 +63,6 @@ struct pkcs7_message { size_t data_hdrlen; /* Length of Data ASN.1 header */ const void *data; /* Content Data (or 0) */ }; + +int pkcs7_digest(struct pkcs7_message *pkcs7, + struct pkcs7_signed_info *sinfo); diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/= pkcs7_trust.c index 78ebfb6373b61..7cb0a6bc7b32e 100644 --- a/crypto/asymmetric_keys/pkcs7_trust.c +++ b/crypto/asymmetric_keys/pkcs7_trust.c @@ -30,6 +30,14 @@ static int pkcs7_validate_trust_one(struct pkcs7_message= *pkcs7, =20 kenter(",%u,", sinfo->index); =20 + /* + * if we're being called immediately after parse, the + * signature won't have a calculated digest yet, so calculate + * one. This function returns immediately if a digest has + * already been calculated + */ + pkcs7_digest(pkcs7, sinfo); + if (sinfo->unsupported_crypto) { kleave(" =3D -ENOPKG [cached]"); return -ENOPKG; diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys= /pkcs7_verify.c index 6d6475e3a9bf2..19b3999381e6f 100644 --- a/crypto/asymmetric_keys/pkcs7_verify.c +++ b/crypto/asymmetric_keys/pkcs7_verify.c @@ -19,8 +19,8 @@ /* * Digest the relevant parts of the PKCS#7 data */ -static int pkcs7_digest(struct pkcs7_message *pkcs7, - struct pkcs7_signed_info *sinfo) +int pkcs7_digest(struct pkcs7_message *pkcs7, + struct pkcs7_signed_info *sinfo) { struct public_key_signature *sig =3D sinfo->sig; struct crypto_shash *tfm; @@ -85,8 +85,8 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7, goto error; } =20 - if (memcmp(sig->digest, sinfo->msgdigest, - sinfo->msgdigest_len) !=3D 0) { + if (pkcs7->data && memcmp(sig->digest, sinfo->msgdigest, + sinfo->msgdigest_len) !=3D 0) { pr_warn("Sig %u: Message digest doesn't match\n", sinfo->index); ret =3D -EKEYREJECTED; @@ -439,6 +439,11 @@ int pkcs7_verify(struct pkcs7_message *pkcs7, return -EINVAL; } =20 + if (!pkcs7->data) { + pr_warn("Data not supplied to verify operation\n"); + return -EBADMSG; + } + for (sinfo =3D pkcs7->signed_infos; sinfo; sinfo =3D sinfo->next) { ret =3D pkcs7_verify_one(pkcs7, sinfo); if (sinfo->blacklisted) { --=20 2.52.0 From nobody Tue Dec 16 18:24:45 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8233F20A5C4; Thu, 11 Dec 2025 02:13:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419201; cv=none; b=M/i+ZHEFJUPGyTBrDRyDkHwdF7Y0oR90/UTczTlSuomWsBhEtgtRDaOxVGNedIZDyw6iiUzbAw8WSqYgHEzlLZJSt7D6vnNJlTo8zE5l5V/cPAkw/v+FdPZQScqvGBFeBtXrHAtCRVKN9CW36fbP9mn04/we3R3HfVB/I9SRuJo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419201; c=relaxed/simple; bh=n5wJ2CXG+nzcMIT49abvHtPdpHcRMOCEe5Imn/9joc0=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iHB8NgKyuxlekCCM7ZLLvISeOw10whVc473/2jsgmD2OdgC8foC5qmoePyMI4CryEwnNy9X3NiMOmAvfRPtxKJ2NCLb2lmTM6NK10plgXI46J5laY6ZfMnNEk6CjXY1p5dE7+xkInlii2SMoaTQGsVNPS8GbE/4CHc/wSs61JL0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=DlNL54mJ; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="DlNL54mJ" Received: from narnia.corp.microsoft.com (unknown [40.78.12.133]) by linux.microsoft.com (Postfix) with ESMTPSA id 725E22116043; Wed, 10 Dec 2025 18:13:17 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 725E22116043 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1765419198; bh=xtXBZp01Gf8QxqlxSJyJMsLhZkeyPe2aXuwT3ptpSmQ=; h=From:To:Subject:Date:In-Reply-To:References:From; b=DlNL54mJ5XJrKBGKOITEjuSJgEj+brxfKrtxQaDOm0Tby2HkFg4occlDpsAEw78+c TsB1QjfOJJRIHBcdqxkAuOLOdg/GCaruWPyYqA6ERZFum8MiIaL+UHD72NXZzRr03g xTfc1pcalKyXrmZd1YdkzfpWADowEc18rczYzcbA= From: Blaise Boscaccy To: Blaise Boscaccy , Jonathan Corbet , Paul Moore , James Morris , "Serge E. Hallyn" , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , =?UTF-8?q?G=C3=BCnther=20Noack?= , "Dr. David Alan Gilbert" , Andrew Morton , James.Bottomley@HansenPartnership.com, dhowells@redhat.com, linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [RFC 06/11] crypto: pkcs7: add ability to extract signed attributes by OID Date: Wed, 10 Dec 2025 18:12:01 -0800 Message-ID: <20251211021257.1208712-7-bboscaccy@linux.microsoft.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> References: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: James Bottomley Signers may add any information they like in signed attributes and sometimes this information turns out to be relevant to specific signing cases, so add an api pkcs7_get_authattr() to extract the value of an authenticated attribute by specific OID. The current implementation is designed for the single signer use case and simply terminates the search when it finds the relevant OID. Signed-off-by: James Bottomley --- crypto/asymmetric_keys/Makefile | 4 +- crypto/asymmetric_keys/pkcs7_aa.asn1 | 18 ++++++ crypto/asymmetric_keys/pkcs7_parser.c | 87 +++++++++++++++++++++++++++ include/crypto/pkcs7.h | 4 ++ 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 crypto/asymmetric_keys/pkcs7_aa.asn1 diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makef= ile index bc65d3b98dcbf..f99b7169ae7cd 100644 --- a/crypto/asymmetric_keys/Makefile +++ b/crypto/asymmetric_keys/Makefile @@ -53,12 +53,14 @@ clean-files +=3D pkcs8.asn1.c pkcs8.asn1.h obj-$(CONFIG_PKCS7_MESSAGE_PARSER) +=3D pkcs7_message.o pkcs7_message-y :=3D \ pkcs7.asn1.o \ + pkcs7_aa.asn1.o \ pkcs7_parser.o \ pkcs7_trust.o \ pkcs7_verify.o =20 -$(obj)/pkcs7_parser.o: $(obj)/pkcs7.asn1.h +$(obj)/pkcs7_parser.o: $(obj)/pkcs7.asn1.h $(obj)/pkcs7_aa.asn1.h $(obj)/pkcs7.asn1.o: $(obj)/pkcs7.asn1.c $(obj)/pkcs7.asn1.h +$(obj)/pkcs7_aa.asn1.o: $(obj)/pkcs7_aa.asn1.c $(obj)/pkcs7_aa.asn1.h =20 # # PKCS#7 parser testing key diff --git a/crypto/asymmetric_keys/pkcs7_aa.asn1 b/crypto/asymmetric_keys/= pkcs7_aa.asn1 new file mode 100644 index 0000000000000..7a8857bdf56e1 --- /dev/null +++ b/crypto/asymmetric_keys/pkcs7_aa.asn1 @@ -0,0 +1,18 @@ +-- SPDX-License-Identifier: BSD-3-Clause +-- +-- Copyright (C) 2009 IETF Trust and the persons identified as authors +-- of the code +-- +-- https://www.rfc-editor.org/rfc/rfc5652#section-3 + +AA ::=3D CHOICE { + aaSet [0] IMPLICIT AASet, + aaSequence [2] EXPLICIT SEQUENCE OF AuthenticatedAttribute +} + +AASet ::=3D SET OF AuthenticatedAttribute + +AuthenticatedAttribute ::=3D SEQUENCE { + type OBJECT IDENTIFIER ({ pkcs7_aa_note_OID }), + values SET OF ANY ({ pkcs7_aa_note_attr }) +} diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys= /pkcs7_parser.c index 423d13c475452..55bdcbad70952 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c @@ -15,6 +15,7 @@ #include #include "pkcs7_parser.h" #include "pkcs7.asn1.h" +#include "pkcs7_aa.asn1.h" =20 MODULE_DESCRIPTION("PKCS#7 parser"); MODULE_AUTHOR("Red Hat, Inc."); @@ -197,6 +198,92 @@ int pkcs7_get_content_data(const struct pkcs7_message = *pkcs7, } EXPORT_SYMBOL_GPL(pkcs7_get_content_data); =20 +struct pkcs7_aa_context { + bool found; + enum OID oid_to_find; + const void *data; + size_t len; +}; + +int pkcs7_aa_note_OID(void *context, size_t hdrlen, + unsigned char tag, + const void *value, size_t vlen) +{ + struct pkcs7_aa_context *ctx =3D context; + enum OID oid =3D look_up_OID(value, vlen); + + ctx->found =3D (oid =3D=3D ctx->oid_to_find); + + return 0; +} + +int pkcs7_aa_note_attr(void *context, size_t hdrlen, + unsigned char tag, + const void *value, size_t vlen) +{ + struct pkcs7_aa_context *ctx =3D context; + + if (ctx->found) { + ctx->data =3D value; + ctx->len =3D vlen; + } + + return 0; +} + +/** + * pkcs7_get_authattr - get authenticated attribute by OID + * @pkcs7: The preparsed PKCS#7 message + * @oid: the enum value of the OID to find + * @_data: Place to return a pointer to the attribute value + * @_len: length of the attribute value + * + * Searches the authenticated attributes until one is found with a + * matching OID. Note that because the attributes are per signer + * there could be multiple signers with different values, but this + * routine will simply return the first one in parse order. + * + * Returns -ENODATA if the attribute can't be found + */ +int pkcs7_get_authattr(const struct pkcs7_message *pkcs7, + enum OID oid, + const void **_data, size_t *_len) +{ + struct pkcs7_signed_info *sinfo =3D pkcs7->signed_infos; + struct pkcs7_aa_context ctx; + + ctx.data =3D NULL; + ctx.oid_to_find =3D oid; + + for (; sinfo; sinfo =3D sinfo->next) { + int ret; + + /* only extract OIDs from validated signers */ + if (!sinfo->verified) + continue; + + /* + * Note: authattrs is missing the initial tag for + * digesting reasons. Step one back in the stream to + * point to the initial tag for fully formed ASN.1 + */ + ret =3D asn1_ber_decoder(&pkcs7_aa_decoder, &ctx, + sinfo->authattrs - 1, + sinfo->authattrs_len + 1); + if (ret < 0 || ctx.data !=3D NULL) + break; + } + + if (!ctx.data) + return -ENODATA; + + *_data =3D ctx.data; + *_len =3D ctx.len; + + return 0; +} +EXPORT_SYMBOL_GPL(pkcs7_get_authattr); + /* * Note an OID when we find one for later processing when we know how * to interpret it. diff --git a/include/crypto/pkcs7.h b/include/crypto/pkcs7.h index 38ec7f5f90411..bd83202cd805c 100644 --- a/include/crypto/pkcs7.h +++ b/include/crypto/pkcs7.h @@ -25,6 +25,10 @@ extern void pkcs7_free_message(struct pkcs7_message *pkc= s7); extern int pkcs7_get_content_data(const struct pkcs7_message *pkcs7, const void **_data, size_t *_datalen, size_t *_headerlen); +extern int pkcs7_get_authattr(const struct pkcs7_message *pkcs7, + enum OID oid, + const void **_data, size_t *_len); + =20 /* * pkcs7_trust.c --=20 2.52.0 From nobody Tue Dec 16 18:24:45 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6403E29BDBF; Thu, 11 Dec 2025 02:13:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419204; cv=none; b=U13xkSwUyukYszMO5QTIhBvwejgzQP4c+hpXiw4Kpgj5x71fg+Q0YhbER/+IeQ9jXBpQVf+Of94BFwK1BTQCXxakHMJvQfrFPbOQ0x/a94NemSzssqlg6HR9wDoDP7tFhdxJBxMs2Yb1JqPKsZroJrQgMDCu9NHjSI+OvKZnvxo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419204; c=relaxed/simple; bh=uegI1mzPRZliA/TQcX5ABSs2HWFj+P0VOewP5BORp+o=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NA1aEEsXOT6rQwXSD6UoN9XGKIXWuysUyfZCtL476Gc8C5NIpGg/7ydlxHs32tk/2igbo7MBQVO8JT3K16ShvpRMTvUQBMKsOmV+bwO5G+G/PeNP6uY+g04nEK/DhXDNDkgQPEVa6Iugszb+6ol3h+xNIx2WI+ASWHxOb1ZLjjw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=mE5MEPr8; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="mE5MEPr8" Received: from narnia.corp.microsoft.com (unknown [40.78.12.133]) by linux.microsoft.com (Postfix) with ESMTPSA id 7DF7A2116049; Wed, 10 Dec 2025 18:13:19 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 7DF7A2116049 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1765419200; bh=++dNq3pik3ds/FgQ3gbpQEqGwqt1ddB5Lw7Ccqc/7dA=; h=From:To:Subject:Date:In-Reply-To:References:From; b=mE5MEPr8pkJe6GrDwQy6WSXJvbzb6Vhk6o2M/64U4BF24h8HPIvf1lBIfXpU56h94 EIyO9BQSD3TUFMwMl4mZv8+KAngAaw+iZR1htM/7VtvWHVCl0S3z/23nFH6J3w9HOu vYy6rpXeaYqj/b1nng71vYIKPSKK30Rb9XX/JY0E= From: Blaise Boscaccy To: Blaise Boscaccy , Jonathan Corbet , Paul Moore , James Morris , "Serge E. Hallyn" , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , =?UTF-8?q?G=C3=BCnther=20Noack?= , "Dr. David Alan Gilbert" , Andrew Morton , James.Bottomley@HansenPartnership.com, dhowells@redhat.com, linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [RFC 07/11] crypto: pkcs7: add tests for pkcs7_get_authattr Date: Wed, 10 Dec 2025 18:12:02 -0800 Message-ID: <20251211021257.1208712-8-bboscaccy@linux.microsoft.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> References: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: James Bottomley Add example code to the test module pkcs7_key_type.c that verifies a message and then pulls out a known authenticated attribute. Signed-off-by: James Bottomley Acked-by: David Howells --- crypto/asymmetric_keys/pkcs7_key_type.c | 42 ++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/crypto/asymmetric_keys/pkcs7_key_type.c b/crypto/asymmetric_ke= ys/pkcs7_key_type.c index b930d3bbf1af5..5a1ecb5501b2b 100644 --- a/crypto/asymmetric_keys/pkcs7_key_type.c +++ b/crypto/asymmetric_keys/pkcs7_key_type.c @@ -12,6 +12,7 @@ #include #include #include +#include =20 MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("PKCS#7 testing key type"); @@ -51,16 +52,55 @@ static int pkcs7_view_content(void *ctx, const void *da= ta, size_t len, static int pkcs7_preparse(struct key_preparsed_payload *prep) { enum key_being_used_for usage =3D pkcs7_usage; + int ret; + struct pkcs7_message *pkcs7; + const void *data; + size_t len; =20 if (usage >=3D NR__KEY_BEING_USED_FOR) { pr_err("Invalid usage type %d\n", usage); return -EINVAL; } =20 - return verify_pkcs7_signature(NULL, 0, + ret =3D verify_pkcs7_signature(NULL, 0, prep->data, prep->datalen, VERIFY_USE_SECONDARY_KEYRING, usage, pkcs7_view_content, prep); + if (ret) + return ret; + + pkcs7 =3D pkcs7_parse_message(prep->data, prep->datalen); + if (IS_ERR(pkcs7)) { + pr_err("pkcs7 parse error\n"); + return PTR_ERR(pkcs7); + } + + /* + * the parsed message has no trusted signer, so nothing should + * be returned here + */ + ret =3D pkcs7_get_authattr(pkcs7, OID_messageDigest, &data, &len); + if (ret =3D=3D 0) { + pr_err("OID returned when no trust in signer\n"); + goto out; + } + /* add trust and check again */ + ret =3D validate_pkcs7_trust(pkcs7, VERIFY_USE_SECONDARY_KEYRING); + if (ret) { + pr_err("validate_pkcs7_trust failed!!\n"); + goto out; + } + /* now we should find the OID */ + ret =3D pkcs7_get_authattr(pkcs7, OID_messageDigest, &data, &len); + if (ret) { + pr_err("Failed to get message digest\n"); + goto out; + } + pr_info("Correctly Got message hash, size=3D%ld\n", len); + + out: + pkcs7_free_message(pkcs7); + return 0; } =20 /* --=20 2.52.0 From nobody Tue Dec 16 18:24:45 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 702B92DC344; Thu, 11 Dec 2025 02:13:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419206; cv=none; b=UfOWSSk3s+jQU5PF32+VWftVf+0VMIdr+evYOtpuFsVBwm+7PVC7pDTY0KlRb9fV50xYcK/c8fprOuUjO7bix3V7+Sh/NS9CAzKRndr4iy5oWin8AD1YUn1j8Btiu+aoH90vjBV5/+mr2gDNbE0kpszk2LtvADnoC5jxfVwPKbI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419206; c=relaxed/simple; bh=CehVMLMVOtMTVSUA/JBtH7AE4p3IR62dXJGkDE5/0FE=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=h46RHX7SU9NkPhg33jxkW9QceNLUoOsinGxKQ9/nzsTKObDoWe9uk0h8ePle8Q7vCu7YKodHUqjQ4kBO/9tWVIvnhjw42H77QDq0P2zWRq9Tsj1CR5tyA2JzQudlAxHgYL7ykZEEmmgQvxCZGkVcm4cBKnM8rGw6c7M5esRb2iU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=UEIQOWkT; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="UEIQOWkT" Received: from narnia.corp.microsoft.com (unknown [40.78.12.133]) by linux.microsoft.com (Postfix) with ESMTPSA id 2BF722116046; Wed, 10 Dec 2025 18:13:22 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 2BF722116046 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1765419203; bh=omIdCqj9WPGrAIza0WzV1LRPwOQHUmhJe7PUs8a/Dmw=; h=From:To:Subject:Date:In-Reply-To:References:From; b=UEIQOWkTT98PC0r5IjMGzlBBi511MrEsSYV/5bkH22HWDdza+pxMByhj5OpNsqtJZ z/8iMa0AbU2Yr/yMB9xgwKYNm1w5lFnHlbw3TwHx25T4zvMn+0phUZsSAzFK7nAYrW sqHsJc7lPp7wOJC+ParRg3I3dDF2Y1fwPG2VRKng= From: Blaise Boscaccy To: Blaise Boscaccy , Jonathan Corbet , Paul Moore , James Morris , "Serge E. Hallyn" , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , =?UTF-8?q?G=C3=BCnther=20Noack?= , "Dr. David Alan Gilbert" , Andrew Morton , James.Bottomley@HansenPartnership.com, dhowells@redhat.com, linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [RFC 08/11] security: Hornet LSM Date: Wed, 10 Dec 2025 18:12:03 -0800 Message-ID: <20251211021257.1208712-9-bboscaccy@linux.microsoft.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> References: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This adds the Hornet Linux Security Module which provides enhanced signature verification and data validation for eBPF programs. This allows users to continue to maintain an invariant that all code running inside of the kernel has actually been signed and verified, by the kernel. This effort builds upon the currently excepted upstream solution. It further hardens it by providing deterministic, in-kernel checking of map hashes to solidify auditing along with preventing TOCTOU attacks against lskel map hashes. Target map hashes are passed in via PKCS#7 signed attributes. Hornet determines the extent which the eBFP program is signed and defers to other LSMs for policy decisions. Signed-off-by: Blaise Boscaccy --- Documentation/admin-guide/LSM/Hornet.rst | 38 +++++ Documentation/admin-guide/LSM/index.rst | 1 + MAINTAINERS | 9 + include/linux/oid_registry.h | 3 + include/uapi/linux/lsm.h | 1 + security/Kconfig | 3 +- security/Makefile | 1 + security/hornet/Kconfig | 11 ++ security/hornet/Makefile | 7 + security/hornet/hornet.asn1 | 13 ++ security/hornet/hornet_lsm.c | 201 +++++++++++++++++++++++ 11 files changed, 287 insertions(+), 1 deletion(-) create mode 100644 Documentation/admin-guide/LSM/Hornet.rst create mode 100644 security/hornet/Kconfig create mode 100644 security/hornet/Makefile create mode 100644 security/hornet/hornet.asn1 create mode 100644 security/hornet/hornet_lsm.c diff --git a/Documentation/admin-guide/LSM/Hornet.rst b/Documentation/admin= -guide/LSM/Hornet.rst new file mode 100644 index 0000000000000..0fb5920e9b68f --- /dev/null +++ b/Documentation/admin-guide/LSM/Hornet.rst @@ -0,0 +1,38 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=3D=3D=3D=3D=3D=3D +Hornet +=3D=3D=3D=3D=3D=3D + +Hornet is a Linux Security Module that provides extensible signature +verification for eBPF programs. This is selectable at build-time with +``CONFIG_SECURITY_HORNET``. + +Overview +=3D=3D=3D=3D=3D=3D=3D=3D + +Hornet addresses concerns from users who require strict audit +trails and verification guarantees, especially in security-sensitive +environments. Map hashes for extended verification are passed in via +the existing PKCS#7 uapi and verifified by the crypto +subsystem. Hornet then calculates the verification state of the +program (full, partial, bad, etc) and then invokes a new downstream +LSM hook to delegate policy decisions. + +Tooling +=3D=3D=3D=3D=3D=3D=3D + +Some tooling is provided to aid with the development of signed eBPF +light-skeletons. + +extract-skel.sh +--------------- + +This shell script extracts the instructions and map data used by the +light skeleton from the autogenerated header file created by bpftool. + +gen_sig +--------- + +gen_sig creates a pkcs#7 signature of a data payload. Additionally it +appends a signed attribute containing a set of hashes. diff --git a/Documentation/admin-guide/LSM/index.rst b/Documentation/admin-= guide/LSM/index.rst index b44ef68f6e4da..57f6e9fbe5fd1 100644 --- a/Documentation/admin-guide/LSM/index.rst +++ b/Documentation/admin-guide/LSM/index.rst @@ -49,3 +49,4 @@ subdirectories. SafeSetID ipe landlock + Hornet diff --git a/MAINTAINERS b/MAINTAINERS index 3da2c26a796b8..64c9aaff6a219 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11399,6 +11399,15 @@ S: Maintained F: Documentation/devicetree/bindings/iio/pressure/honeywell,mprls0025pa.ya= ml F: drivers/iio/pressure/mprls0025pa* =20 +HORNET SECURITY MODULE +M: Blaise Boscaccy +L: linux-security-module@vger.kernel.org +S: Supported +T: git https://github.com/blaiseboscaccy/hornet.git +F: Documentation/admin-guide/LSM/Hornet.rst +F: scripts/hornet/ +F: security/hornet/ + HP BIOSCFG DRIVER M: Jorge Lopez L: platform-driver-x86@vger.kernel.org diff --git a/include/linux/oid_registry.h b/include/linux/oid_registry.h index 6de479ebbe5da..94e7c1a3fc639 100644 --- a/include/linux/oid_registry.h +++ b/include/linux/oid_registry.h @@ -145,6 +145,9 @@ enum OID { OID_id_rsassa_pkcs1_v1_5_with_sha3_384, /* 2.16.840.1.101.3.4.3.15 */ OID_id_rsassa_pkcs1_v1_5_with_sha3_512, /* 2.16.840.1.101.3.4.3.16 */ =20 + /* Hornet LSM */ + OID_hornet_data, /* 2.25.316487325684022475439036912669789383960 */ + OID__NR }; =20 diff --git a/include/uapi/linux/lsm.h b/include/uapi/linux/lsm.h index 938593dfd5daf..2ff9bcdd551e2 100644 --- a/include/uapi/linux/lsm.h +++ b/include/uapi/linux/lsm.h @@ -65,6 +65,7 @@ struct lsm_ctx { #define LSM_ID_IMA 111 #define LSM_ID_EVM 112 #define LSM_ID_IPE 113 +#define LSM_ID_HORNET 114 =20 /* * LSM_ATTR_XXX definitions identify different LSM attributes diff --git a/security/Kconfig b/security/Kconfig index 285f284dfcac4..8cbe314fd9238 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -230,6 +230,7 @@ source "security/safesetid/Kconfig" source "security/lockdown/Kconfig" source "security/landlock/Kconfig" source "security/ipe/Kconfig" +source "security/hornet/Kconfig" =20 source "security/integrity/Kconfig" =20 @@ -274,7 +275,7 @@ config LSM default "landlock,lockdown,yama,loadpin,safesetid,apparmor,selinux,smack,= tomoyo,ipe,bpf" if DEFAULT_SECURITY_APPARMOR default "landlock,lockdown,yama,loadpin,safesetid,tomoyo,ipe,bpf" if DEFA= ULT_SECURITY_TOMOYO default "landlock,lockdown,yama,loadpin,safesetid,ipe,bpf" if DEFAULT_SEC= URITY_DAC - default "landlock,lockdown,yama,loadpin,safesetid,selinux,smack,tomoyo,ap= parmor,ipe,bpf" + default "landlock,lockdown,yama,loadpin,safesetid,selinux,smack,tomoyo,ap= parmor,ipe,hornet,bpf" help A comma-separated list of LSMs, in initialization order. Any LSMs left off this list, except for those with order diff --git a/security/Makefile b/security/Makefile index 22ff4c8bd8cec..e24bccd951f88 100644 --- a/security/Makefile +++ b/security/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_CGROUPS) +=3D device_cgroup.o obj-$(CONFIG_BPF_LSM) +=3D bpf/ obj-$(CONFIG_SECURITY_LANDLOCK) +=3D landlock/ obj-$(CONFIG_SECURITY_IPE) +=3D ipe/ +obj-$(CONFIG_SECURITY_HORNET) +=3D hornet/ =20 # Object integrity file lists obj-$(CONFIG_INTEGRITY) +=3D integrity/ diff --git a/security/hornet/Kconfig b/security/hornet/Kconfig new file mode 100644 index 0000000000000..19406aa237ac6 --- /dev/null +++ b/security/hornet/Kconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-only +config SECURITY_HORNET + bool "Hornet support" + depends on SECURITY + default n + help + This selects Hornet. + Further information can be found in + Documentation/admin-guide/LSM/Hornet.rst. + + If you are unsure how to answer this question, answer N. diff --git a/security/hornet/Makefile b/security/hornet/Makefile new file mode 100644 index 0000000000000..342142c5ff8a4 --- /dev/null +++ b/security/hornet/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_SECURITY_HORNET) :=3D hornet.o + +hornet-y :=3D hornet_lsm.o \ + hornet.asn1.o + +$(obj)/hornet.asn1.o: $(obj)/hornet.asn1.c $(obj)/hornet.asn1.h diff --git a/security/hornet/hornet.asn1 b/security/hornet/hornet.asn1 new file mode 100644 index 0000000000000..c8d47b16b65d7 --- /dev/null +++ b/security/hornet/hornet.asn1 @@ -0,0 +1,13 @@ +-- SPDX-License-Identifier: BSD-3-Clause +-- +-- Copyright (C) 2009 IETF Trust and the persons identified as authors +-- of the code +-- +-- https://www.rfc-editor.org/rfc/rfc5652#section-3 + +HornetData ::=3D SET OF Map + +Map ::=3D SEQUENCE { + index INTEGER ({ hornet_map_index }), + sha OCTET STRING ({ hornet_map_hash }) +} ({ hornet_next_map }) diff --git a/security/hornet/hornet_lsm.c b/security/hornet/hornet_lsm.c new file mode 100644 index 0000000000000..a8499ee108ad3 --- /dev/null +++ b/security/hornet/hornet_lsm.c @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Hornet Linux Security Module + * + * Author: Blaise Boscaccy + * + * Copyright (C) 2025 Microsoft Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hornet.asn1.h" + +#define MAX_USED_MAPS 64 + +struct hornet_maps { + bpfptr_t fd_array; +}; + +struct hornet_parse_context { + size_t indexes[MAX_USED_MAPS]; + bool skips[MAX_USED_MAPS]; + unsigned char hashes[SHA256_DIGEST_SIZE * MAX_USED_MAPS]; + int hash_count; +}; + +static int hornet_verify_hashes(struct hornet_maps *maps, + struct hornet_parse_context *ctx) +{ + int map_fd; + u32 i; + struct bpf_map *map; + int err =3D 0; + unsigned char hash[SHA256_DIGEST_SIZE]; + + for (i =3D 0; i < ctx->hash_count; i++) { + if (ctx->skips[i]) + continue; + + err =3D copy_from_bpfptr_offset(&map_fd, maps->fd_array, + ctx->indexes[i] * sizeof(map_fd), + sizeof(map_fd)); + if (err < 0) + return LSM_INT_VERDICT_BADSIG; + + CLASS(fd, f)(map_fd); + if (fd_empty(f)) + return LSM_INT_VERDICT_BADSIG; + if (unlikely(fd_file(f)->f_op !=3D &bpf_map_fops)) + return LSM_INT_VERDICT_BADSIG; + + if (!map->frozen) + return LSM_INT_VERDICT_BADSIG; + + map =3D fd_file(f)->private_data; + map->ops->map_get_hash(map, SHA256_DIGEST_SIZE, hash); + + err =3D (memcmp(hash, &ctx->hashes[ctx->indexes[i] * SHA256_DIGEST_SIZE], + SHA256_DIGEST_SIZE)); + if (!err) + return LSM_INT_VERDICT_BADSIG; + } + return LSM_INT_VERDICT_OK; +} + +int hornet_next_map(void *context, size_t hdrlen, + unsigned char tag, + const void *value, size_t vlen) +{ + struct hornet_parse_context *ctx =3D (struct hornet_parse_context *)value; + + ctx->hash_count++; + return 0; +} + + +int hornet_map_index(void *context, size_t hdrlen, + unsigned char tag, + const void *value, size_t vlen) +{ + struct hornet_parse_context *ctx =3D (struct hornet_parse_context *)value; + + ctx->hashes[ctx->hash_count] =3D *(int *)value; + return 0; +} + +int hornet_map_hash(void *context, size_t hdrlen, + unsigned char tag, + const void *value, size_t vlen) + +{ + struct hornet_parse_context *ctx =3D (struct hornet_parse_context *)value; + + if (vlen !=3D SHA256_DIGEST_SIZE && vlen !=3D 0) + return -EINVAL; + + if (vlen !=3D 0) { + ctx->skips[ctx->hash_count] =3D false; + memcpy(&ctx->hashes[ctx->hash_count * SHA256_DIGEST_SIZE], value, vlen); + } else + ctx->skips[ctx->hash_count] =3D true; + + return 0; +} + +static int hornet_check_program(struct bpf_prog *prog, union bpf_attr *att= r, + struct bpf_token *token, bool is_kernel) +{ + struct hornet_maps maps =3D {0}; + bpfptr_t usig =3D make_bpfptr(attr->signature, is_kernel); + struct pkcs7_message *msg; + struct hornet_parse_context *ctx; + void *sig; + int err; + const void *authattrs; + size_t authattrs_len; + + if (!attr->signature) + return LSM_INT_VERDICT_UNSIGNED; + + ctx =3D kzalloc(sizeof(struct hornet_parse_context), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + maps.fd_array =3D make_bpfptr(attr->fd_array, is_kernel); + sig =3D kzalloc(attr->signature_size, GFP_KERNEL); + if (!sig) { + err =3D -ENOMEM; + goto out; + } + err =3D copy_from_bpfptr(sig, usig, attr->signature_size); + if (err !=3D 0) + goto out; + + msg =3D pkcs7_parse_message(sig, attr->signature_size); + if (IS_ERR(msg)) { + err =3D LSM_INT_VERDICT_BADSIG; + goto out; + } + + if (validate_pkcs7_trust(msg, VERIFY_USE_SECONDARY_KEYRING)) { + err =3D LSM_INT_VERDICT_PARTIALSIG; + goto out; + } + if (pkcs7_get_authattr(msg, OID_hornet_data, + &authattrs, &authattrs_len) =3D=3D -ENODATA) { + err =3D LSM_INT_VERDICT_PARTIALSIG; + goto out; + } + + err =3D asn1_ber_decoder(&hornet_decoder, ctx, authattrs, authattrs_len); + if (err < 0 || authattrs =3D=3D NULL) { + err =3D LSM_INT_VERDICT_PARTIALSIG; + goto out; + } + err =3D hornet_verify_hashes(&maps, ctx); +out: + kfree(ctx); + return err; +} + +static const struct lsm_id hornet_lsmid =3D { + .name =3D "hornet", + .id =3D LSM_ID_HORNET, +}; + +static int hornet_bpf_prog_load_integrity(struct bpf_prog *prog, union bpf= _attr *attr, + struct bpf_token *token, bool is_kernel) +{ + int result =3D hornet_check_program(prog, attr, token, is_kernel); + + if (result < 0) + return result; + + return security_bpf_prog_load_post_integrity(prog, attr, token, is_kernel, + &hornet_lsmid, result); +} + +static struct security_hook_list hornet_hooks[] __ro_after_init =3D { + LSM_HOOK_INIT(bpf_prog_load_integrity, hornet_bpf_prog_load_integrity), +}; + +static int __init hornet_init(void) +{ + pr_info("Hornet: eBPF signature verification enabled\n"); + security_add_hooks(hornet_hooks, ARRAY_SIZE(hornet_hooks), &hornet_lsmid); + return 0; +} + +DEFINE_LSM(hornet) =3D { + .name =3D "hornet", + .init =3D hornet_init, +}; --=20 2.52.0 From nobody Tue Dec 16 18:24:45 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A516F2BDC32; Thu, 11 Dec 2025 02:13:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419208; cv=none; b=pRwwY94xtkNEIbhqO+488wjtSuTDtPihb3HU9os/dVjz1X832kDT7/6XHv0VvSQloDzRaGANoNXy3fxOg64qNhMYId6vI3cPPMjnBpXmxrhlQ75H0Yblqvqjv9r395nX91naHdHOSTmXmqPiUgroq9Ec+/hflEWQ8rLCbIJRS2c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419208; c=relaxed/simple; bh=38eFVkVie/Vy+ZY3T+ue8ul1yRsyl1JiEYo5u8TdQh4=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DqbU/qI5+dv12Z3ve6FqLEACbYwXvopN81J6lyTaaCTxjsuhXVbq5lNAku3Ng1Vx+pYwo7DLqTXo7C53bpPmXT4qFeaLeudMqdgMjVId2cBbUQn0IHlKqAKNsL6pjPep5s+IiGxIGMDJhORv51sPwqxi3eqMSSRC9YFj8ygBD4A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=J8LP7FCT; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="J8LP7FCT" Received: from narnia.corp.microsoft.com (unknown [40.78.12.133]) by linux.microsoft.com (Postfix) with ESMTPSA id 820AC2116049; Wed, 10 Dec 2025 18:13:24 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 820AC2116049 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1765419205; bh=19gqP6RcNdFMv4Osb1338Yn4ALv5mzANh2hYkAKtQvk=; h=From:To:Subject:Date:In-Reply-To:References:From; b=J8LP7FCTwgS0jDD29ahXIkFw1jfcadSXGptr09O4xCC5/SrfUaGQCEvog1udXqGWB 6rPuED66XsV6bq2bMYCHTgxX4/7rRI2MtI39W8RIrETuOv5jE1ns5EWF3juIItDG8k 689kEZHSmRcU6cyY/OzoipFOyPi8EHYqWB8LxZys= From: Blaise Boscaccy To: Blaise Boscaccy , Jonathan Corbet , Paul Moore , James Morris , "Serge E. Hallyn" , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , =?UTF-8?q?G=C3=BCnther=20Noack?= , "Dr. David Alan Gilbert" , Andrew Morton , James.Bottomley@HansenPartnership.com, dhowells@redhat.com, linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [RFC 09/11] hornet: Introduce gen_sig Date: Wed, 10 Dec 2025 18:12:04 -0800 Message-ID: <20251211021257.1208712-10-bboscaccy@linux.microsoft.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> References: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable This introduces the gen_sig tool. It creates a pkcs#7 signature of a data payload. Additionally it appends a signed attribute containing a set of hashes. Typical usage is to provide a payload containing the light skeleton ebpf syscall program binary and it's associated maps, which can be extracted from the auto-generated skeleton header. Signed-off-by: Blaise Boscaccy --- scripts/Makefile | 1 + scripts/hornet/Makefile | 5 + scripts/hornet/gen_sig.c | 392 ++++++++++++++++++++++++++++++++++++ scripts/hornet/write-sig.sh | 27 +++ 4 files changed, 425 insertions(+) create mode 100644 scripts/hornet/Makefile create mode 100644 scripts/hornet/gen_sig.c create mode 100755 scripts/hornet/write-sig.sh diff --git a/scripts/Makefile b/scripts/Makefile index 46f860529df5e..a2cace05d7342 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -57,6 +57,7 @@ subdir-$(CONFIG_GENKSYMS) +=3D genksyms subdir-$(CONFIG_GENDWARFKSYMS) +=3D gendwarfksyms subdir-$(CONFIG_SECURITY_SELINUX) +=3D selinux subdir-$(CONFIG_SECURITY_IPE) +=3D ipe +subdir-$(CONFIG_SECURITY_HORNET) +=3D hornet =20 # Let clean descend into subdirs subdir- +=3D basic dtc gdb kconfig mod diff --git a/scripts/hornet/Makefile b/scripts/hornet/Makefile new file mode 100644 index 0000000000000..3ee41e5e9a9ff --- /dev/null +++ b/scripts/hornet/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +hostprogs-always-y :=3D gen_sig + +HOSTCFLAGS_gen_sig.o =3D $(shell $(HOSTPKG_CONFIG) --cflags libcrypto 2> /= dev/null) +HOSTLDLIBS_gen_sig =3D $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/= null || echo -lcrypto) diff --git a/scripts/hornet/gen_sig.c b/scripts/hornet/gen_sig.c new file mode 100644 index 0000000000000..1d501efeb8f13 --- /dev/null +++ b/scripts/hornet/gen_sig.c @@ -0,0 +1,392 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + * + * Generate a signature for an eBPF program along with appending + * map hashes as signed attributes + * + * Copyright =C2=A9 2025 Microsoft Corporation. + * + * Authors: Blaise Boscaccy + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 + * of the licence, or (at your option) any later version. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if OPENSSL_VERSION_MAJOR >=3D 3 +# define USE_PKCS11_PROVIDER +# include +# include +#else +# if !defined(OPENSSL_NO_ENGINE) && !defined(OPENSSL_NO_DEPRECATED_3_0) +# define USE_PKCS11_ENGINE +# include +# endif +#endif +#include "../ssl-common.h" + +#define SHA256_LEN 32 +#define BUF_SIZE (1 << 15) // 32 KiB +#define MAX_HASHES 64 + +struct hash_spec { + char *file; +}; + +typedef struct { + ASN1_INTEGER *index; + ASN1_OCTET_STRING *hash; + +} HORNET_MAP; + +DECLARE_ASN1_FUNCTIONS(HORNET_MAP) +ASN1_SEQUENCE(HORNET_MAP) =3D { + ASN1_SIMPLE(HORNET_MAP, index, ASN1_INTEGER), + ASN1_SIMPLE(HORNET_MAP, hash, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(HORNET_MAP); + +IMPLEMENT_ASN1_FUNCTIONS(HORNET_MAP) + +DEFINE_STACK_OF(HORNET_MAP) + +typedef struct { + STACK_OF(HORNET_MAP) * maps; +} MAP_SET; + +DECLARE_ASN1_FUNCTIONS(MAP_SET) +ASN1_SEQUENCE(MAP_SET) =3D { + ASN1_SET_OF(MAP_SET, maps, HORNET_MAP) +} ASN1_SEQUENCE_END(MAP_SET); + +IMPLEMENT_ASN1_FUNCTIONS(MAP_SET) + +#define DIE(...) do { fprintf(stderr, __VA_ARGS__); fputc('\n', stderr); \ + exit(EXIT_FAILURE); } while (0) + +static BIO *bio_open_wr(const char *path) +{ + BIO *b =3D BIO_new_file(path, "wb"); + + if (!b) { + perror(path); + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } + return b; +} + +static void usage(const char *prog) +{ + fprintf(stderr, + "Usage:\n" + " %s -data content.bin -cert signer.crt -key signer.key [-pass pass]\n" + " -out newsig.p7b \n" + " --add-hash FILE [--add-hash FILE ...]\n", + prog); +} + +static const char *key_pass; + +static int pem_pw_cb(char *buf, int len, int w, void *v) +{ + int pwlen; + + if (!key_pass) + return -1; + + pwlen =3D strlen(key_pass); + if (pwlen >=3D len) + return -1; + + strcpy(buf, key_pass); + + key_pass =3D NULL; + + return pwlen; +} + +static EVP_PKEY *read_private_key(const char *private_key_name) +{ + EVP_PKEY *private_key; + BIO *b; + + b =3D BIO_new_file(private_key_name, "rb"); + ERR(!b, "%s", private_key_name); + private_key =3D PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, + NULL); + ERR(!private_key, "%s", private_key_name); + BIO_free(b); + + return private_key; +} + +static X509 *read_x509(const char *x509_name) +{ + unsigned char buf[2]; + X509 *x509; + BIO *b; + int n; + + b =3D BIO_new_file(x509_name, "rb"); + ERR(!b, "%s", x509_name); + + /* Look at the first two bytes of the file to determine the encoding */ + n =3D BIO_read(b, buf, 2); + if (n !=3D 2) { + if (BIO_should_retry(b)) { + fprintf(stderr, "%s: Read wanted retry\n", x509_name); + exit(1); + } + if (n >=3D 0) { + fprintf(stderr, "%s: Short read\n", x509_name); + exit(1); + } + ERR(1, "%s", x509_name); + } + + ERR(BIO_reset(b) !=3D 0, "%s", x509_name); + + if (buf[0] =3D=3D 0x30 && buf[1] >=3D 0x81 && buf[1] <=3D 0x84) + /* Assume raw DER encoded X.509 */ + x509 =3D d2i_X509_bio(b, NULL); + else + /* Assume PEM encoded X.509 */ + x509 =3D PEM_read_bio_X509(b, NULL, NULL, NULL); + + BIO_free(b); + ERR(!x509, "%s", x509_name); + + return x509; +} + +static int sha256(const char *path, unsigned char out[SHA256_LEN], unsigne= d int *out_len) +{ + FILE *f; + int rc; + EVP_MD_CTX *ctx; + unsigned char buf[BUF_SIZE]; + size_t n; + unsigned int mdlen =3D 0; + + if (!path || !out) + return -1; + + f =3D fopen(path, "rb"); + if (!f) { + perror("fopen"); + return -2; + } + + ERR_load_crypto_strings(); + + rc =3D -3; + ctx =3D EVP_MD_CTX_new(); + if (!ctx) { + rc =3D -4; + goto done; + } + +#if OPENSSL_VERSION_NUMBER >=3D 0x30000000L + if (EVP_DigestInit_ex2(ctx, EVP_sha256(), NULL) !=3D 1) { + rc =3D -5; + goto done; + } +#else + if (EVP_DigestInit_ex(ctx, EVP_sha256(), NULL) !=3D 1) { + rc =3D -5; + goto done; + } +#endif + while ((n =3D fread(buf, 1, sizeof(buf), f)) > 0) { + if (EVP_DigestUpdate(ctx, buf, n) !=3D 1) { + rc =3D -6; + goto done; + } + } + if (ferror(f)) { + rc =3D -7; + goto done; + } + + if (EVP_DigestFinal_ex(ctx, out, &mdlen) !=3D 1) { + rc =3D -8; + goto done; + } + if (mdlen !=3D SHA256_LEN) { + rc =3D -9; + goto done; + } + + if (out_len) + *out_len =3D mdlen; + rc =3D 0; + +done: + EVP_MD_CTX_free(ctx); + fclose(f); + ERR_free_strings(); + return rc; +} + +static void add_hash(MAP_SET *set, unsigned char *buffer, int buffer_len, = int index) +{ + HORNET_MAP *map =3D NULL; + + map =3D HORNET_MAP_new(); + ASN1_INTEGER_set(map->index, index); + ASN1_OCTET_STRING_set(map->hash, buffer, buffer_len); + sk_HORNET_MAP_push(set->maps, map); +} + +int main(int argc, char **argv) +{ + const char *cert_path =3D NULL; + const char *key_path =3D NULL; + const char *data_path =3D NULL; + const char *out_path =3D NULL; + + X509 *signer; + EVP_PKEY *pkey; + BIO *data_in; + CMS_ContentInfo *cms_out; + struct hash_spec hashes[MAX_HASHES]; + int hash_count =3D 0; + int flags; + CMS_SignerInfo *si; + MAP_SET *set; + unsigned char hash_buffer[SHA256_LEN]; + unsigned int hash_len; + ASN1_OBJECT *oid; + unsigned char *der =3D NULL; + int der_len; + int err; + BIO *b_out; + int i; + + for (i =3D 1; i < argc; i++) { + if (!strcmp(argv[i], "-cert") && i+1 < argc) + cert_path =3D argv[++i]; + else if (!strcmp(argv[i], "-data") && i+1 < argc) + data_path =3D argv[++i]; + else if (!strcmp(argv[i], "-key") && i+1 < argc) + key_path =3D argv[++i]; + else if (!strcmp(argv[i], "-pass") && i+1 < argc) + key_pass =3D argv[++i]; + else if (!strcmp(argv[i], "-out") && i+1 < argc) + out_path =3D argv[++i]; + else if (!strcmp(argv[i], "--add-skip-check")) { + hashes[hash_count++].file =3D NULL; + i++; + } else if (!strcmp(argv[i], "--add-hash") && i+1 < argc) { + hashes[hash_count++].file =3D argv[++i]; + } else { + usage(argv[0]); + return EXIT_FAILURE; + } + } + + if (!cert_path || !key_path || !out_path || !data_path) { + usage(argv[0]); + return EXIT_FAILURE; + } + + OpenSSL_add_all_algorithms(); + ERR_load_crypto_strings(); + + signer =3D read_x509(cert_path); + if (!signer) { + ERR_print_errors_fp(stderr); + DIE("Load cert failed"); + } + + pkey =3D read_private_key(key_path); + if (!pkey) { + ERR_print_errors_fp(stderr); + DIE("Load key failed"); + } + + data_in =3D BIO_new_file(data_path, "rb"); + if (!data_in) { + ERR_print_errors_fp(stderr); + DIE("Load data failed"); + } + + cms_out =3D CMS_sign(NULL, NULL, NULL, NULL, + CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY | CMS_DETACHED); + + if (!cms_out) { + ERR_print_errors_fp(stderr); + DIE("create cms failed"); + } + + flags =3D CMS_NOCERTS | CMS_PARTIAL | CMS_BINARY | CMS_NOSMIMECAP | CMS_D= ETACHED; + + si =3D CMS_add1_signer(cms_out, signer, pkey, EVP_sha256(), flags); + if (!si) + DIE("add signer failed"); + + set =3D MAP_SET_new(); + set->maps =3D sk_HORNET_MAP_new_null(); + + for (i =3D 0; i < hash_count; i++) { + if (hashes[i].file) { + sha256(hashes[i].file, hash_buffer, &hash_len); + } else { + memset(hash_buffer, 0, SHA256_LEN); + hash_len =3D SHA256_LEN; + } + add_hash(set, hash_buffer, hash_len, i); + } + + oid =3D OBJ_txt2obj("2.25.316487325684022475439036912669789383960", 1); + if (!oid) { + ERR_print_errors_fp(stderr); + DIE("create oid failed"); + } + + der_len =3D ASN1_item_i2d((ASN1_VALUE *)set, &der, ASN1_ITEM_rptr(MAP_SET= )); + CMS_signed_add1_attr_by_OBJ(si, oid, V_ASN1_SEQUENCE, der, der_len); + + err =3D CMS_final(cms_out, data_in, NULL, CMS_NOCERTS | CMS_BINARY); + if (err =3D=3D 0) + ERR_print_errors_fp(stderr); + + OPENSSL_free(der); + MAP_SET_free(set); + + b_out =3D bio_open_wr(out_path); + if (!b_out) { + ERR_print_errors_fp(stderr); + DIE("opening output path failed"); + } + + i2d_CMS_bio_stream(b_out, cms_out, NULL, 0); + + BIO_free(data_in); + BIO_free(b_out); + EVP_cleanup(); + ERR_free_strings(); + return 0; +} diff --git a/scripts/hornet/write-sig.sh b/scripts/hornet/write-sig.sh new file mode 100755 index 0000000000000..7eaabe3bab9aa --- /dev/null +++ b/scripts/hornet/write-sig.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2025 Microsoft Corporation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License as published by the Free Software Foundation. + +function usage() { + echo "Sample for rewriting an autogenerated eBPF lskel headers" + echo "with a new signature" + echo "" + echo "USAGE: header_file sig" + exit +} + +ARGC=3D$# + +EXPECTED_ARGS=3D2 + +if [ $ARGC -ne $EXPECTED_ARGS ] ; then + usage +else + SIG=3D$(xxd -p $2 | tr -d '\n' | sed 's/\(..\)/\\\\x\1/g') + sed '/const char opts_sig/,/;/c\\tstatic const char opts_sig[] __attri= bute__((__aligned__(8))) =3D "\\\n'"$(printf '%s\n' "$SIG")"'\";' $1 +fi --=20 2.52.0 From nobody Tue Dec 16 18:24:45 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 637002BE029; Thu, 11 Dec 2025 02:13:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419210; cv=none; b=o3CKuCey3NBPpWHYZJ8sKckGXwfevaqhHotmv/TV8ejc5zTZZ6dCK8xUbXfK5IhZgE0demwTzkN+zUKVE6rV7X/4JtK3PQLonInCUxeXZ81UtNunVTX4ZaD3KJB5jecCgkpvD89KXtc7sGPRRwZPW5WlwPavFHyJWMd/QLNsLmg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419210; c=relaxed/simple; bh=mkroXq3OFkMoZGRn8gju20th14fJo2uSmvtnN/OMTwg=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tN4WOkfZqGAWIjX/lDYrHXZDIzkrLoTnhv5gRDVz+dVDOy466w91RW9NcT9PAjrLFi0TmIh9nvJFSRj0iqt1+ROSYbCNLXMtavjjMQ+/UYDqfKADy5knbkjpTjBexMN9rNhCPx3tjSaH4OYEPp0TugmsYmTtmEtUEW4Qaf0Ca+0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=fEC9TIho; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="fEC9TIho" Received: from narnia.corp.microsoft.com (unknown [40.78.12.133]) by linux.microsoft.com (Postfix) with ESMTPSA id ABDCF2116048; Wed, 10 Dec 2025 18:13:26 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com ABDCF2116048 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1765419207; bh=f6AZcn65ci1H3rxNkKRrHYwj60rHswJG0EWtgmSUxiY=; h=From:To:Subject:Date:In-Reply-To:References:From; b=fEC9TIho8RERKhtTSYrejeDP+WaxV5liGpYNiCrp3JRIPFy0CwaeO1C3YW2m0751n Z4cWuFpSsHywjghSY6XSRWh8JFSR4qAOgPyLLsDqnAKVJuNYABvYxf7IbdiYQjVcHB tFE9PKy8m5AlCUSpj9WhosXQgHb6kPhs93GECtfg= From: Blaise Boscaccy To: Blaise Boscaccy , Jonathan Corbet , Paul Moore , James Morris , "Serge E. Hallyn" , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , =?UTF-8?q?G=C3=BCnther=20Noack?= , "Dr. David Alan Gilbert" , Andrew Morton , James.Bottomley@HansenPartnership.com, dhowells@redhat.com, linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [RFC 10/11] hornet: Add a light skeleton data extractor scripts Date: Wed, 10 Dec 2025 18:12:05 -0800 Message-ID: <20251211021257.1208712-11-bboscaccy@linux.microsoft.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> References: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" These script eases light skeleton development against Hornet by generating a data payloads which can be used for signing a light skeleton binary using gen_sig. Signed-off-by: Blaise Boscaccy --- scripts/hornet/extract-insn.sh | 27 +++++++++++++++++++++++++++ scripts/hornet/extract-map.sh | 27 +++++++++++++++++++++++++++ scripts/hornet/extract-skel.sh | 27 +++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100755 scripts/hornet/extract-insn.sh create mode 100755 scripts/hornet/extract-map.sh create mode 100755 scripts/hornet/extract-skel.sh diff --git a/scripts/hornet/extract-insn.sh b/scripts/hornet/extract-insn.sh new file mode 100755 index 0000000000000..399b9ca500e3f --- /dev/null +++ b/scripts/hornet/extract-insn.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2025 Microsoft Corporation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License as published by the Free Software Foundation. + +function usage() { + echo "Sample script for extracting instructions" + echo "autogenerated eBPF lskel headers" + echo "" + echo "USAGE: header_file" + exit +} + +ARGC=3D$# + +EXPECTED_ARGS=3D1 + +if [ $ARGC -ne $EXPECTED_ARGS ] ; then + usage +else + printf $(gcc -E $1 | grep "opts\.insns =3D" | \ + awk -F")" '{print $2}' | sed 's/;\+$//' | sed 's/\"//g') +fi diff --git a/scripts/hornet/extract-map.sh b/scripts/hornet/extract-map.sh new file mode 100755 index 0000000000000..ca5d912dc5654 --- /dev/null +++ b/scripts/hornet/extract-map.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2025 Microsoft Corporation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License as published by the Free Software Foundation. + +function usage() { + echo "Sample script for extracting instructions" + echo "autogenerated eBPF lskel headers" + echo "" + echo "USAGE: header_file" + exit +} + +ARGC=3D$# + +EXPECTED_ARGS=3D1 + +if [ $ARGC -ne $EXPECTED_ARGS ] ; then + usage +else + printf $(gcc -E $1 | grep "opts\.data =3D" | \ + awk -F")" '{print $2}' | sed 's/;\+$//' | sed 's/\"//g') +fi diff --git a/scripts/hornet/extract-skel.sh b/scripts/hornet/extract-skel.sh new file mode 100755 index 0000000000000..6550a86b89917 --- /dev/null +++ b/scripts/hornet/extract-skel.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2025 Microsoft Corporation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of version 2 of the GNU General Public +# License as published by the Free Software Foundation. + +function usage() { + echo "Sample script for extracting instructions and map data out of" + echo "autogenerated eBPF lskel headers" + echo "" + echo "USAGE: header_file field" + exit +} + +ARGC=3D$# + +EXPECTED_ARGS=3D2 + +if [ $ARGC -ne $EXPECTED_ARGS ] ; then + usage +else + printf $(gcc -E $1 | grep "static const char opts_$2" | \ + awk -F"=3D" '{print $2}' | sed 's/;\+$//' | sed 's/\"//g') +fi --=20 2.52.0 From nobody Tue Dec 16 18:24:45 2025 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B407C2E8DF3; Thu, 11 Dec 2025 02:13:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419212; cv=none; b=urduuvkFTgTM+XcpQd9zFz7D42XWtLaWbUq54bJu45oeW5geqSwG23gKu6UbKmtJF5aMnjw+Swa2dRLHJjZdzE1DZVNrBIHlEmY5WFDM1ookNw6TETGj7TIjCU1AI+vYirVYn5LcKRX0oyEXPxA1WFTZcG+4ms4gPE3yXSlVJaY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765419212; c=relaxed/simple; bh=bU1syixsdUU9erFGRh3p4odK64b/fnWTtdkrDOy+C6w=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PnMPS49oFUAj4k587No3iX+yt3/9aLioJVe1ZMU6a0oZ6IJ8kTLvJ6ZiyY9mGgnwofPMIcIOdEfO3qfvA+LTCiut/oJFyptGy8GWB75a0V1uOd2y/0dOHAHglI21rfWrynshaRAYaS6vw6XSZxJT3hrLAUlvzc8hy2+apzg3HNo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=EOhVABtz; arc=none smtp.client-ip=13.77.154.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="EOhVABtz" Received: from narnia.corp.microsoft.com (unknown [40.78.12.133]) by linux.microsoft.com (Postfix) with ESMTPSA id 9F98B2116043; Wed, 10 Dec 2025 18:13:28 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 9F98B2116043 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1765419209; bh=tQoMsWo/rligOQ/1VDMbzQ8q+5PIN7gnOlz3Zgc/UI4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=EOhVABtzUGMULcnl9okOuI5HzmXVzs7fkolR2ZZaHdI2opfVxDF4plkKtYTI7F3pH XDh55JPJPebHlzJHAAc3l47fdzU9wwcchS3ZkS+NY7j+eLZOAXAR3hc1ASgpXEl5hS rM793oQIwgZR3VmJQPm6wZJwuz2TByqM9Xd9J6bo= From: Blaise Boscaccy To: Blaise Boscaccy , Jonathan Corbet , Paul Moore , James Morris , "Serge E. Hallyn" , =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , =?UTF-8?q?G=C3=BCnther=20Noack?= , "Dr. David Alan Gilbert" , Andrew Morton , James.Bottomley@HansenPartnership.com, dhowells@redhat.com, linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [RFC 11/11] selftests/hornet: Add a selftest for the Hornet LSM Date: Wed, 10 Dec 2025 18:12:06 -0800 Message-ID: <20251211021257.1208712-12-bboscaccy@linux.microsoft.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> References: <20251211021257.1208712-1-bboscaccy@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This selftest contains a testcase that utilizes light skeleton eBPF loaders and exercises hornet's map validation. Signed-off-by: Blaise Boscaccy --- tools/testing/selftests/Makefile | 1 + tools/testing/selftests/hornet/Makefile | 63 ++++++++++++++++++++ tools/testing/selftests/hornet/loader.c | 21 +++++++ tools/testing/selftests/hornet/trivial.bpf.c | 33 ++++++++++ 4 files changed, 118 insertions(+) create mode 100644 tools/testing/selftests/hornet/Makefile create mode 100644 tools/testing/selftests/hornet/loader.c create mode 100644 tools/testing/selftests/hornet/trivial.bpf.c diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Mak= efile index c46ebdb9b8ef7..4631893f0e91e 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -43,6 +43,7 @@ TARGETS +=3D ftrace TARGETS +=3D futex TARGETS +=3D gpio TARGETS +=3D hid +TARGETS +=3D hornet TARGETS +=3D intel_pstate TARGETS +=3D iommu TARGETS +=3D ipc diff --git a/tools/testing/selftests/hornet/Makefile b/tools/testing/selfte= sts/hornet/Makefile new file mode 100644 index 0000000000000..ccb4d503425d2 --- /dev/null +++ b/tools/testing/selftests/hornet/Makefile @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0 +include ../../../build/Build.include +include ../../../scripts/Makefile.arch +include ../../../scripts/Makefile.include + +CLANG ?=3D clang +CFLAGS :=3D -g -O2 -Wall +BPFTOOL ?=3D $(TOOLSDIR)/bpf/bpftool/bpftool +SCRIPTSDIR :=3D $(abspath ../../../../scripts/hornet) +TOOLSDIR :=3D $(abspath ../../..) +LIBDIR :=3D $(TOOLSDIR)/lib +BPFDIR :=3D $(LIBDIR)/bpf +TOOLSINCDIR :=3D $(TOOLSDIR)/include +APIDIR :=3D $(TOOLSINCDIR)/uapi +CERTDIR :=3D $(abspath ../../../../certs) +PKG_CONFIG ?=3D $(CROSS_COMPILE)pkg-config + +TEST_GEN_PROGS :=3D loader +TEST_GEN_FILES :=3D vmlinux.h loader.h trivial.bpf.o map.bin sig.bin insn.= bin signed_loader.h +$(TEST_GEN_PROGS): LDLIBS +=3D -lbpf +$(TEST_GEN_PROGS): $(TEST_GEN_FILES) + +include ../lib.mk + +BPF_CFLAGS :=3D -target bpf \ + -D__TARGET_ARCH_$(ARCH) \ + -I/usr/include/$(shell uname -m)-linux-gnu \ + $(KHDR_INCLUDES) + +vmlinux.h: + $(BPFTOOL) btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h + +trivial.bpf.o: trivial.bpf.c vmlinux.h + $(CLANG) $(CFLAGS) $(BPF_CFLAGS) -c $< -o $@ + +loader.h: trivial.bpf.o + $(BPFTOOL) gen skeleton -S -k $(CERTDIR)/signing_key.pem -i $(CERTDIR)/si= gning_key.x509 \ + -L $< name trivial > $@ + +insn.bin: loader.h + $(SCRIPTSDIR)/extract-insn.sh $< > $@ + +map.bin: loader.h + $(SCRIPTSDIR)/extract-map.sh $< > $@ + +$(OUTPUT)/gen_sig: ../../../../scripts/hornet/gen_sig.c + $(call msg,GEN_SIG,,$@) + $(Q)$(CC) $(shell $(PKG_CONFIG) --cflags libcrypto 2> /dev/null) \ + $< -o $@ \ + $(shell $(PKG_CONFIG) --libs libcrypto 2> /dev/null || echo -lcrypto) + +sig.bin: insn.bin map.bin $(OUTPUT)/gen_sig + $(OUTPUT)/gen_sig -key $(CERTDIR)/signing_key.pem -cert $(CERTDIR)/signin= g_key.x509 \ + -data insn.bin --add-hash map.bin -out sig.bin + +signed_loader.h: sig.bin + $(SCRIPTSDIR)/write-sig.sh loader.h sig.bin > $@ + +loader: loader.c signed_loader.h + $(CC) $(CFLAGS) -I$(LIBDIR) -I$(APIDIR) $< -o $@ -lbpf + + +EXTRA_CLEAN =3D $(OUTPUT)/gen_sig diff --git a/tools/testing/selftests/hornet/loader.c b/tools/testing/selfte= sts/hornet/loader.c new file mode 100644 index 0000000000000..f27580c7262b3 --- /dev/null +++ b/tools/testing/selftests/hornet/loader.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + +#include +#include +#include +#include +#include +#include +#include "signed_loader.h" + +int main(int argc, char **argv) +{ + struct trivial *skel; + + skel =3D trivial__open_and_load(); + if (!skel) + return -1; + + trivial__destroy(skel); + return 0; +} diff --git a/tools/testing/selftests/hornet/trivial.bpf.c b/tools/testing/s= elftests/hornet/trivial.bpf.c new file mode 100644 index 0000000000000..d38c5b53ff932 --- /dev/null +++ b/tools/testing/selftests/hornet/trivial.bpf.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause + +#include "vmlinux.h" + +#include +#include +#include + +char LICENSE[] SEC("license") =3D "Dual BSD/GPL"; + +int monitored_pid =3D 0; + +SEC("tracepoint/syscalls/sys_enter_unlinkat") +int handle_enter_unlink(struct trace_event_raw_sys_enter *ctx) +{ + char filename[128] =3D { 0 }; + struct task_struct *task; + unsigned long start_time =3D 0; + int pid =3D bpf_get_current_pid_tgid() >> 32; + char *pathname_ptr =3D (char *) BPF_CORE_READ(ctx, args[1]); + + bpf_probe_read_str(filename, sizeof(filename), pathname_ptr); + task =3D (struct task_struct *)bpf_get_current_task(); + start_time =3D BPF_CORE_READ(task, start_time); + + bpf_printk("BPF triggered unlinkat by PID: %d, start_time %ld. pathname = =3D %s", + pid, start_time, filename); + + if (monitored_pid =3D=3D pid) + bpf_printk("target pid found"); + + return 0; +} --=20 2.52.0