-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
What happened?
The linux-headers postinst script runs make olddefconfig to prepare the build environment before recompiling scripts/ natively on the target host. This is necessary and correct for cross-compiled kernels — compiled host-side binaries from scripts/ cannot be shipped in the package since they target the build host, not the target machine.
However, make olddefconfig does more than just prepare the environment: it re-evaluates the kernel configuration against the toolchain available on the target host. If any tool that was present at kernel build time is absent or has a different version on the target, olddefconfig silently disables the corresponding CONFIG_* options and regenerates include/generated/autoconf.h accordingly.
As a result, the installed linux-headers package describes a different kernel than the one actually running — one that could have been built on this particular host, not the one that was actually built and installed.
autoconf.h is a build artifact: it must reflect the configuration of the already-compiled kernel image, not the capabilities of the installation host.
Affected options (examples)
| Build-time tool | Affected options | Consequence |
|---|---|---|
clang |
CONFIG_CC_IS_CLANG, CONFIG_LTO_CLANG, CONFIG_CLANG_VERSION |
Out-of-tree modules that check for LTO or clang-specific APIs get a false picture |
pahole (version-sensitive) |
CONFIG_DEBUG_INFO_BTF, related BPF options |
DKMS modules depending on BTF may behave incorrectly |
| GCC plugins | CONFIG_GCC_PLUGINS, CONFIG_GCC_VERSION |
Plugin-dependent options silently disappear |
Observed example
Kernel built with CC=clang and CONFIG_LTO_CLANG=y. Target host has only gcc installed. After package installation, make olddefconfig runs without CC=clang, detects gcc, and resets clang-dependent options:
# /boot/config-* (actual running kernel)
CONFIG_CC_IS_CLANG=y
CONFIG_LTO_CLANG_THIN=y
CONFIG_CLANG_VERSION=190107
# /usr/src/linux-headers-*/include/generated/autoconf.h (after postinst)
/* CONFIG_CC_IS_CLANG is not defined */
/* CONFIG_LTO_CLANG_THIN is not defined */
#define CONFIG_CLANG_VERSION 0
An out-of-tree module checking for LTO support or clang-specific kernel APIs gets an incorrect view of the kernel configuration.
Expected behavior
autoconf.h in the installed headers package should be identical to the one produced during kernel compilation, regardless of what toolchain is available on the target host.
Suggested fix
Preserve include/generated/autoconf.h from the kernel build tree in the package (it is already a build artifact present at packaging time). In postinst, save it before running make olddefconfig and restore it afterward — since olddefconfig is needed only to regenerate the supporting files that make scripts depends on, not to alter the kernel's configuration record.
This is consistent with how upstream scripts/package/install-extmod-build handles headers packaging: it ships include/generated as-is from the build tree and does not run olddefconfig on the target at all.
Armbian build framework version
Current main branch (lib/functions/compilation/kernel-debs.sh, function kernel_package_callback_linux_headers, postinst generation around line 530).