FABRIC-2.md: correct glibc misattribution in 2h hot-detach writeup
block_subsystem.c is shared/vendored source -- its calloc()/free() calls resolve to real glibc in the hosted build, but to this kernel's own freestanding shims (src/starkernel/vm/host/shim.c, backed by kmalloc()/ kfree() in src/starkernel/memory/kmalloc.c) in the kernel build, which is where the address-reuse bug was actually diagnosed live. The previous writeup said "glibc's allocator" -- wrong environment entirely. Verified kmalloc_aligned() is a plain first-fit walk from heap_head with no coalescing, confirming the same free-then-immediate-same-size-alloc reuse behavior originally observed, just attributed to the right allocator. Caught by the user asking directly whether this project has any glibc dependency, given .claude/CLAUDE.md's strict ANSI C99/no-GNU-extensions requirement (confirmed -std=c99 throughout both Makefiles). Documentation correction only -- no code changed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CXjAPTEKrgY2Mrk25KoLDn
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
af267a52a6
commit
1b80609cb0
+19
-7
@@ -3883,13 +3883,25 @@ current tail — and recommended a pointer-identity check in `blk_vm_load()`'s c
|
||||
a minimal fix requiring no new API. That fix was implemented, then **directly falsified by its
|
||||
own designed-for-this test**: attach device A (blank), detach, re-attach device B (distinct
|
||||
content) at the identical LBN range, read that LBN — pointer comparison passed the check (i.e.
|
||||
called it a hit) and served **stale content from device A** anyway. Root cause: glibc's
|
||||
allocator hands `free(slot)` in `blk_subsys_detach_device()` straight back to the very next
|
||||
same-size `calloc(1, sizeof(*slot))` in `blk_subsys_attach_device()`, with nothing else allocated
|
||||
in between — confirmed live in this exact session, not inferred — so the "fresh" pointer and the
|
||||
stale one were bitwise identical despite belonging to two different physical devices. A pointer
|
||||
comparison cannot distinguish "still the same live device" from "a different device that
|
||||
happened to land at the same address" when the allocator is this deterministic.
|
||||
called it a hit) and served **stale content from device A** anyway. Root cause: this kernel's own
|
||||
freestanding heap allocator — `block_subsystem.c` is shared/vendored source, so its `calloc()`/
|
||||
`free()` calls resolve differently per build (real glibc in the hosted build; this kernel's own
|
||||
`malloc`/`free`/`calloc` shims in `src/starkernel/vm/host/shim.c`, backed by `kmalloc()`/
|
||||
`kfree()` in `src/starkernel/memory/kmalloc.c`, in the kernel build this bug was actually diagnosed
|
||||
in). `kmalloc_aligned()` is a plain first-fit walk from `heap_head` on every call; `kfree()` just
|
||||
marks a block's `free` flag — no coalescing, no randomization. `free(slot)` in
|
||||
`blk_subsys_detach_device()` hands its block straight back to the very next same-size
|
||||
`calloc(1, sizeof(*slot))` in `blk_subsys_attach_device()`, with nothing else allocated in
|
||||
between — confirmed live in this exact session, not inferred — so the "fresh" pointer and the
|
||||
stale one were bitwise identical despite belonging to two different physical devices. (An initial
|
||||
draft of this writeup attributed the reuse to "glibc's allocator" — wrong: the live diagnosis ran
|
||||
in the kernel build, nowhere near glibc; corrected after the user asked directly whether this
|
||||
project has any glibc dependency, per `.claude/CLAUDE.md`'s strict ANSI C99/no-GNU-extensions
|
||||
requirement, which the kernel build already honors throughout — this was a documentation
|
||||
attribution error, not a code or license-compliance one.) A pointer comparison cannot distinguish
|
||||
"still the same live device" from "a different device that happened to land at the same address"
|
||||
when the allocator is this deterministic — true of this first-fit kmalloc just as much as it
|
||||
would be of glibc's own allocator under the same free-then-immediately-realloc pattern.
|
||||
|
||||
Fixed properly with a monotonic `blk_subsys_epoch()` counter (`block_subsystem.c`, `uint64_t
|
||||
g.epoch`, bumped in `blk_subsys_attach_device()`, `blk_subsys_add_raw_device()`, and
|
||||
|
||||
Reference in New Issue
Block a user