Skip to content

blobs: check external-io-dir containment on path boundaries#172712

Open
fr-manvi wants to merge 1 commit into
cockroachdb:masterfrom
fr-manvi:blobs-io-dir-containment
Open

blobs: check external-io-dir containment on path boundaries#172712
fr-manvi wants to merge 1 commit into
cockroachdb:masterfrom
fr-manvi:blobs-io-dir-containment

Conversation

@fr-manvi

Copy link
Copy Markdown

The blob service resolves every nodelocal path against the configured --external-io-dir and then checks that the result stayed inside it, but ensureContained does that with a plain string prefix test against the absolute directory. filepath.Join has already collapsed the .. segments by the time the check runs, so a path that lands on a sibling directory whose name merely begins with the I/O directory's name satisfies the prefix and is accepted: with --external-io-dir=/data/backups, nodelocal://1/../backups-archive/x resolves to /data/backups-archive/x and passes. Every LocalStorage entry point routes through the same helper, so reads, writes, deletes, stats and listings all leave the directory the same way, whether they arrive from a nodelocal:// URI or over the Blob gRPC service. I noticed it while working out what the I/O directory actually guarantees for a principal that has been given external IO access but is not otherwise trusted with the node's filesystem. Comparing with filepath.Rel restores the boundary while keeping the check purely lexical, which is what the comment above prependExternalIODir asks for so that operators can still open up the directory with symlinks. The test covers the sibling-prefix case alongside the ordinary parent traversal that was already rejected.

Epic: none

ensureContained compared the joined path against the absolute
external I/O directory with a string prefix test. filepath.Join has
already resolved the .. segments at that point, so a path landing on a
sibling directory whose name begins with the I/O directory's name
satisfied the prefix and was accepted: with --external-io-dir=/data/backups,
nodelocal://1/../backups-archive/x resolved to /data/backups-archive/x.
Every LocalStorage operation routes through this helper, so reads,
writes, deletes, stats and listings all left the directory that way.

Compare with filepath.Rel instead, which restores the boundary and
stays lexical so symlinked I/O directories keep working.

Epic: none

Release note (bug fix): Fixed a bug where a nodelocal path could resolve
to a directory outside the one configured with --external-io-dir, if that
directory's name started with the configured directory's name.
@fr-manvi
fr-manvi requested a review from a team as a code owner July 22, 2026 06:59
@fr-manvi
fr-manvi requested review from msbutler and removed request for a team July 22, 2026 06:59
@blathers-crl

blathers-crl Bot commented Jul 22, 2026

Copy link
Copy Markdown

Thank you for contributing to CockroachDB. Please ensure you have followed the guidelines for creating a PR.

My owl senses detect your PR is good for review. Please keep an eye out for any test failures in CI.

I was unable to automatically find a reviewer. You can try CCing one of the following members:

  • A person you worked with closely on this PR.
  • The person who created the ticket, or a CRDB organization member involved with the ticket (author, commenter, etc.).
  • Join our community slack channel and ask on #contributors.
  • Try find someone else from here.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf.

@blathers-crl blathers-crl Bot added O-community Originated from the community X-blathers-untriaged blathers was unable to find an owner labels Jul 22, 2026
@cockroachlabs-cla-agent

cockroachlabs-cla-agent Bot commented Jul 22, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

O-community Originated from the community X-blathers-untriaged blathers was unable to find an owner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant