From: Pingfan Liu <piliu@redhat.com>
Cc: Pingfan Liu <piliu@redhat.com>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
John Fastabend <john.fastabend@gmail.com>,
Andrii Nakryiko <andrii@kernel.org>,
Martin KaFai Lau <martin.lau@linux.dev>,
Eduard Zingerman <eddyz87@gmail.com>, Song Liu <song@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>,
Jeremy Linton <jeremy.linton@arm.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>, Ard Biesheuvel <ardb@kernel.org>,
Simon Horman <horms@kernel.org>,
Gerd Hoffmann <kraxel@redhat.com>,
Vitaly Kuznetsov <vkuznets@redhat.com>,
Philipp Rudo <prudo@redhat.com>, Viktor Malik <vmalik@redhat.com>,
Jan Hendrik Farr <kernel@jfarr.cc>, Baoquan He <bhe@redhat.com>,
Dave Young <dyoung@redhat.com>,
Andrew Morton <akpm@linux-foundation.org>,
kexec@lists.infradead.org, bpf@vger.kernel.org
Subject: [PATCHv4 00/12] kexec: Use BPF lskel to enable kexec to load PE format boot image
Date: Tue, 22 Jul 2025 10:03:07 +0800 [thread overview]
Message-ID: <20250722020319.5837-1-piliu@redhat.com> (raw)
*** Review the history ***
Nowadays UEFI PE bootable image is more and more popular on the distribution.
But it is still an open issue to load that kind of image by kexec with IMA enabled
There are several approaches to reslove this issue, but none of them are
accepted in upstream till now.
The summary of those approaches:
-1. UEFI service emulator for UEFI stub
-2. PE format parser in kernel
For the first one, I have tried a purgatory-style emulator [1]. But it
confronts the hardware scaling trouble. For the second one, there are two
choices, one is to implement it inside the kernel, the other is inside the user
space. Both zboot-format [2] and UKI-format [3] parsers are rejected due to
the concern that the variant format parsers will inflate the kernel code. And
finally, we have these kinds of parsers in the user space 'kexec-tools'.
*** The approach in this series ***
This approach allows the various PE boot image to be parsed in the bpf-prog,
as a result, the kexec kernel code to remain relatively stable.
Benefits
And it abstracts architecture independent part and
the API is limitted
To protect against malicious attacks on the BPF loader in user space, it
employs BPF lskel to load and execute BPF programs from within the
kernel.
Each type of PE image contains a dedicated section '.bpf', which stores
the bpf-prog designed to parse the format. This ensures that the PE's
signature also protects the integrity of the '.bpf' section.
The parsing process operates as a pipeline. The current BPF program
parser attaches to bpf_handle_pefile() and detaches at the end of the
current stage via disarm_bpf_prog(). The results parsed by the current
BPF program are buffered in the kernel through prepare_nested_pe() and
then delivered to the next stage. For each stage of the pipeline, the
BPF bytecode is stored in the '.bpf' section of the PE file. That means
a vmlinuz.efi embeded in UKI format can be handled.
Special thanks to Philipp Rudo, who spent significant time evaluating
the practicality of my solution, and to Viktor Malik, who guided me
toward using BPF light skeleton to prevent malicious attacks from user
space.
*** Test result ***
Configured with RHEL kernel debug file, which turns on most of locking,
memory debug option, I have not seen any warning or bug for 1000 times.
Test approach:
-1. compile kernel
-2. get the zboot image with bpf-prog by 'make -C tools/kexec zboot'
-3. compile kexec-tools from https://github.com/pfliu/kexec-tools/pull/new/pe_bpf
The rest process is the common convention to use kexec.
[1]: https://lore.kernel.org/lkml/20240819145417.23367-1-piliu@redhat.com/T/
[2]: https://lore.kernel.org/kexec/20230306030305.15595-1-kernelfans@gmail.com/
[3]: https://lore.kernel.org/lkml/20230911052535.335770-1-kernel@jfarr.cc/
[4]: https://lore.kernel.org/linux-arm-kernel/20230921133703.39042-2-kernelfans@gmail.com/T/
v3 -> v4
- Use dynamic allocator in decompression ([4/12])
- Fix issue caused by Identical Code Folding ([5/12])
- Integrate the image generator tool in the kernel tree ([11,12/12])
- Address the issue according to Philipp's comments in v3 reviewing.
Thanks Philipp!
RFCv2 -> v3
- move the introduced bpf kfuncs to kernel/bpf/* and mark them sleepable
- use listener and publisher model to implement bpf_copy_to_kernel()
- keep each introduced kfunc under the control of memcg
RFCv1 -> RFCv2
- Use bpf kfunc instead of helper
- Use C source code to generate the light skeleton file
Pingfan Liu (12):
kexec_file: Make kexec_image_load_default global visible
lib/decompress: Keep decompressor when CONFIG_KEXEC_PE_IMAGE
bpf: Introduce bpf_copy_to_kernel() to buffer the content from
bpf-prog
bpf: Introduce decompressor kfunc
kexec: Introduce kexec_pe_image to parse and load PE file
kexec: Integrate with the introduced bpf kfuncs
kexec: Introduce a bpf-prog lskel to parse PE file
kexec: Factor out routine to find a symbol in ELF
kexec: Integrate bpf light skeleton to load zboot image
arm64/kexec: Add PE image format support
tools/kexec: Introduce a bpf-prog to parse zboot image format
tools/kexec: Add a zboot image building tool
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/kexec.h | 1 +
arch/arm64/kernel/machine_kexec_file.c | 3 +
include/linux/bpf.h | 39 ++
include/linux/decompress/mm.h | 7 +
include/linux/kexec.h | 6 +
kernel/Kconfig.kexec | 8 +
kernel/Makefile | 2 +
kernel/bpf/Makefile | 2 +-
kernel/bpf/helpers.c | 225 +++++++++
kernel/bpf/helpers_carrier.c | 211 +++++++++
kernel/kexec_bpf/Makefile | 71 +++
kernel/kexec_bpf/kexec_pe_parser_bpf.c | 67 +++
kernel/kexec_bpf/kexec_pe_parser_bpf.lskel.h | 147 ++++++
kernel/kexec_file.c | 88 ++--
kernel/kexec_pe_image.c | 463 +++++++++++++++++++
lib/decompress.c | 6 +-
tools/kexec/Makefile | 90 ++++
tools/kexec/pe.h | 177 +++++++
tools/kexec/zboot_image_builder.c | 280 +++++++++++
tools/kexec/zboot_parser_bpf.c | 158 +++++++
21 files changed, 2007 insertions(+), 45 deletions(-)
create mode 100644 kernel/bpf/helpers_carrier.c
create mode 100644 kernel/kexec_bpf/Makefile
create mode 100644 kernel/kexec_bpf/kexec_pe_parser_bpf.c
create mode 100644 kernel/kexec_bpf/kexec_pe_parser_bpf.lskel.h
create mode 100644 kernel/kexec_pe_image.c
create mode 100644 tools/kexec/Makefile
create mode 100644 tools/kexec/pe.h
create mode 100644 tools/kexec/zboot_image_builder.c
create mode 100644 tools/kexec/zboot_parser_bpf.c
--
2.49.0
next reply other threads:[~2025-07-22 2:03 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-22 2:03 Pingfan Liu [this message]
2025-07-22 2:03 ` [PATCHv4 01/12] kexec_file: Make kexec_image_load_default global visible Pingfan Liu
2025-07-22 2:03 ` [PATCHv4 02/12] lib/decompress: Keep decompressor when CONFIG_KEXEC_PE_IMAGE Pingfan Liu
2025-07-22 2:03 ` [PATCHv4 03/12] bpf: Introduce bpf_copy_to_kernel() to buffer the content from bpf-prog Pingfan Liu
2025-07-22 16:42 ` kernel test robot
2025-07-22 2:03 ` [PATCHv4 04/12] bpf: Introduce decompressor kfunc Pingfan Liu
2025-07-23 0:44 ` kernel test robot
2025-07-22 2:03 ` [PATCHv4 05/12] kexec: Introduce kexec_pe_image to parse and load PE file Pingfan Liu
2025-07-22 2:03 ` [PATCHv4 06/12] kexec: Integrate with the introduced bpf kfuncs Pingfan Liu
2025-07-22 2:03 ` [PATCHv4 07/12] kexec: Introduce a bpf-prog lskel to parse PE file Pingfan Liu
2025-07-22 2:03 ` [PATCHv4 08/12] kexec: Factor out routine to find a symbol in ELF Pingfan Liu
2025-07-22 17:22 ` kernel test robot
2025-07-22 2:03 ` [PATCHv4 09/12] kexec: Integrate bpf light skeleton to load zboot image Pingfan Liu
2025-07-22 2:03 ` [PATCHv4 10/12] arm64/kexec: Add PE image format support Pingfan Liu
2025-07-22 5:49 ` Catalin Marinas
2025-07-22 2:03 ` [PATCHv4 11/12] tools/kexec: Introduce a bpf-prog to parse zboot image format Pingfan Liu
2025-07-22 2:03 ` [PATCHv4 12/12] tools/kexec: Add a zboot image building tool Pingfan Liu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250722020319.5837-1-piliu@redhat.com \
--to=piliu@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=andrii@kernel.org \
--cc=ardb@kernel.org \
--cc=ast@kernel.org \
--cc=bhe@redhat.com \
--cc=bpf@vger.kernel.org \
--cc=catalin.marinas@arm.com \
--cc=daniel@iogearbox.net \
--cc=dyoung@redhat.com \
--cc=eddyz87@gmail.com \
--cc=horms@kernel.org \
--cc=jeremy.linton@arm.com \
--cc=john.fastabend@gmail.com \
--cc=kernel@jfarr.cc \
--cc=kexec@lists.infradead.org \
--cc=kraxel@redhat.com \
--cc=martin.lau@linux.dev \
--cc=prudo@redhat.com \
--cc=song@kernel.org \
--cc=vkuznets@redhat.com \
--cc=vmalik@redhat.com \
--cc=will@kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox