Skip to content

release: arm64 CI lane, json decode + floats, fatal RELRO re-protect#357

Merged
octalide merged 15 commits into
mainfrom
dev
Jul 3, 2026
Merged

release: arm64 CI lane, json decode + floats, fatal RELRO re-protect#357
octalide merged 15 commits into
mainfrom
dev

Conversation

@octalide

@octalide octalide commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Rolls dev to main: permanent [target.linux-arm64] + qemu aarch64 CI lane (#280/PR #353), decode-on-demand JSON string accessor (#340/PR #354), RFC 8259 float parsing in std.data.json + bounded-span parse_f64_len (#349/PR #355), and fatal RELRO re-protection (#347/PR #356, pairs with mach#1844/#1845).

octalide and others added 15 commits July 2, 2026 17:39
declare the aarch64/linux/aapcs64 cross-target so std is cross-buildable
to aarch64 out of the box, matching mach's own [target.linux-arm64].

Refs #280
cross-build std's test suite for linux-arm64 and run it under
qemu-aarch64, giving std an independent aarch64 regression signal
(mirrors the cross-riscv64 lane's install shape).

Refs #280
chore: permanent [target.linux-arm64] + qemu aarch64 CI lane
Resolve the parse/emit string-representation split (mach-std#340) with a
decode-on-demand accessor: the parser keeps storing raw wire bytes (zero-copy),
and value_string_decode unescapes them into logical bytes at the point of
consumption -- the inverse of the emit escaper. Handles " \ \/ \b\f\n\r\t and
\uXXXX including surrogate-pair astral code points decoded to UTF-8, erroring on
malformed escapes. Documents the raw-vs-decoded contract on the storage field
and both accessors.
Escape matrix (short escapes, \uXXXX BMP incl. uppercase hex, surrogate-pair
astral -> UTF-8, verbatim UTF-8 pass-through), malformed-escape rejection
(bad escape, truncated/non-hex \u, unpaired/lone/bad surrogate, trailing
backslash), the emit size-then-fill buffer protocol, and the reframed
round-trip decode(parse(emit(make_string(L)))) == L.
fix(data/json): decode-on-demand string accessor
parse_f64 assumes a null terminator (it derives length via str_len), which is
unsafe on a byte span embedded in a larger buffer -- the exact case a zero-copy
parser faces. Factor the body into parse_f64_len(s, len), bounded by an explicit
length, and have parse_f64 delegate with str_len(s). No behaviour change for
existing callers.
Extend number parsing to the full RFC 8259 grammar (fraction + exponent). A
number with a fraction or exponent yields a float value, parsed with correct
rounding via parse_f64_len over the zero-copy source span; integer-looking
numbers keep yielding an i64 exactly as before. Value gains is_float/float_val,
with value_is_float and value_float accessors (value_float widens integers so it
is defined for any NUMBER); emit writes floats in shortest round-trippable form.

Closes #349.
feat(data/json): float support in number parsing
_rt_relocate's PT_GNU_RELRO re-protection was best-effort: it skipped a region
not congruent with the runtime page (the documented large-page degradation) and
ignored the mprotect result. Now that the ELF writer aligns every segment to the
target's max page (>= any supported kernel page, briar-systems/mach#1845), the
region is always a whole number of runtime pages, so neither escape is
legitimate - an absent AT_PAGESZ, a congruence mismatch, or a failed mprotect is
a broken environment or a violated layout contract, and running unhardened would
silently mask it.

Extract the step into relro_reprotect, which panics naming the violated invariant
in each case - the glibc stance, matching std.system.os.page_size's AT_PAGESZ
precedent (#336/#343). No silent-unhardened path remains: a --pie binary either
runs fully hardened or dies loudly.
Add test/relro: a --pie happy-path probe (a relocated constant pointer, run
hardened, returns 42) and a fault probe that forces relro_reprotect down its
congruence-invariant branch and asserts the panic message on stderr plus death
by signal. verify.sh drives both, defaulting to native x86_64 and accepting a
target + qemu runner for the cross arches.

The fault probe calls relro_reprotect with forced incongruent args, so it
exercises the fatal branch independently of the compiler's page alignment - CI
covers it under the released mach seed (whose writer predates the max-page
layout). Wired into the build job (native) and both cross-qemu jobs.
runtime/linux: make RELRO re-protection failure fatal (part C)
@octalide octalide merged commit 5588e17 into main Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant