fix(uki): harden reassembly, add stub-258 CI coverage, patch embedded kernel ImageBase - #138
Merged
Merged
Conversation
|
@imlk0 ,您好,您的请求已接收,请耐心等待结果。 |
|
@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start 。 |
|
@imlk0 ,您好,您的请求已接收,请耐心等待结果。 |
|
@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start 。 |
|
@imlk0 ,您好,您的请求已接收,请耐心等待结果。 |
|
@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start 。 |
|
@imlk0 ,您好,您的请求已接收,请耐心等待结果。 |
|
@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start 。 |
|
@imlk0 ,您好,您的请求已接收,请耐心等待结果。 |
|
@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start 。 |
|
@imlk0 ,您好,您的请求已接收,请耐心等待结果。 |
|
@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start 。 |
|
@imlk0 ,您好,您的请求已接收,请耐心等待结果。 |
|
@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start 。 |
imlk0
force-pushed
the
review-uki-section-fix
branch
from
September 21, 2026 02:07
9378f11 to
24b8e03
Compare
|
@imlk0 ,您好,您的请求已接收,请耐心等待结果。 |
|
@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start 。 |
uki_reassemble only checked for objdump after dracut had already spent minutes building the UKI. Hoist a pre-check for both objcopy and objdump to the start of the UKI block so a missing binutils fails fast, before any dracut work. Assisted-by: Claude:glm-5.2 Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
cp and mv were unguarded, and under set -e a failure (ENOSPC, EBUSY) aborted the function before reaching 'rm -rf $dumpdir', leaking /tmp/cryptpilot-uki-XXXXXX across runs. Add a RETURN trap that releases the scratch dir and any half-written .relayout on every exit path, and guard cp/mv with explicit error messages. Assisted-by: Claude:glm-5.2 Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
When the stub and dracut both carry .sbat with identical sizes, the stub's version is kept and dracut's is dropped. SBAT is a revocation list, so emit a NOTE so operators can audit which version survives. Assisted-by: Claude:glm-5.2 Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
The reassembly objcopy takes build_stub (a byte copy of the stub) as input and inherits its ImageBase from the PE optional header; the pipeline never modifies ImageBase. Passing --image-base=<same value> is therefore a no-op (verified on binutils 2.35: outputs are byte-identical with and without it), and on binutils lacking the flag it cannot be passed anyway. Remove the flag and its feature-detection case; the post-reassembly SizeOfImage sanity check still catches any regression. Assisted-by: Claude:glm-5.2 Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
…stub 258/259 For a pinned systemd stub with major version < 260 (systemd fixed it in >= 260, PR #40429), the stub's SizeOfImage math yields a wrong RVA and the UKI fails to boot at low RAM. Zero the kernel's PE OptionalHeader.ImageBase so the buggy stub's math yields the correct RVA. Patch the UKI assembly path: after uki_reassemble, dump the .linux section, patch its ImageBase to 0, and update-section it back (mirroring the existing .cmdline patching). Only the kernel embedded in the UKI is touched; /boot/vmlinuz is left byte-for-byte unchanged. Safe per the PE spec: ImageBase is the preferred load address, not used by the position-independent kernel at runtime (the stub loads it into its own base-0 buffer regardless). Define patch_kernel_image_base_zero inside the chroot heredoc (where objcopy/python3 live, alongside uki_reassemble). No-op when ImageBase is already 0 (>= v6.7 kernels / alinux4). Robust: validates MZ + PE signature + optional-header magic (PE32+/PE32), checks for truncation, writes + fsync + re-reads to verify. Caveat: changes the kernel hash, so re-sign and re-measure. Verified end-to-end: stub-258+alinux3 convert patches the UKI's .linux (log: "PATCHED .linux.bin: PE ImageBase 0x1000000 -> 0x0"); the output image's /boot/vmlinuz stays byte-identical to the source; the UKI boots at 4G/8G/16G. Assisted-by: Claude:glm-5.2 Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
…4:8G/4:16G) with --uki-stub-version 258 coverage The convert step is the expensive part; previously the CI pinned a single QEMU_RAM=4G per job. Replace --ram with a --boot-matrix option taking space-separated cpu:ram tokens; the script reuses the single converted output.qcow2 (each boot layers a fresh COW on the read-only base) and boots every combo, so convert runs once and only the cheap boot repeats. The matrix is scoped to two targeted rows (uki/noenc/disk on alinux3 and alinux4) carrying uki_stub_version=258 + boot_matrix="2:4G 4:8G 4:16G". GitHub-hosted ubuntu-latest has 4 vCPU and no nested KVM, so vCPU is capped at <=4 (= host nproc); the RAM dimension (4/8/16 G — the one that surfaces the UKI SizeOfImage hole) is kept. The 2:4G entry surfaces the hole on a pinned stub at low RAM. The baseline 24 jobs no longer carry a boot matrix (single boot, distro stub), cutting CI cost. --uki-stub-version is plumbed through test-convert.sh + the Makefile; the two vars reach make via the step env + docker exec --env (make imports them from the environment), avoiding inline quoting through bash -c. zstd is installed in the test container for the host-side Arch-Archive stub extraction. Robustness: bump the per-boot timeout 360 s -> 540 s for headroom on a loaded runner (TCG has no hardware acceleration on GitHub-hosted runners), retry each failed combo once before declaring the matrix broken, and add 'failed to start Boot ...: Load Error' + 'UEFI Interactive Shell' as failure markers so the boot test fails fast (in ~10s) when OVMF's StartImage returns Load Error instead of waiting the full 900s. Assisted-by: Claude:glm-5.2 Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
imlk0
force-pushed
the
review-uki-section-fix
branch
from
September 21, 2026 03:46
24b8e03 to
0601fab
Compare
|
@imlk0 ,您好,您的请求已接收,请耐心等待结果。 |
|
@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start 。 |
|
@imlk0 ,您好,您的请求已接收,请耐心等待结果。 |
|
@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start 。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #137 (
fix(uki): correct malformed section layout in UKIs generated by legacy dracut). Three concerns: hardenuki_reassemble, add--uki-stub-version 258CI coverage, and patch the kernel embedded in the UKI so systemd stub 258/259 can boot older kernels.1. uki_reassembly robustness (review feedback on #137)
objcopy/objdumpare checked at the start of the UKI block, before dracut spends minutes building the UKI.RETURNtrap releases the mktemp dir and any half-written.relayouton every exit path (includingset -eaborts);cp/mvare guarded..sbatdrops — when the stub and dracut both ship.sbatwith the same size, emit aNOTEso operators can audit which revocation version survives.--image-base— the reassemblyobjcopytakes a byte copy of the stub as input and inherits itsImageBasefrom the PE optional header; pinning--image-baseto the same value is a no-op (verified on binutils 2.35: outputs are byte-identical). The post-reassemblySizeOfImagesanity check still catches any regression.2.
--uki-stub-version 258CI coverage + boot matrixCI never passed
uki_stub_version, so every UKI job used the distro stub (ImageBase=0, no SizeOfImage hole) and the reassembly fix was never exercised against a real pinned stub. This PR plumbs--uki-stub-versionthroughtests/test-convert.sh+ the Makefile, and adds two CIincluderows (uki/noenc/diskon alinux3 and alinux4) carryinguki_stub_version=258+boot_matrix="2:4G 4:8G 4:16G". The baseline 24 jobs drop the boot matrix (single boot, distro stub) to keep cost down; make imports the two vars from the step env (no inlinebash -cquoting). The2:4Gentry surfaces the SizeOfImage hole on a real pinned stub at low RAM; the reassembly fix should make it boot. The boot test now also detects UEFIStartImage"Load Error" fast (instead of timing out).3. Patch the UKI's embedded kernel
ImageBasefor systemd stub 258/259systemd stub >= 258 and < 260 computes each inner kernel section's load offset as
(VirtualAddress - ImageBase)and rejects the image when that underflows, printingSection would write outside of memory(systemd #40342, regression from PR #37372, fixed in systemd >= 260 by PR #40429). Kernels v5.7..v6.6 are built withImageBase = CONFIG_PHYSICAL_START(default0x1000000) while their section RVAs (~0x4000) are below it, so a pinned 258/259 stub cannot boot them (e.g. alinux3 5.10); alinux4 (6.6) backported the mainline v6.7 revert toImageBase=0, so it boots.For a pinned stub in the buggy range (< 260),
uki_reassembleis followed byobjcopy --dump-section .linux→ patch the kernel PEOptionalHeader.ImageBaseto 0 →--update-section .linuxback (mirroring the existing.cmdlinepatching). Only the kernel embedded in the UKI is touched;/boot/vmlinuzis left byte-for-byte unchanged. Safe per the PE spec:ImageBaseis the preferred load address, not used by the position-independent kernel at runtime (the stub loads it into its own base-0 buffer). No-op whenImageBaseis already 0 (>= v6.7 kernels / alinux4). Caveat: changes the kernel hash, so re-sign and re-measure.Verification
bash -noncryptpilot-convert.shandtests/test-convert.sh;cargo fmt --check;cargo build..linux(PATCHED .linux.bin: PE ImageBase 0x1000000 -> 0x0); the output image's/boot/vmlinuzstays byte-identical to the source kernel; the UKI boots at 4G/8G/16G. Verified locally and in CI — theuki/noenc/disk/alinux3stub-258 job now passes (it previously failed withLoad Error).Note
The
build-and-push(Docker image) job on the latest run failed on a transientmirrors.aliyun.comrepo-metadata timeout (Curl error (28)), unrelated to this change — re-runnable.