Background
The Lind memory layout reserves address range [0, GUARD_SIZE) (currently 4 KB) as a
guard page. Any memory access to this region should trap to catch null-pointer bugs.
However, this guard page has never been enforced — the vmmap entry for it was not
actually registered, so accesses to addresses near 0 silently succeeded.
A recent refactor (early_init_stack) attempts to properly map this region so that
accesses to it will fault. This exposed several places in the lind-glibc that perform
writes through uninitialized (NULL) pointers of the form:
libc_struct->field = val; // libc_struct is NULL
These writes land at small positive offsets from address 0 (i.e. within the guard
page). They went unnoticed before because the permissive memory management never
faulted on them, and the broken structs happened not to cause visible failures in
practice.
Goal
- Properly install the guard page at startup so that any access to
[0, GUARD_SIZE)
traps immediately.
- Audit and fix all glibc sites that perform invalid writes through NULL pointers.
Known offending sites (identified so far)
-
__libc_setup_tls (csu/libc-tls.c) — updates DTV fields via a NULL struct
pointer. Lind-wasm does not use the DTV mechanism, so this block was already removed
in a prior cleanup (see libc-tls.c). This site is resolved.
-
__libc_fork — at least one statement inside __libc_fork triggers a trap once
the guard page is enforced. The exact statement has not yet been identified. Needs
investigation.
-
Potentially more — these are only the two sites surfaced by the initial attempt.
A full audit of glibc initialization and fork paths is likely needed.
Background
The Lind memory layout reserves address range
[0, GUARD_SIZE)(currently 4 KB) as aguard page. Any memory access to this region should trap to catch null-pointer bugs.
However, this guard page has never been enforced — the vmmap entry for it was not
actually registered, so accesses to addresses near 0 silently succeeded.
A recent refactor (
early_init_stack) attempts to properly map this region so thataccesses to it will fault. This exposed several places in the lind-glibc that perform
writes through uninitialized (NULL) pointers of the form:
These writes land at small positive offsets from address 0 (i.e. within the guard
page). They went unnoticed before because the permissive memory management never
faulted on them, and the broken structs happened not to cause visible failures in
practice.
Goal
[0, GUARD_SIZE)traps immediately.
Known offending sites (identified so far)
__libc_setup_tls(csu/libc-tls.c) — updates DTV fields via a NULL structpointer. Lind-wasm does not use the DTV mechanism, so this block was already removed
in a prior cleanup (see
libc-tls.c). This site is resolved.__libc_fork— at least one statement inside__libc_forktriggers a trap oncethe guard page is enforced. The exact statement has not yet been identified. Needs
investigation.
Potentially more — these are only the two sites surfaced by the initial attempt.
A full audit of glibc initialization and fork paths is likely needed.