Skip to content

feat: disable ASLR for walltime/memory and seed Go's global math/rand - #596

Draft
not-matthias wants to merge 2 commits into
mainfrom
cod-4013-disable-aslr-in-walltimememory-and-fix-go-mathrand-seed-in
Draft

not-matthias wants to merge 2 commits into
mainfrom
cod-4013-disable-aslr-in-walltimememory-and-fix-go-mathrand-seed-in

Conversation

@not-matthias

Copy link
Copy Markdown
Member

Summary

Reduce run-to-run variance from random seeds the runner doesn't control.

  • ASLR off in walltime and memory. Simulation already runs under setarch --addr-no-randomize. Walltime and memory now do too, so the memory layout and address-seeded hashes (e.g. abseil's absl::Hash) stay the same across runs.
    • setarch wraps the innermost benchmark command, because the kernel clears ADDR_NO_RANDOMIZE when exec'ing setuid or file-capability binaries (sudo, memtrack).
    • setarch is probed once. If it fails (e.g. Docker's default seccomp profile), the runner warns and runs the benchmark unchanged.
  • GODEBUG=randautoseed=0 in every mode. The global math/rand starts from Seed(1). The value is prepended to the user's GODEBUG, so their settings are kept and an explicit randautoseed still wins.

Testing

  • cargo clippy --all-targets, executor and runner-shared tests pass.
  • Local walltime run: benchmark sees personality 0x40000 and GODEBUG=randautoseed=0,<user value>.
  • Memory mode not run end to end (needs eBPF privileges); the generated shell chain was checked by hand.

Open

  • Run a walltime variance A/B before un-drafting: ASLR off is on by default with no opt-out.

Fixes COD-4013

Set GODEBUG=randautoseed=0 on benchmark processes in every mode, so the
global math/rand source starts from Seed(1) instead of a random seed and
code that draws from it behaves the same on every run.

The setting is prepended to the user's GODEBUG. Go uses the last
occurrence of a setting, so the user's other settings are kept and an
explicit randautoseed from the user still wins.

Refs COD-4013
Simulation already runs under setarch --addr-no-randomize. Walltime and
memory kept ASLR on, so the memory layout and address-seeded hashes
(e.g. abseil's absl::Hash) changed on every run and added variance.

Wrap the innermost benchmark command in setarch for both modes. The
kernel clears ADDR_NO_RANDOMIZE when exec'ing setuid or file-capability
binaries, so setarch sits inside sudo/systemd-run for walltime and inside
the shell command that memtrack runs for memory mode.

setarch is probed once. When it fails, e.g. because Docker's default
seccomp profile blocks personality(ADDR_NO_RANDOMIZE), the runner warns
and runs the benchmark unchanged instead of failing. The probe is
skipped off Linux.

Refs COD-4013
@codspeed

codspeed Bot commented Oct 26, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

2 warnings

⚠️ Walltime results may be unreliable

Some benchmarks used the Walltime instrument outside CodSpeed Macro Runners, which can make the results inconsistent.

Learn more about Macro Runners

See affected benchmarks

⚠️ 8 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

✅ 41 untouched benchmarks
⏩ 6 skipped benchmarks1


Comparing cod-4013-disable-aslr-in-walltimememory-and-fix-go-mathrand-seed-in (8c12824) with main (d9612e3)

Open in CodSpeed

Footnotes

  1. 6 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

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