Skip to content

fix: handle cross-mount resolv.conf symlinks in sandbox#32

Merged
jy-tan merged 7 commits intomainfrom
fix-cross-mount-symlinks
Feb 8, 2026
Merged

fix: handle cross-mount resolv.conf symlinks in sandbox#32
jy-tan merged 7 commits intomainfrom
fix-cross-mount-symlinks

Conversation

@jy-tan
Copy link
Copy Markdown
Contributor

@jy-tan jy-tan commented Feb 8, 2026

Summary

On WSL (and other systems where /etc/resolv.conf is a symlink to a path on a separate mount point), DNS-related reads fail inside the sandbox. This requires fixes at two layers: bwrap (mount setup) and Landlock (filesystem access control).

The root cause is that bwrap's --ro-bind / / is a non-recursive bind mount that doesn't capture child mount points. On WSL, /etc/resolv.conf -> /mnt/wsl/resolv.conf becomes a dangling symlink in the sandbox because /mnt/wsl (a 9p mount from the WSL hypervisor) isn't included. Additionally, even with the file made available via mounts, Landlock blocks reads to the resolved path since /mnt/wsl isn't in the allowed system paths.

Changes

  • bwrap mount setup (linux.go): sameDevice + intermediaryDirs helpers; walk from / to target's parent, --tmpfs at the mount boundary, --dir for deeper subdirs, --ro-bind the target file
  • Landlock (linux_landlock.go): add read rule for the resolved symlink target's parent directory

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 1 file

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="internal/sandbox/linux.go">

<violation number="1" location="internal/sandbox/linux.go:464">
P2: This logic unconditionally mounts a tmpfs over any directory found to be on a different device than root. If `resolv.conf` targets a path within `/dev` or `/proc` (e.g., `/dev/shm/resolv.conf`), this will overwrite the critical `--dev-bind` or `--proc` mounts established earlier (lines 438-439) with an empty tmpfs, breaking the sandbox's device access or process visibility.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread internal/sandbox/linux.go
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="internal/sandbox/linux.go">

<violation number="1" location="internal/sandbox/linux.go:453">
P2: Exclude `/run` and `/sys` from the special mount logic when `defaultDenyRead` is enabled, as they are already explicitly bound.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread internal/sandbox/linux.go
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="internal/sandbox/linux.go">

<violation number="1" location="internal/sandbox/linux.go:456">
P2: Disabling this fix in `defaultDenyRead` mode breaks DNS on systems (like WSL) where `resolv.conf` points to a path not in `GetDefaultReadablePaths` (e.g., `/mnt/wsl`).

Instead of disabling the fix globally for `defaultDenyRead`, you should allow it but specifically exclude paths that are already bound in that mode (like `/run` and `/sys`). This ensures `resolv.conf` works in both modes while avoiding overwritten binds.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread internal/sandbox/linux.go Outdated
@jy-tan jy-tan merged commit da5f61e into main Feb 8, 2026
5 checks passed
@jy-tan jy-tan deleted the fix-cross-mount-symlinks branch February 8, 2026 23:22
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