Skip to content

Batch: nine compiler, sandbox and test fixes from @adilalperenciftci - #3474

Merged
paul-hammant merged 13 commits into
mainfrom
batch/contrib-2026-10-30
Oct 30, 2026
Merged

paul-hammant merged 13 commits into
mainfrom
batch/contrib-2026-10-30

Conversation

@paul-hammant

Copy link
Copy Markdown
Collaborator

Credit

This batch is Adil Alperen Çiftci's work (@adilalperenciftci). Thank you, Adil: nine focused fixes across the compiler, the sandbox runtime and the test suite. His authorship is preserved on each of his nine commits, cherry-picked unchanged from the pinned heads of the original PRs. The three commits at the top are ours and are small follow-ups (two test tightenings and one compiler warning fix, described below).

The nine changes

PR Change What the review found
#3447 Fail closed at effect analysis limits Effect analysis limits now refuse instead of silently passing.
#3448 Enforce hide/seal on destructuring Destructuring into a hidden name is refused, as declarations are.
#3449 Retain enum prefixes for containment hide Color now stops Color.Red, and seal except Color allows it.
#3441 Intersect embedded and preload sandbox policies Embedded and preload policies intersect, building on Nic's per-thread grant levels from #3334.
#3451 Honour zero sandbox verbosity AETHER_SANDBOX_VERBOSE=0 no longer forces stderr logging in every sandboxed child.
#3453 Audit entry fields on one snapshot Audit entry() reads one consistent snapshot.
#3458 Python host: restore nested map context Nested Python host calls restore the caller's map.
#3460 Shared-map hosts with sandbox ABI Shared-map host tests build with the sandbox ABI.
#3461 Sweep timeout: record SIGTERM directly sweep_timeout records SIGTERM in the hung process itself, fixing the macOS x86_64 flake.

Cherry-picked in this order, with no textual conflicts: 3461, 3447, 3448, 3449, 3453, 3441, 3451, 3460, 3458.

Our follow-ups

Verification

  • macOS (arm64): make -j8 and make test: 676 passed, 0 failed. effect_tag_limits, enum_containment, sweep_timeout, audit_entry_snapshot pass. host_python_map_context and the Linux-only sandbox tests skip (no python3-config on this Mac; preload is Linux/FreeBSD only).
  • Linux x86_64 (Ubuntu 22.04, real host), HARDEN=0 CC=gcc make ci (gcc -Werror): CI PASSED, Aether Tests 2055 passed, 0 failed, 25 skipped. An earlier run of this branch failed the -Werror compiler build on the truncation warning above, which is why the third follow-up exists.
  • Linux, run directly under both gcc and clang: sandbox_policy_intersection (5/5 cases), sandbox_verbose_flag, audit_entry_snapshot, host_python_map_context (PASS, python3.10 headers present), sweep_timeout, effect_tag_limits, enum_containment, hide_seal_directives (22/22) all pass.
  • Mutation check: with if (result == -1) return 1; added to check_grant (file grants ignored when no thread level), the new case "no thread level (-1): file grants lacking the resource deny" fails (exit 0, expected 3) and the script exits non-zero. Unmutated, all 5 cases pass.
  • tests/sandbox/test_shared_map_all.sh: on origin/main 0 of 13 pass; with this branch 12 pass, 1 fails (Ruby read), Java and Factor skipped. The Ruby failure is host configuration: the embedded Ruby cannot dlopen /usr/lib/libruby-3.0.so.3.0.2 (the library is at /lib/x86_64-linux-gnu/libruby-3.0.so.3.0), and the baseline fails Ruby for the same reason.

Not run

FreeBSD (the GhostBSD box was unreachable). Windows. Java and Factor shared-map hosts (dev packages not installed). Ruby shared-map with a corrected AETHER_RUBY_SONAME.

When this merges, the nine originals will be closed pointing here.

🤖 Generated with Claude Code

adilalperenciftci and others added 12 commits October 30, 2026 07:54
Record termination in the native foreground and background helpers instead of depending on when the shell emits trap output. Keep the timeout status, process-group cleanup, and Windows no-signal assertions unchanged.

Signed-off-by: Adil Alperen Ciftci <adilalperenciftci@users.noreply.github.com>
Signed-off-by: Adil Alperen Çiftci <adilalperenciftci@users.noreply.github.com>
Signed-off-by: Adil Alperen Çiftci <adilalperenciftci@users.noreply.github.com>
Signed-off-by: Adil Alperen Çiftci <adilalperenciftci@users.noreply.github.com>
I reproduced the wrapped audit ring advancing between the category, resource, and verdict accessors, which combined fields from different entries. Copy the selected entry under the ring lock and keep the accessor sequence in thread-local storage.

Add a synchronized overwrite regression test for the std.audit read order.

Signed-off-by: Adil Alperen Çiftci <adilalperenciftci@users.noreply.github.com>
Treat in-process grant levels and preload grants as independent boundaries. Continue to file or shared-memory grants after an in-process allow, while denying immediately when either policy refuses the operation.

Update the regression harness to exercise the current runtime hooks and cover both policy orderings.

Signed-off-by: Adil Alperen Ciftci <adilalperenciftci@users.noreply.github.com>
Signed-off-by: Adil Alperen Çiftci <adilalperenciftci@users.noreply.github.com>
Compile the in-process bridges with sandbox checker support and export each detected runtime library path before execution. This lets versioned Debian and Ubuntu runtimes reach the grant-map assertions instead of failing during setup.

Signed-off-by: Adil Alperen Çiftci <adilalperenciftci@users.noreply.github.com>
Preserve the previous shared-map token around nested run_sandboxed_with_map calls and restore it when the inner call returns. Reject an over-depth entry before activating or freezing the new map context.

Add an embedded CPython regression covering the inner map, restored outer map, and final token cleanup.

Signed-off-by: Adil Alperen Ciftci <adilalperenciftci@users.noreply.github.com>
…level case

Deny cases now require the harness's EACCES status (exit 3) instead of any
non-zero exit, so an unrelated failure (open errno, read error) no longer
passes as a denial. Add two cases where the embedded checker returns -1 (no
sandbox level on this thread): the preload file grants must decide, denying
when the grant list lacks the resource and allowing when it has it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When python3-config is found but the harness fails to compile or link, FAIL
rather than SKIP so a broken link on a real runner cannot pass silently.
Pass -lrt only on Linux so macOS builds do not receive a flag they lack, and
honour $CC so the test runs under gcc and clang.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gcc -Werror=format-truncation rejects snprintf of a 511-byte enum_prefix into
a 256-byte message buffer (typechecker.c, from the enum containment change).
Enlarge the buffer to hold the worst case; no behaviour change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

PY_CFLAGS="$(python3-config --embed --cflags 2>/dev/null || python3-config --cflags 2>/dev/null)"
PY_LIBS="$(python3-config --embed --ldflags 2>/dev/null || python3-config --ldflags 2>/dev/null)"
PY_SONAME="$(python3 -c 'import sysconfig; print(sysconfig.get_config_var("INSTSONAME") or "")' 2>/dev/null)"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the macOS CI failure: INSTSONAME there is a relative framework path (Python.framework/Versions/3.15/Python) that dlopen cannot resolve. Build it from the framework prefix when set: os.path.join(sysconfig.get_config_var("PYTHONFRAMEWORKPREFIX") or "", sysconfig.get_config_var("INSTSONAME")).

…framework libpython

On ELF a library with a runtime of its own binds that runtime's calls to
the importer's, which every Aether program exports (-rdynamic); the
copies merge, which binary_import_actors relies on for its exit drain.
An Aether consumer of a library made for another runtime ABI therefore
runs it on the importer's runtime, and the library's ABI check refuses
it. The matrix expected those pairs to run, so it failed on Linux on
main and on the 0.861.0, 0.862.0 and 0.863.0 releases, once the tree
was ahead of the latest release (0.860.0). Where the static libraries'
recorded IDs differ on ELF it now expects the refusal and its reason;
Mach-O and PE keep the copies apart and still run both ways.

host_python_map_context resolves a relative INSTSONAME (a framework
Python on macOS: Python.framework/Versions/3.x/Python) to the libpython
it names, so the macOS legs can dlopen it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

3 participants