Skip to content

runtime: intersect embedded and preload sandbox policies - #3441

Closed
adilalperenciftci wants to merge 1 commit into
aether-lang-dev:mainfrom
adilalperenciftci:fix/sandbox-policy-intersection
Closed

adilalperenciftci wants to merge 1 commit into
aether-lang-dev:mainfrom
adilalperenciftci:fix/sandbox-policy-intersection

Conversation

@adilalperenciftci

Copy link
Copy Markdown
Contributor

Summary

I reproduced an allowing in-process checker replacing, rather than composing with, an active preload grant list. In embedded guest runtimes this let the local checker authorize an operation that the outer process policy denied.

This change makes the two policies intersect:

  • an embedded denial still stops immediately;
  • an embedded allowance continues to the active shared-memory/file grant list;
  • when no preload policy is active, the embedded checker keeps its existing behavior;
  • denial logging remains single-shot at the layer that rejects the operation.

Verification

  • BEFORE: an allowing embedded checker bypassed a preload filesystem denial.
  • AFTER: the preload denial survives the embedded allowance.
  • Embedded denial with an allowing preload policy: passed.
  • Both policies allowing the operation: passed.
  • Sandbox spec-block, trusted-name, and preload-lookup integrations: passed.
  • make check-tests: passed.
  • make test: 634 passed, 0 failed on Ubuntu VM.
  • make check-changelog: passed.

Copilot AI balanced review requested due to automatic review settings October 29, 2026 08:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@paul-hammant

Copy link
Copy Markdown
Collaborator

Thanks. The change is right in intent: an embedded policy that allows shouldn't let a process skip a stricter preload grant list (levels should intersect). We're holding this one out of the batch with your other sandbox PRs, though, because it conflicts with an in-flight rework of the same code: #3334 (commit 6854baa, #2955) replaces the process-wide _aether_sandbox_checker with per-thread levels (aether_sandbox_check_resolved() returning 1 / 0 / -1, plus aether_sandbox_levels_here()).

The same bug survives there (any result >= 0 returns before the file grants), so the equivalent change on top of it would be:

if (aether_sandbox_check_resolved) {
    int r = aether_sandbox_check_resolved(category, match_target);
    if (r == 0) { log_deny(category, match_target); return 0; }
    /* r > 0 (allowed here) or -1 (no level): fall through to file grants */
}
if (!sandbox_active) return 1;

and the test harness would supply aether_sandbox_check_resolved / aether_sandbox_levels_here instead of _aether_sandbox_checker. Once #3334 lands, a rebase along those lines would be welcome. (Case 2 of the test passes on the old code too, so it's a guard rather than a proof; that's fine to keep.)

🤖 Generated with Claude Code

@adilalperenciftci

Copy link
Copy Markdown
Contributor Author

Adaptation plan after #3334 merges:

  • Rebase this branch onto the merged sandbox-level API.
  • Replace the harness's _aether_sandbox_checker stub with aether_sandbox_check_resolved() and aether_sandbox_levels_here().
  • Treat result 0 as an immediate denial with one denial record.
  • Treat result 1 and -1 as a continuation into the active preload grant list.
  • Preserve the no-preload-policy path after the level result is evaluated.
  • Re-run all policy-intersection cases: level denial/preload allow, level allow/preload denial, both allow, and no resolved level with preload enforcement.

I will not rebase or push the API adaptation until #3334 is merged.

@nicolas-maman

nicolas-maman commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

adilalperenciftci Can you please introduce yourself on nicolasmd87@gmail.com? Thank you

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>
@paul-hammant

Copy link
Copy Markdown
Collaborator

Thanks @adilalperenciftci! This landed in #3474, which batched nine of your PRs and merged on 2026-10-30 (ca1dae7d). Your commit went in unchanged with your authorship, so this PR is superseded, and I'm closing it.

On top of your commit, #3474 tightens sandbox_policy_intersection: the deny cases now require the harness's EACCES status (exit 3), and two new cases cover the embedded checker returning -1 (no level on this thread).

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.

4 participants