Skip to content

Linux sandbox fails with "bwrap: Can't create file ... Is a directory" when protected workspace path is a symlinked directory #15725

@Harag

Description

@Harag

What version of Codex CLI is running?

codex-cli 0.116.0

What subscription do you have?

Pro

Which model were you using?

gpt-5.4

What platform is your computer?

Linux 6.17.0-19-generic x86_64 GNU/Linux

What terminal emulator and version are you using (if applicable)?

bash on Ubuntu Linux

What issue are you seeing?

In my repro, the workspace root contains:

.agents -> some-folder/.agents

When Codex runs a normal shell tool in sandboxed mode, bubblewrap fails immediately with:

bwrap: Can't create file at .../.agents: Is a directory

This is not a normal permission denial. The problem is that the Linux sandbox is treating the protected alias like a file path and tries to mask it with a file-style bind, but the
alias resolves to a directory. bubblewrap rejects that path-type mismatch before the user command runs.

This may be in the same general Linux/bwrap/workspace-write area as other sandbox failures, but the exact symptom here is different from namespace creation failures: this repro is
specifically an Is a directory error caused by a symlinked directory alias at the workspace root.

What steps can reproduce the bug?

  1. On Linux, create a workspace where the root contains a symlink to a directory, for example:
    mkdir -p some-folder/.agents
    ln -s some-folder/.agents .agents

  2. Start Codex CLI in that workspace with a sandboxed mode that uses the Linux bubblewrap backend.

  3. Run any normal shell command through Codex, for example:
    pwd
    rg --files
    sed -n '1,20p' some-file
    git status

  4. Observe that the command fails before execution with:
    bwrap: Can't create file at .../.agents: Is a directory

  5. Switch to danger-full-access, or remove/rename the root .agents symlink, and the same command succeeds.

What is the expected behavior?

Sandboxed shell execution should still work when a protected workspace-root alias is a symlink to a directory.

If Codex needs to make that path read-only/unreadable inside bubblewrap, it should preserve the path type and bind the resolved directory appropriately instead of trying to file-mask
the alias. Routine shell commands should not fail before execution because a protected alias points to a directory.

Additional information

I tested a local fix and it resolves the repro.

Tested diff:

Local patch artifacts:

  • /tmp/codex-bwrap-symlink-directory-fix.patch
  • /tmp/codex-bwrap-symlink-directory-fix-verification.txt

Patch summary:

  • Detect when a protected alias resolves to an existing directory.
  • In that case, do not use a file-style /dev/null mask on the alias.
  • Instead, bind the resolved directory path in a way that preserves directory semantics.

Validation performed:

  • Rust tests passed for the new sandbox cases.
  • Direct bubblewrap repro confirmed the old behavior fails with Is a directory.
  • Direct bubblewrap verification confirmed the patched behavior keeps the directory readable while preventing writes through the protected alias.
  • The installed Codex wrapper was smoke-tested successfully after replacing the vendored binary with the locally built patched binary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingsandboxIssues related to permissions or sandboxing

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions