danos/system/kernel
Daniel Samson 5a5146ec13
kernel: ring 0 reaches user memory only through the checked copy
SMAP makes the rule the copy layer has followed since it was written into a
rule the hardware keeps. A ring-0 read or write of a user page now faults,
so any code that reaches for a user pointer directly fails the first time it
runs rather than the first time someone attacks it — and the suite becomes
the enforcement test, because every case exercises the kernel with the bit
on. Nothing had to be fixed to turn it on, which is the retrospective proof
that the nine stragglers converted earlier were all of them.

The interrupt entry needed one instruction first. Hardware does not clear
the alignment-check flag on its way into a handler, and ring 3 sets that
flag freely, so a process could have taken an interrupt with SMAP suspended
for the duration. The system call path was already covered — its flag mask
clears it — but the interrupt path needed a `clac`, which cannot simply be
assembled in: it is an invalid instruction on a processor without SMAP, and
danos boots on those too. So the entry ships as a three-byte NOP and is
patched at boot, through the physmap, because the kernel maps its own text
read-only.

The ordering that makes that safe is enforced rather than described: the
patch sets a flag, and no core will set the SMAP bit until it is true. A
translation that fails, or bytes that read back wrong through the address
they will actually be fetched from, leave the machine unhardened and saying
so — which is the same posture the IOMMU takes, and better than enforcing
over an entry path that cannot comply. The patch runs before interrupts are
enabled and before any second core exists; a comment says so, because the
three bytes pass through an encoding that must never be executed and a
future change that moves this later has to deal with that first.

Suite 114/114, with a case that reads a user page from ring 0 and requires
the fault, and the multi-core case asserting every core that ran work had
the bit — the same shape SMEP got, for the same reason: CR4 is per-core, and
a hardening is only as wide as its narrowest core.
2026-08-01 12:20:44 +01:00
..
architecture/x86_64 kernel: ring 0 reaches user memory only through the checked copy 2026-08-01 12:20:44 +01:00
acpi.zig kernel: the IOMMU backends move behind the architecture boundary 2026-07-30 07:16:08 +01:00
console.zig console: page-wrap instead of scrolling — never read the framebuffer 2026-07-21 19:22:59 +01:00
device-model.zig kernel: flatten the device/discovery code, merge power into acpi, rename fdt 2026-07-22 21:49:20 +01:00
devices-broker.zig kernel: user memory is reached only through a checked copy 2026-07-31 20:57:49 +01:00
fdt.zig kernel: flatten the device/discovery code, merge power into acpi, rename fdt 2026-07-22 21:49:20 +01:00
font.psf Re-organize the source tree as a monorepo mirroring the FHS 2026-07-10 12:55:56 +01:00
heap.zig docs: audit all 'what's next' sections against the code; fix stale comments 2026-07-22 02:23:51 +01:00
iommu.zig kernel: the IOMMU backends move behind the architecture boundary 2026-07-30 07:16:08 +01:00
ipc-synchronous.zig init: /protocol replaces the ServiceId registry 2026-08-01 02:39:07 +01:00
ipc.zig Re-organize the source tree as a monorepo mirroring the FHS 2026-07-10 12:55:56 +01:00
irq.zig init: /protocol replaces the ServiceId registry 2026-08-01 02:39:07 +01:00
kernel.zig kernel: ring 0 reaches user memory only through the checked copy 2026-08-01 12:20:44 +01:00
log-ring.zig build: the unix paths retire — configuration, logs, and volumes move into the danos tree 2026-07-31 19:41:35 +01:00
log.zig kernel: the boot transcript on screen, every line timestamped 2026-07-21 19:09:34 +01:00
platform.zig kernel: flatten the device/discovery code, merge power into acpi, rename fdt 2026-07-22 21:49:20 +01:00
pmm.zig M14b: DMA memory (dma_alloc / dma_free) 2026-07-10 19:43:59 +01:00
process.zig kernel: a hostile return address cannot fault the kernel 2026-08-01 11:22:07 +01:00
scheduler.zig kernel: user memory is reached only through a checked copy 2026-07-31 20:57:49 +01:00
sync.zig kernel: contain a fatal fault — name the task, release the BKL before halt 2026-07-14 09:05:10 +01:00
tests.zig kernel: ring 0 reaches user memory only through the checked copy 2026-08-01 12:20:44 +01:00
user-memory.zig kernel: user memory is reached only through a checked copy 2026-07-31 20:57:49 +01:00
vfs.zig init: /protocol replaces the ServiceId registry 2026-08-01 02:39:07 +01:00
wall-clock.zig kernel: tagged log ring — per-line pid/name/level records, klog_status 2026-07-21 15:30:28 +01:00