Skip to content

fix: enforce POSIX path permission checks on stat/lstat#372

Draft
toddr-bot wants to merge 1 commit intocpan-authors:mainfrom
toddr-bot:koan.toddr.bot/fix-stat-path-perms
Draft

fix: enforce POSIX path permission checks on stat/lstat#372
toddr-bot wants to merge 1 commit intocpan-authors:mainfrom
toddr-bot:koan.toddr.bot/fix-stat-path-perms

Conversation

@toddr-bot
Copy link
Copy Markdown
Collaborator

What

Enforce execute (search) permission on ancestor directories when stat/lstat resolve a path under set_user().

Why

POSIX requires execute permission on every directory component to resolve a path. stat("/a/b/c") should fail with EACCES when the caller lacks execute on /a or /a/b. Without this check, set_user() users could inspect file metadata in directories they couldn't traverse — breaking the permission model that all other operations now enforce.

Fixes #371.

How

  • Added _check_path_perms($path) helper that walks ancestor directories and checks execute permission via _check_perms(). Root bypasses the check entirely (root can always traverse directories, unlike the "needs at least one x bit" rule for executing regular files).
  • Called from _mock_stat() for path-based stat/lstat only — filehandle stat is correctly unaffected since the handle is already open.

Testing

10 new tests in t/stat_path_perms.t covering:

  • Accessible vs inaccessible parent directories
  • Deep paths with restricted intermediate ancestors
  • Root bypass
  • Owner/group/other permission triads
  • No-mock-user passthrough
  • Filehandle stat bypassing path checks
  • File test operators (-e, -f) inheriting the restriction

Full test suite passes (1596 tests, only pre-existing fh-ref-leak.t failures).

stat() and lstat() now check execute (search) permission on every
ancestor directory when set_user() is active.  Previously, stat()
returned file information regardless of directory permissions, allowing
any mock user to stat files in directories they couldn't traverse.

POSIX requires execute permission on each directory component to resolve
a path — e.g. stat("/a/b/c") needs execute on "/" , "/a", and "/a/b".
Root bypasses this check (root can always traverse directories).

Adds _check_path_perms() helper and 10 tests covering:
- Basic path permission enforcement for stat and lstat
- Deep paths with inaccessible intermediate directories
- Root bypass, owner/group permission triads
- Filehandle stat bypassing path checks (already open)
- File test operators (-e, -f) inheriting the restriction

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

bug: stat/lstat bypass path permission checks when set_user() is active

1 participant