Bug-fix sweep: repl reentrancy, virtio/blocksys bounds, identity CRCs, LOG_LINE_MAX
Code review fixes, all compile clean (hosted gcc + aarch64/riscv64 kernel flags):
- repl.c (H1): reentrancy guards on the MSG-TICK idle pump. sk_repl_idle()
now defers when Hera is mid-interpret (g_mama_interpreting) or when its
own vm_interpret is on the stack (g_idle_pump_active), so a blocking
KEY/EXPECT/QUERY inside a dispatched line can no longer re-enter the
interpreter and clobber the in-flight input buffer.
- virtio_rng.c: clamp device-returned used_len to VRNG_BUF_SIZE before the
caller's data_buf copy, closing a device-controlled OOB read.
- block_subsystem.c: first-write path now keys off created_time==0 instead
of dead magic==0 so fresh blocks get a real created_time stamp; first_free/
last_allocated fixed to absolute Forth LBNs (set in blk_compute_fresh_geometry
from slot->start_lbn, no longer the wrong physical-BAM-index values from
compute_totals_from_B); physical-bounds guard on blk_meta_zone_read/write
prevents unsigned underflow on a corrupt fence >= device size.
- capsule_zuse_boot.c / capsule_wirebind.c: identity seed validated magic ->
version -> CRC-64 (compute_crc64 over offsetof(crc)) before trusting it,
so a corrupt/format-mismatched record is refused, never loaded.
- log.h / starkernel/log.h: unused LOG_LINE_MAX 256 renamed LOG_MSG_LINE_MAX
to lift the include-order collision with vm.h's LOG_LINE_MAX 64; stale
include-order comments dropped (kernel_main.c, shim.c, capsule_birth.c).
- FABRIC-3.md: three stale-doc carry-forward items closed [x] with cbe7b49
notes.
Real KEY/?TERMINAL/QUERY/EXPECT bodies (console WIP):
- repl.h/repl.c: sk_console_getkey()/sk_console_key_available()/
sk_console_readline() public bodies; non-destructive peek buffers the
found byte so a following KEY returns it.
- shim.c: getchar()/fgetc()/fgets()/sf_terminal_ready() routed through the
real console paths instead of stubs; sf_terminal_ready() in platform_io.h
with sf_terminal_ready() implemented for the hosted build (linux/io.c,
POSIX select on fd 0) wired into Makefile.
- io_words.c: ?TERMINAL now returns actual terminal-readiness, not constant 0.
Artifacts: minted disk/artemis.img + rebuilt lfs kernel; BLOCK_MAP.md,
doe csv + qemu log regenerated.
This commit is contained in:
+32
-5
@@ -367,10 +367,13 @@ static void compute_totals_from_B(blk_volume_meta_t *m) {
|
||||
uint64_t payload4k = (m->total_devblocks > (1+B+R+F)) ? (m->total_devblocks - 1 - B - R - F) : 0;
|
||||
uint64_t storable = 3ULL * payload4k;
|
||||
m->total_blocks = (m->tracked_blocks < storable) ? m->tracked_blocks : storable;
|
||||
uint64_t reserved = (uint64_t) BLK_DISK_SYS_RESERVED;
|
||||
if (reserved > m->total_blocks) reserved = m->total_blocks;
|
||||
m->first_free = BLK_DISK_SYS_RESERVED + reserved;
|
||||
m->last_allocated = BLK_DISK_SYS_RESERVED + reserved - 1;
|
||||
/* NOTE: first_free/last_allocated are intentionally NOT set here. They
|
||||
* are absolute Forth LBN hints (readers in blk_allocate()/blk_mark_free()
|
||||
* subtract slot->start_lbn), which this pure-geometry function cannot
|
||||
* know -- it has no slot/LBN-base context. Setting them to a physical
|
||||
* BAM index here made the first-free hint point at the wrong block; the
|
||||
* slot's owner establishes them from slot->start_lbn instead (see
|
||||
* blk_compute_fresh_geometry()). */
|
||||
}
|
||||
|
||||
/* ===== physical BAM I/O (sync to/from slot->bam[]) ===== */
|
||||
@@ -530,6 +533,14 @@ static void blk_compute_fresh_geometry(blk_dev_slot_t *slot) {
|
||||
slot->vol_meta.meta_fence_blocks = BLK_META_FENCE_INIT;
|
||||
compute_totals_from_B(&slot->vol_meta);
|
||||
|
||||
/* Allocation hints are absolute Forth LBNs (see the readers' note at
|
||||
* compute_totals_from_B()). This slot's first user-visible block is at
|
||||
* slot->start_lbn, so that is the true "next free" hint on a fresh
|
||||
* volume -- anything else (e.g. a physical BAM index) made the hint
|
||||
* point into the wrong block and left blk_allocate() guessing. */
|
||||
slot->vol_meta.first_free = (uint64_t) slot->start_lbn;
|
||||
slot->vol_meta.last_allocated = (uint64_t) slot->start_lbn - 1u;
|
||||
|
||||
if (sf_has_rtc()) slot->vol_meta.created_time = sf_realtime_ns();
|
||||
else slot->vol_meta.created_time = sf_monotonic_ns();
|
||||
|
||||
@@ -941,7 +952,14 @@ int blk_update(uint32_t block_num) {
|
||||
uint8_t *blkdata = c->data + pack * BLK_FORTH_SIZE;
|
||||
c->meta[pack].checksum = compute_crc64(blkdata, BLK_FORTH_SIZE);
|
||||
uint64_t now = blk_get_timestamp();
|
||||
if (c->meta[pack].magic == 0) {
|
||||
/* cache_load_devblock() already force-stamps magic on every load, so
|
||||
* testing magic==0 here is dead code that silently dropped the
|
||||
* first-write created_time stamp. A block that has never been written
|
||||
* before has created_time==0 (the loaded slot was memset); an existing
|
||||
* block carries its stamped-on-first-write non-zero created_time. Use
|
||||
* that as the first-write signal so a fresh block records its true
|
||||
* creation time. */
|
||||
if (c->meta[pack].created_time == 0) {
|
||||
c->meta[pack].magic = 0x424C4B5F5354524BULL;
|
||||
c->meta[pack].created_time = now;
|
||||
}
|
||||
@@ -1135,6 +1153,11 @@ int blk_meta_zone_read(uint32_t devblock_from_top, uint8_t buf[4096]) {
|
||||
blk_dev_slot_t *slot = first_disk_slot();
|
||||
if (!slot || !slot->dev) return BLK_ENODEV;
|
||||
if (devblock_from_top >= slot->vol_meta.meta_fence_blocks) return BLK_EINVAL;
|
||||
/* The fence index must also sit inside the physical device -- a corrupt
|
||||
* volume whose meta_fence_blocks >= total_devblocks would otherwise pass
|
||||
* the fence check and let (total_devblocks - 1 - devblock_from_top)
|
||||
* underflow on the unsigned subtraction below, targeting a wild devblock. */
|
||||
if ((uint64_t) devblock_from_top >= slot->vol_meta.total_devblocks) return BLK_EINVAL;
|
||||
|
||||
uint64_t devblock_idx = slot->vol_meta.total_devblocks - 1ULL - devblock_from_top;
|
||||
uint32_t base1k = (uint32_t) devblock_idx * 4u;
|
||||
@@ -1150,6 +1173,10 @@ int blk_meta_zone_write(uint32_t devblock_from_top, const uint8_t buf[4096]) {
|
||||
blk_dev_slot_t *slot = first_disk_slot();
|
||||
if (!slot || !slot->dev) return BLK_ENODEV;
|
||||
if (devblock_from_top >= slot->vol_meta.meta_fence_blocks) return BLK_EINVAL;
|
||||
/* Same physical-bounds guard as blk_meta_zone_read(): prevents the
|
||||
* unsigned underflow of (total_devblocks - 1 - devblock_from_top) on a
|
||||
* corrupt fence >= device size. */
|
||||
if ((uint64_t) devblock_from_top >= slot->vol_meta.total_devblocks) return BLK_EINVAL;
|
||||
|
||||
uint64_t devblock_idx = slot->vol_meta.total_devblocks - 1ULL - devblock_from_top;
|
||||
uint32_t base1k = (uint32_t) devblock_idx * 4u;
|
||||
|
||||
Reference in New Issue
Block a user