Skip to content

fix: validate ls special permission bits by position#3420

Open
matthewflint wants to merge 1 commit into
openai:mainfrom
matthewflint:mflint/sandbox-special-permission-bits
Open

fix: validate ls special permission bits by position#3420
matthewflint wants to merge 1 commit into
openai:mainfrom
matthewflint:mflint/sandbox-special-permission-bits

Conversation

@matthewflint
Copy link
Copy Markdown
Contributor

@matthewflint matthewflint commented May 15, 2026

Summary

  • Allow Permissions.from_str() to parse valid ls -l special execute-column markers: s/S for owner and group, and t/T for other.
  • Preserve the modeled execute bit for lowercase s/t; ignore the special bit itself because Permissions currently stores only rwx bits.
  • Keep validation position-aware so invalid cross-position markers, such as t in owner/group or s in other, are rejected.
  • Add regression coverage through parse_ls_la() for sticky directories, setuid/setgid-style entries, and invalid special-bit positions.

Test plan

  • UV_CACHE_DIR=/tmp/uv-cache UV_PROJECT_ENVIRONMENT=/tmp/openai-pr3420-venv UV_PYTHON=3.12.13 uv run pytest tests/sandbox/test_parse_utils.py
  • UV_CACHE_DIR=/tmp/uv-cache UV_PROJECT_ENVIRONMENT=/tmp/openai-pr3420-venv UV_PYTHON=3.12.13 uv run ruff check src/agents/sandbox tests/sandbox
  • UV_CACHE_DIR=/tmp/uv-cache UV_PROJECT_ENVIRONMENT=/tmp/openai-pr3420-venv UV_PYTHON=3.12.13 uv run pyright
  • UV_CACHE_DIR=/tmp/uv-cache UV_PROJECT_ENVIRONMENT=/tmp/openai-pr3420-venv UV_PYTHON=3.12.13 make format
  • UV_CACHE_DIR=/tmp/uv-cache UV_PROJECT_ENVIRONMENT=/tmp/openai-pr3420-venv UV_PYTHON=3.12.13 make lint
  • UV_CACHE_DIR=/tmp/uv-cache UV_PROJECT_ENVIRONMENT=/tmp/openai-pr3420-venv UV_PYTHON=3.12.13 make typecheck
  • UV_CACHE_DIR=/tmp/uv-cache UV_PROJECT_ENVIRONMENT=/tmp/openai-pr3420-venv UV_PYTHON=3.12.13 make tests

Issue number

N/A

Checks

  • I've added new tests
  • Documentation update is not needed for this parser-only bugfix
  • I've made sure the focused sandbox parser test, Ruff, and Pyright pass
  • I've run make format, make lint, make typecheck, and make tests

@matthewflint matthewflint force-pushed the mflint/sandbox-special-permission-bits branch from eb16c7e to e13755c Compare May 15, 2026 11:47
Copy link
Copy Markdown
Member

@seratch seratch left a comment

Choose a reason for hiding this comment

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

Thanks for fixing this. One small tightening suggestion: can we make the special execute-column handling position-aware?

ls -l only emits s/S in the owner and group execute columns, and t/T in the other execute column. The current generic triplet parser accepts t/T for owner/group and s/S for other, which should not appear in real ls output.

I think the behavior would be easier to defend if we kept the current rwx-only model but validated the special characters by position:

  • owner: allow x, s, S, -
  • group: allow x, s, S, -
  • other: allow x, t, T, -

Could you also add regression coverage for rejecting the invalid cross-position cases?

Validate special execute-column markers according to their ls position.

Owner and group now accept setuid/setgid markers `s` and `S`, while other accepts sticky markers `t` and `T`. Lowercase markers preserve the modeled execute bit, uppercase markers parse without execute, and cross-position markers are rejected.

Add parse_ls_la regression coverage for valid special-bit entries and invalid cross-position `s`/`S`/`t`/`T` cases.
@matthewflint matthewflint force-pushed the mflint/sandbox-special-permission-bits branch from e13755c to a649a4d Compare May 16, 2026 14:20
@matthewflint matthewflint changed the title fix: accept special ls permission bits in sandbox parsing fix: validate ls special permission bits by position May 16, 2026
@matthewflint
Copy link
Copy Markdown
Contributor Author

@seratch thanks for the catch. I pushed an update that makes this validation position-aware now.

Owner and group accept x, s, S, and -; other accepts x, t, T, and -. Lowercase s/t still maps to the modeled execute bit, uppercase S/T parses without execute, and cross-position markers are rejected.

I also added regression coverage through parse_ls_la() for the invalid s/S/t/T positions and reran the parser test, Ruff, Pyright, and the repo checks listed in the PR body.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants