Skip to content

fix(resolver): skip inaccessible ancestors in readDirInfo - #28782

Closed
BenjaBobs wants to merge 1 commit into
oven-sh:mainfrom
BenjaBobs:bh/fix-sandbox-access-denied-errors
Closed

BenjaBobs wants to merge 1 commit into
oven-sh:mainfrom
BenjaBobs:bh/fix-sandbox-access-denied-errors

Conversation

@BenjaBobs

@BenjaBobs BenjaBobs commented Apr 2, 2026 •

Copy link
Copy Markdown

What does this PR do TLDR?

Allows bun to run in a sandbox like Landlock or Seatbelt.

Closes #28220

What does this PR do?

Fixes CouldntReadCurrentDirectory when Bun can read the current working directory but cannot open one or more ancestor directories while building resolver DirInfo.

The resolver now treats permission-denied ancestor directories as an inheritance boundary instead of aborting the whole lookup. If the target directory itself is unreadable, it still fails as before.

This also adds a Linux Landlock regression test for #28220 that reproduces the sandboxed bun run failure and verifies the fixed behavior.

How did you verify your code works?

  • env USE_SYSTEM_BUN=1 bun test test/regression/issue/28220.test.ts
    • fails with:
      • error loading current directory
      • CouldntReadCurrentDirectory
  • bun bd test test/regression/issue/28220.test.ts
    • passes with the fix

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@coderabbitai

coderabbitai Bot commented Apr 2, 2026 •

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Refined Zig resolver directory-read error handling: classify permission-denied errors, introduce a missing-parent sentinel and explicit parent-result flow to skip inaccessible non-target directories, change parent-index usage, and add a Linux-only Landlock regression test that compiles a helper and verifies sandboxed bun run behavior.

Changes

Cohort / File(s) Summary
Resolver Error Handling
src/resolver/resolver.zig
Added isPermissionDeniedDirReadError(err: anyerror) bool; introduced missing_parent_result sentinel and explicit parent_result variable; on permission-denied for non-target directories set parent_result = missing_parent_result and continue; use parent_result.index for parent lookups; assign parent_result = queue_top.result after processing queue entries.
Landlock Sandbox Regression Test
test/regression/issue/28220.test.ts
Added Linux-only test that generates and compiles a C Landlock helper (skips when unsupported), runs sandboxed bun run for ESM and CommonJS entries, and asserts expected stdout/stderr and exit codes for accessible and inaccessible target-directory cases.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: skipping inaccessible ancestors in the resolver's readDirInfo function, which is the core fix in this PR.
Description check ✅ Passed The PR description follows the required template with clear sections explaining what the PR does, the fix details, and verification steps performed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/regression/issue/28220.test.ts`:
- Around line 115-157: The test currently builds the landlock helper once into a
shared /tmp/landlock-helper and relies on module-level variables helperPath and
landlockSupported for other tests; change it so each test builds and self-checks
its own helper inside a test-specific tempDir (use tempDir from harness), remove
reliance on the shared helperPath/landlockSupported state, and invoke the
compile+self-check setup at the start of each test (or factor into a per-test
setup helper function referenced by test names like "compile landlock helper"
and the subsequent "bun run ..." tests) so paths are isolated and tests are
self-contained.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4bafb50e-5d30-44a7-808b-917200be4e6c

📥 Commits

Reviewing files that changed from the base of the PR and between 4760d78 and d2aace7.

📒 Files selected for processing (2)
  • src/resolver/resolver.zig
  • test/regression/issue/28220.test.ts

Comment thread test/regression/issue/28220.test.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/regression/issue/28220.test.ts`:
- Around line 135-145: The test reads the Landlock self-check stdout but never
asserts the subprocess exit code; add an explicit assertion on the Bun.spawnSync
result: after computing landlockSupported from check.stdout, assert that when
landlockSupported is true then check.status === 0 (or check.exitCode === 0 if
your environment uses exitCode), and when landlockSupported is false assert
check.status !== 0 (or non-zero exitCode). Use the existing variables check and
landlockSupported to locate where to add these assertions in
issue/28220.test.ts.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 622b25c7-0aa2-4f20-afbf-3e0e97ec2c13

📥 Commits

Reviewing files that changed from the base of the PR and between d2aace7 and 387729d.

📒 Files selected for processing (1)
  • test/regression/issue/28220.test.ts

Comment thread test/regression/issue/28220.test.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/regression/issue/28220.test.ts`:
- Around line 155-227: Add a new test case in
test/regression/issue/28220.test.ts that exercises the "unreadable target dir"
scenario: using the same prepareLandlockFixture/helperPath pattern, create a
tempDir (e.g., "issue-28220-unreadable-target-dir"), write a simple index/main
file into testBase, then make testBase itself unreadable (chmod 0 or use the
landlock helper to deny read to the target dir) before spawning Bun via
Bun.spawnSync with the same cmd/env/cwd/stdio settings; assert that stderr
contains the expected failure markers (e.g., "CouldntReadCurrentDirectory" or
"error loading current directory") and that result.exitCode is non-zero to lock
in the invariant that unreadable cwd fails, mirroring the other tests' structure
(reference the existing test names and prepareLandlockFixture/helperPath/bunExe
usage).
- Around line 12-15: The test currently assumes compilation succeeds by
asserting expect(compile.exitCode).toBe(0) after generating LANDLOCK_HELPER_SRC;
instead wrap the compile step (the invocation producing compile and the
assertion on compile.exitCode) in a try/catch or check compile.status and call
the test skip logic so build failures are treated as a skipped test. Locate the
compile invocation that uses LANDLOCK_HELPER_SRC and the
expect(compile.exitCode).toBe(0) assertion and replace it with a guarded block
that catches compilation errors or non-zero exitCode and calls the existing skip
path (the same skip behavior used later for runtime Landlock checks), ensuring
the rest of the test is not executed when the C compiler or <linux/landlock.h>
are unavailable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b6455ccb-e341-431c-a5c6-fd8db04a4099

📥 Commits

Reviewing files that changed from the base of the PR and between 387729d and a26e0a5.

📒 Files selected for processing (1)
  • test/regression/issue/28220.test.ts

Comment thread test/regression/issue/28220.test.ts
Comment thread test/regression/issue/28220.test.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/regression/issue/28220.test.ts`:
- Around line 163-176: The test suite gating currently uses
canCompileLandlockHelper() which only checks C compilation; change it to probe
runtime Landlock support instead: use prepareLandlockFixture() (or call the
compiled helper in a temp fixture) to obtain the runtime flag
prepareResult.landlockSupported (or landlockSupported) and set
landlockRuntimeSupported = prepareResult.landlockSupported; then use
describe.skipIf(!isLinux || !landlockRuntimeSupported) instead of
describe.skipIf(!isLinux || !landlockCompileSupported) so tests are skipped when
the kernel doesn't actually support landlock and the helper won't be invoked
erroneously.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7a40aaf8-2b9e-4759-a648-cbdee013050c

📥 Commits

Reviewing files that changed from the base of the PR and between a26e0a5 and f015917.

📒 Files selected for processing (1)
  • test/regression/issue/28220.test.ts

Comment thread test/regression/issue/28220.test.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/regression/issue/28220.test.ts`:
- Around line 134-160: prepareLandlockFixture currently returns an object with
compileSupported only on the early-return branch; update the final return to
include compileSupported so both branches return the same shape (include
compileSupported along with helperPath, landlockSupported, and testBase), and
ensure any expectations (e.g., checks using check.exitCode/stdout) still run
before returning.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ed6e5961-4b7d-4240-8971-40a5dd731408

📥 Commits

Reviewing files that changed from the base of the PR and between f015917 and 07c6dce.

📒 Files selected for processing (1)
  • test/regression/issue/28220.test.ts

Comment thread test/regression/issue/28220.test.ts Outdated
@BenjaBobs

Copy link
Copy Markdown
Author

Any news on this? Do you want me to update/rebase the pr?
Do you want it to go in another direction? Anything I can do to help this move along?

@BenjaBobs
BenjaBobs force-pushed the bh/fix-sandbox-access-denied-errors branch 2 times, most recently from cee35b0 to 509fc54 Compare May 15, 2026 19:02
@BenjaBobs

Copy link
Copy Markdown
Author

Since the rust port is merged, I also ported this fix to rust now, it is ready for another review.

@panga

panga commented May 21, 2026

Copy link
Copy Markdown

+1

@BenjaBobs
BenjaBobs force-pushed the bh/fix-sandbox-access-denied-errors branch from 509fc54 to 1c282a1 Compare May 22, 2026 19:17
@BenjaBobs

Copy link
Copy Markdown
Author

Rebased again, it appears it now also fixes #30859, and the PR #31198 seems to be similar

@karljamoralin

Copy link
Copy Markdown

+1 on this as well

DevCoreXOfficial added a commit to DevCoreXOfficial/core-termux that referenced this pull request Jul 22, 2026
…dCurrentDirectory on Android

bun v1.3.14's readDirInfo resolver walks from CWD up to / opening every
ancestor with openat(O_DIRECTORY). Android sandbox blocks /data/, /data/data/
(outside com.termux), and / with EACCES. bun treats ANY ancestor-open failure
as fatal and throws CouldntReadCurrentDirectory.

Instead of returning ENOENT (which bun also treats as fatal), redirect
inaccessible ancestor opens to the CWD. The entries read for these redirected
ancestors are harmless since they don't carry bun config files.

This works around the missing fix from oven-sh/bun#28782, which skips
permission-denied ancestors in the resolver but was not included in v1.3.14.
@robobun

robobun commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Thank you for this contribution!

This was fixed in #31938 and #33119: the resolver now treats EPERM/EACCES on ancestor directories as empty and continues. See src/resolver/resolver.rs on current main.

Closing as already fixed. Thanks again for taking the time to send this!

@robobun robobun closed this Jul 31, 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.

bun run fails with CouldntReadCurrentDirectory when ancestor directories are not readable

4 participants