Skip to content

chmod, chown: check --preserve-root on the directory actually descended into - #14972

Open
abendrothj wants to merge 2 commits into
uutils:mainfrom
abendrothj:chmod-chown-operand-by-fd
Open

abendrothj wants to merge 2 commits into
uutils:mainfrom
abendrothj:chmod-chown-operand-by-fd

Conversation

@abendrothj

@abendrothj abendrothj commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

The recursive operand of chmod, chown and chgrp was checked against --preserve-root with its own path lookup, separate from the one the change and the descent used. A rename landing in between could send a -H/-L recursion into "/" after the check had passed.

chown/chgrp now also decide on the stat that the operand's descriptor is already verified against. chmod opens the operand, checks that descriptor, and changes its mode through it; it still reopens the directory to descend, like GNU, and only continues if it is the same directory. Under -P this also stops the operand's own mode change from following a symlink swapped in at the directory's name.

Closes #14990

Copilot AI balanced review requested due to automatic review settings September 30, 2026 02:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@codspeed

codspeed Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Merging this PR will improve performance by 12.57%

⚡ 2 improved benchmarks
✅ 391 untouched benchmarks
⏩ 54 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
⚡ Simulation three_39_bit_primes 346.9 ms 282.8 ms +22.69%
⚡ Simulation thirteen_39_bit_primes 9.4 s 9.1 s +3.29%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing abendrothj:chmod-chown-operand-by-fd (ab7438f) with main (cacdd8d)

Open in CodSpeed

Footnotes

  1. 54 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

GNU testsuite comparison:

Skipping an intermittent issue tests/date/resolution (passes in this run but fails in the 'main' branch)

@xtqqczze

This comment was marked as resolved.

@xtqqczze

This comment was marked as outdated.

@abendrothj

Copy link
Copy Markdown
Contributor Author

Opened #14990.

The recursive operand's --preserve-root check looked the path up again,
separately from the stat that the operand's descriptor is then verified
against. A rename landing between the two let that check see a harmless
directory while the chown and the descent went into "/" under -H or -L.

Also decide on that stat, through a new uucore::fs::dev_ino_is_root_dir.
The path lookup stays, so a symlink to "/" that the stat did not follow is
still reported as before.
The operand of a recursive chmod was checked against --preserve-root by
path, changed by path and then opened by path to descend, so a rename
landing between those steps could send the mode change and the descent
into "/" under -H, or through a symlink swapped in under -P.

Open the operand first, check that descriptor is not "/", and change the
mode through it. The directory is then opened again to descend, as GNU
does, so the new mode still decides whether it can be read, and the
descent goes ahead only if that is the same directory. A directory that
cannot be read before its mode change, and -H with --no-dereference,
still go by path.
Copilot AI balanced review requested due to automatic review settings October 1, 2026 01:17
@abendrothj
abendrothj force-pushed the chmod-chown-operand-by-fd branch from b5edd8c to ab7438f Compare October 1, 2026 01:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@abendrothj

Copy link
Copy Markdown
Contributor Author

The SELinux GNU job failed while booting its VM, before any test ran; unrelated to this change.

This branch has not been deployed

No deployments
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.

chmod, chown: -R --preserve-root judges the operand by a separate path lookup

3 participants