Introducing Hornet LSM
From: | Blaise Boscaccy <bboscaccy-AT-linux.microsoft.com> | |
To: | Jonathan Corbet <corbet-AT-lwn.net>, David Howells <dhowells-AT-redhat.com>, Herbert Xu <herbert-AT-gondor.apana.org.au>, "David S. Miller" <davem-AT-davemloft.net>, Paul Moore <paul-AT-paul-moore.com>, James Morris <jmorris-AT-namei.org>, "Serge E. Hallyn" <serge-AT-hallyn.com>, Masahiro Yamada <masahiroy-AT-kernel.org>, Nathan Chancellor <nathan-AT-kernel.org>, Nicolas Schier <nicolas-AT-fjasle.eu>, Shuah Khan <shuah-AT-kernel.org>, Mickaël Salaün <mic-AT-digikod.net>, Günther Noack <gnoack-AT-google.com>, Nick Desaulniers <nick.desaulniers+lkml-AT-gmail.com>, Bill Wendling <morbo-AT-google.com>, Justin Stitt <justinstitt-AT-google.com>, Blaise Boscaccy <bboscaccy-AT-linux.microsoft.com>, Jarkko Sakkinen <jarkko-AT-kernel.org>, Jan Stancek <jstancek-AT-redhat.com>, Neal Gompa <neal-AT-gompa.dev>, linux-doc-AT-vger.kernel.org, linux-kernel-AT-vger.kernel.org, keyrings-AT-vger.kernel.org, linux-crypto-AT-vger.kernel.org, linux-security-module-AT-vger.kernel.org, linux-kbuild-AT-vger.kernel.org, linux-kselftest-AT-vger.kernel.org, bpf-AT-vger.kernel.org, llvm-AT-lists.linux.dev, nkapron-AT-google.com, teknoraver-AT-meta.com, roberto.sassu-AT-huawei.com, xiyou.wangcong-AT-gmail.com | |
Subject: | [PATCH v2 security-next 0/4] Introducing Hornet LSM | |
Date: | Fri, 04 Apr 2025 14:54:49 -0700 | |
Message-ID: | <20250404215527.1563146-1-bboscaccy@linux.microsoft.com> | |
Archive-link: | Article |
This patch series introduces the Hornet LSM. The goal of Hornet is to provide a signature verification mechanism for eBPF programs. eBPF has similar requirements to that of modules when it comes to loading: find symbol addresses, fix up ELF relocations, some struct field offset handling stuff called CO-RE (compile-once run-anywhere), and some other miscellaneous bookkeeping. During eBPF program compilation, pseudo-values get written to the immediate operands of instructions. During loading, those pseudo-values get rewritten with concrete addresses or data applicable to the currently running system, e.g., a kallsyms address or an fd for a map. This needs to happen before the instructions for a bpf program are loaded into the kernel via the bpf() syscall. Unlike modules, an in-kernel loader unfortunately doesn't exist. Typically, the instruction rewriting is done dynamically in userspace via libbpf. Since the relocations and instruction modifications are happening in userspace, and their values may change depending upon the running system, this breaks known signature verification mechanisms. Light skeleton programs were introduced in order to support early loading of eBPF programs along with user-mode drivers. They utilize a separate eBPF program that can load a target eBPF program and perform all necessary relocations in-kernel without needing a working userspace. Light skeletons were mentioned as a possible path forward for signature verification. Hornet takes a simple approach to light-skeleton-based eBPF signature verification. A PKCS#7 signature of a data buffer containing the raw instructions of an eBPF program, followed by the initial values of any maps used by the program is used. A utility script is provided to parse and extract the contents of autogenerated header files created via bpftool. That payload can then be signed and appended to the light skeleton executable. Maps are frozen to prevent TOCTOU bugs where a sufficiently privileged user could rewrite map data between the calls to BPF_PROG_LOAD and BPF_PROG_RUN. Additionally, both sparse-array-based and fd_array_cnt-based map fd arrays are supported for signature verification. References: [1] https://lore.kernel.org/bpf/20220209054315.73833-1-alexei... [2] https://lore.kernel.org/bpf/CAADnVQ+wPK1KKZhCgb-Nnf0Xfjk8... Change list: - v1 -> v2 - Jargon clarification, maintainer entry and a few cosmetic fixes Revisions: - v1 https://lore.kernel.org/bpf/20250321164537.16719-1-bbosca... Blaise Boscaccy (4): security: Hornet LSM hornet: Introduce sign-ebpf hornet: Add a light-skeleton data extactor script selftests/hornet: Add a selftest for the Hornet LSM Documentation/admin-guide/LSM/Hornet.rst | 53 +++ Documentation/admin-guide/LSM/index.rst | 1 + MAINTAINERS | 9 + crypto/asymmetric_keys/pkcs7_verify.c | 10 + include/linux/kernel_read_file.h | 1 + include/linux/verification.h | 1 + include/uapi/linux/lsm.h | 1 + scripts/Makefile | 1 + scripts/hornet/Makefile | 5 + scripts/hornet/extract-skel.sh | 29 ++ scripts/hornet/sign-ebpf.c | 411 +++++++++++++++++++ security/Kconfig | 3 +- security/Makefile | 1 + security/hornet/Kconfig | 11 + security/hornet/Makefile | 4 + security/hornet/hornet_lsm.c | 239 +++++++++++ tools/testing/selftests/Makefile | 1 + tools/testing/selftests/hornet/Makefile | 51 +++ tools/testing/selftests/hornet/loader.c | 21 + tools/testing/selftests/hornet/trivial.bpf.c | 33 ++ 20 files changed, 885 insertions(+), 1 deletion(-) create mode 100644 Documentation/admin-guide/LSM/Hornet.rst create mode 100644 scripts/hornet/Makefile create mode 100755 scripts/hornet/extract-skel.sh create mode 100644 scripts/hornet/sign-ebpf.c create mode 100644 security/hornet/Kconfig create mode 100644 security/hornet/Makefile create mode 100644 security/hornet/hornet_lsm.c 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 -- 2.48.1