kxbox: three boot profiles, and the kasan one cannot exist - #63
Merged
Conversation
A lesson asks for a kernel by name. That name used to be a free string that
nothing ever compared to anything, so boot("lockdpe") worked, printed a banner
saying lockdep, and ran the teaching kernel. A lesson about lock ordering would
then find no lock ordering problems and a reader would conclude the code has
none. kxbox/profiles.py is the registry of the three names that exist, boot()
raises on anything else and says what the three are, and the banner prints what
the profile turns on and what it costs.
The third profile is called memcheck and not kasan. arch/x86/Kconfig on the
pinned kernel selects HAVE_ARCH_KASAN only if X86_64 and selects
HAVE_ARCH_KFENCE with no condition, and Tier 0 is 32 bit because v86 is a 32 bit
emulator. KASAN also depends on !SLUB_TINY and the base here is tinyconfig,
which sets it. So the profile is built out of KFENCE, page poisoning,
DEBUG_PAGEALLOC and the slab debugger.
Working that out turned up that config/lockdep.config had been setting
CONFIG_KASAN=y and CONFIG_KASAN_GENERIC=y since it was written, and no kernel
this project has built ever had them. build/D-lockdep/config has no CONFIG_KASAN
line at all. Kconfig drops a symbol whose dependencies are unmet and says
nothing, so the build succeeded and the image booted and the fragment went on
claiming a feature that was never there. The two lines are gone and
tools/kconfig now fails a 32 bit profile that asks for an architecture gated
symbol, reading the condition off a committed excerpt of arch/x86/Kconfig rather
than having it written into the checker, so a kernel that starts supporting
KASAN on i386 turns the check off by itself.
Two new corpus artefacts, both real files out of the pinned tarball: the excerpt
above, and the whole of lib/Kconfig.kfence. Three lines of the kfence file were
unparsed, which is what taught kxray/source/kconfig.py to read if and endif as a
condition stack and range as a property. Six of the eight KFENCE symbols sit
inside if KFENCE and five of those have no depends on line of their own, so a
reader looking at one symbol alone cannot say why it is off. Symbol.conditions
is where the block condition and the symbol's own dependencies come back
together.
Baseline moves from 39 artefacts and 7837 lines to 41 and 7968, which is the two
new files and nothing else.
This was referenced Sep 6, 2026
Open
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.
The M1 row for this reads "Three boot profiles: teaching, lockdep and kasan". Two of the three are here, the third one cannot exist, and finding out why turned up a config bug this repository has been shipping since the lockdep fragment was written.
The three profiles
kxbox/profiles.pyis the list of kernels a lesson may ask for by name.There are two different things in this project called a profile and this file is where they are joined. A build profile is a row in
kxbox/kernel/pin.toml, there are six of them, they are namedA-fullthroughE-memcheckand they exist so somebody building kernels can settle the kill criterion. A boot profile is what a lesson writes. A lesson author should not have to know that the teaching kernel is currently built asA-full, or that it might be built asC-longtermnext month if the first one turns out to be too big for a tab.A name nothing builds now raises
boot(profile=...)took a free string that nothing compared to anything. The string was carried around and printed in the banner, so this worked:It printed a banner saying lockdep and ran the teaching kernel. Nothing after that would have failed. The lesson would boot, run, find no lock ordering problem, and a reader would conclude that the code they are looking at has none. A clean answer that means nothing is worse than a crash, because a crash gets fixed.
The banner also says what the profile turns on and what it takes for it, which is the line that stops somebody timing a function on the lockdep kernel and reporting the number:
There is no kasan profile
The milestone asked for one.
arch/x86/Kconfigon the pinned kernel has this, and it is the whole answer:Tier 0 is 32 bit x86 because v86 is a 32 bit emulator.
menuconfig KASANdepends onHAVE_ARCH_KASAN, nothing selects that on i386, soCONFIG_KASANis not a symbol that exists on this build. It does not appear in menuconfig and it cannot be set. There is a second reason on top of the architecture that would apply on a 64 bit build too: KASAN also depends on!SLUB_TINY, and the Tier 0 base istinyconfig, which sets it.KFENCE is selected with no condition on it, so 32 bit x86 does get that. It is the sampling cousin of KASAN and catches a subset of the same bugs, with out of band redzones on a rotating handful of allocations rather than a shadow byte for every eight bytes of memory.
config/memcheck.configis KFENCE plus page poisoning,DEBUG_PAGEALLOC, the slab debugger and the object and list checks, and that is the memory checking a 32 bit kernel can actually do.The profile is named
memcheckrather thankasanbecause calling it kasan would be the same lie in a different file.The bug this turned up
kxbox/kernel/config/lockdep.confighas been asking for this since the day it was written:The kernel that came out of it has neither. Every KASAN line in the generated config for that profile:
That one line says the compiler could have done it if the architecture had asked. There is no
CONFIG_KASANline at all, not even a# CONFIG_KASAN is not set, because a symbol whose dependencies are unmet is not turned off, it is dropped, and Kconfig drops it without printing anything. The build succeeded, the image booted, the measurements inRESULTS.mdare honest, and the fragment went on claiming a feature no kernel here has ever had. The failure was invisible from every direction at once.tools/kconfignow catches it, without a toolchain and in about a second:The condition is not written into the checker.
gates()reads it off the committed excerpt, so a kernel that starts supporting KASAN on i386 turns the check off by replacing a file rather than by somebody remembering this exists. The check is skipped entirely unless the merged fragments say the build is 32 bit, which they say in either of two ways,# CONFIG_64BIT is not setorCONFIG_X86_32=y.Two new corpus artefacts
Both are real files out of the pinned tarball rather than anything written for this.
corpora/source/pinned/arch/x86/Kconfig.excerptis 32 lines: the opening ofconfig X86and the run ofHAVE_ARCH_selects. The full file is 3138 lines and almost none of it is about this project. The kernel's own comment three lines aboveconfig X86is kept in the excerpt because it makes the same point, which is that theif X86_64markers are about what has been ported rather than about what is possible.corpora/source/pinned/lib/Kconfig.kfenceis the whole 99 line file, because it is the declaration of everything the memcheck profile turns on.Three of its lines came back unparsed, which is the useful part.
if KFENCEat line 26,range 1 65535at line 41 andendif # KFENCEat line 99. Rather than write the number down as acceptable,kxray/source/kconfig.pylearned to read them.ifandendifare a condition stack now, not presentation likemenuis. Six of the eight KFENCE symbols sit insideif KFENCEand five of those six have nodepends online of their own, so reading one of those symbols on its own tells you it has no conditions at all and leaves you unable to say why it is missing from a build.Symbol.withinis what the block said andSymbol.dependsis what the symbol said, andSymbol.conditionsputs them back together with the block first, because the block is the outer condition and reads that way on the page.rangeis a property now.KFENCE_NUM_OBJECTScarriesrange 1 65535, and that is the only place in the tree where the kernel says out loud what that number is allowed to be.The baseline moves from 39 artefacts and 7837 lines to 41 and 7968. That is 32 plus 99, which is exactly the two new files and nothing else.
What is not in here
Running
tools.kconfig --verifyagainst the builtD-lockdepconfig reports 11 more problems beyond the 2 KASAN ones fixed here, and they are all genuine.CONFIG_MATH_EMULATION,CONFIG_VIRTIO,CONFIG_VIRTIO_PCI,CONFIG_NET_9P,CONFIG_NET_9P_VIRTIO,CONFIG_9P_FS,CONFIG_9P_FS_POSIX_ACL,CONFIG_PAHOLE_HAS_SPLIT_BTF,CONFIG_SCHED_DEBUG,CONFIG_TASK_DELAY_ACCTandCONFIG_MEMCG. Two lines of the built config explain most of them:# CONFIG_NET is not setat line 748 and# CONFIG_CGROUPS is not setat line 159.They are not fixed here on purpose. This PR is about one row of the milestone, and the consequences of turning
CONFIG_NETon cannot be checked without rebuilding four kernels and measuring them again. A follow up issue with the evidence is better than a config change nobody can verify.E-memcheckis inpin.tomland has not been built yet, so its row inRESULTS.mdsaysnot measuredrather than a number somebody guessed.Checks
Every gate, locally: ruff check and format, 1475 pytest tests, 7 skipped, the node tests, lintprose across 37 files, and the check runs of diagrams, nbbuild, sitebuild, kxbox, vendor, baseline, claimledger, coverage, bpc, kconfig, refcheck, lintnb and kxmanim.
tools.kconfigreports7.2.2 pinned, 6 profile(s) clean.