Skip to content

createDirectories chmods pre-existing directories, breaking writeFile under /tmp and other system dirs #1024

@andrewjamesbrown

Description

@andrewjamesbrown

Summary

FilesystemAdapter.createDirectories issues chmod on every directory in the provided path, including pre-existing top-level directories like /tmp that the sandbox user does not own. This causes any writeFile whose parent is an existing system directory to fail.

This violates POSIX mkdir -p --mode semantics: chmod should only apply to directories the call actually created, never to pre-existing ones.

Version

@alibaba-group/opensandbox 0.1.7 (also reproduced visually in 0.1.5 / 0.1.8 per maintainers of a downstream SDK).

Reproduction

const sandbox = await client.createSandbox({ image: 'ubuntu:22.04' /* default user not root */ });
// /tmp exists in the image, owned by root, 1777 perms
await sandbox.files.writeFiles([{ path: '/tmp/probe.txt', data: 'hello' }]);
// works, because writeFiles doesn't try to chmod /tmp

// But the typical "ensure parent then write" pattern fails:
await sandbox.files.createDirectories([{ path: '/tmp' }]);
// → SandboxApiException: error accessing file: chmod /tmp: operation not permitted
//   at FilesystemAdapter.createDirectories (dist/chunk-UTFOITR4.js:686)

Expected

createDirectories([{ path: '/tmp' }]) against an existing /tmp should be a no-op (idempotent, like mkdir -p). Chmod should only be applied if the call actually creates a directory.

Actual

The adapter unconditionally chmods every path component, regardless of whether it already existed. When the sandbox process lacks permission to chmod a pre-existing component (the common case for /tmp, /var, /etc, /usr), the entire call fails — even though no directory needed to be created.

Impact

  • Any downstream SDK that calls createDirectories defensively (to ensure a parent exists before writeFiles) breaks for paths under any system-owned directory.
  • The error message — chmod /tmp: operation not permitted — reads like a sandbox-config issue and is misleading. The actual cause is createDirectories doing more than it should.

Suggested fix

In createDirectories, only chmod directories that were actually created in this call (i.e., the ones that did not exist before). Skip chmod for any path component that already exists with adequate perms.

Workaround (in our downstream SDK)

We've shipped a "lazy ensureDir" pattern: try writeFiles first; only call createDirectories if that fails (typical case: parent missing). This avoids the redundant createDirectories call entirely when the parent exists, sidestepping the bug. It's not a real fix though — nested writes under /tmp/missing/dir/file still hit the issue because createDirectories would attempt to chmod /tmp even when only creating /tmp/missing/dir.

Happy to send a PR if it would help.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions