Skip to content

install: create leading directories in write-only directories - #14779

Open
abendrothj wants to merge 3 commits into
uutils:mainfrom
abendrothj:fix/install-write-only-leading-dirs
Open

abendrothj wants to merge 3 commits into
uutils:mainfrom
abendrothj:fix/install-write-only-leading-dirs

Conversation

@abendrothj

@abendrothj abendrothj commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #14778.

install -D could not create leading directories inside a directory that is writable and searchable but not readable, where GNU can:

$ mkdir wx && chmod 300 wx && echo hi > f
$ install -D f wx/sub/f
install: cannot create directory 'wx/sub': Permission denied

create_dir_all_safe opens the deepest existing ancestor with O_RDONLY | O_DIRECTORY to anchor the walk, which demands read permission. mkdirat only needs write and execute.

DirFd::open_anchor falls back to a search-only descriptor - O_PATH on Linux, O_SEARCH elsewhere - when the readable open returns EACCES. Everything install does through that descriptor works with it: mkdirat, openat of a child directory, openat with O_CREAT, fstatat, fchmodat, fchownat, renameat, linkat, unlinkat, utimensat. It cannot list directory entries, which the creation walk never does. Platforms with neither flag keep today's EACCES.

Only symlink-following opens get the fallback; the NoFollow opens in the descent are untouched, so the TOCTOU hardening from #10140 is unchanged.

install -d and installing into an existing write-only directory were already fine; this is only about creating leading directories.

Copilot AI lite review requested due to automatic review settings September 21, 2026 09:45

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.

@github-actions

github-actions Bot commented Sep 21, 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)

Copilot AI review requested due to automatic review settings September 22, 2026 01:04
@abendrothj
abendrothj force-pushed the fix/install-write-only-leading-dirs branch from 8d87373 to e53e63f Compare September 22, 2026 01:04

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
abendrothj force-pushed the fix/install-write-only-leading-dirs branch from e53e63f to 18a794d Compare September 22, 2026 01:40
Copilot AI review requested due to automatic review settings September 22, 2026 01:40

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

About the red Tests (unix) job: that runner is OpenBSD 7.9, which has neither O_PATH nor O_SEARCH, so there's no way to anchor *at calls on a directory we can't read and this approach can't work there. safe_traversal now exports SEARCH_ONLY_SUPPORTED and the new test skips when it's false.

To be explicit about the gap: install -D into a write-only directory still fails on OpenBSD, exactly as it did before this PR. The fix applies on Linux, macOS, FreeBSD, NetBSD and the Solaris family. I could add a path-based fallback for the rest, but that trades the fd-anchored traversal for plain path resolution and I'd rather not do that silently — tell me if you want it.

@abendrothj
abendrothj force-pushed the fix/install-write-only-leading-dirs branch from 18a794d to 3e557aa Compare October 1, 2026 01:15
Copilot AI lite review requested due to automatic review settings October 1, 2026 01:15

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 review overview

🟡 Changes recommended

Critical cross-platform compilation and test-gating issues remain unresolved.

Review effort: Lite
Findings: 2 High severity

Open (2)

Comment thread src/uucore/src/lib/features/safe_traversal.rs
Comment thread tests/by-util/test_install.rs Outdated
@codspeed

codspeed Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 10.56%

⚡ 2 improved benchmarks
❌ 2 regressed benchmarks
✅ 389 untouched benchmarks
⏩ 54 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Simulation three_39_bit_primes 346.9 ms 605.1 ms -42.67%
❌ Simulation du_all_wide_tree[(5000, 500)] 37.1 ms 38.5 ms -3.54%
⚡ Simulation five_38_bit_primes 1.8 s 1.7 s +11.16%
⚡ Simulation thirteen_39_bit_primes 9.4 s 9 s +4.09%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing abendrothj:fix/install-write-only-leading-dirs (57c03da) 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. ↩

Copilot AI lite review requested due to automatic review settings October 1, 2026 06:52

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 review overview

🟡 Changes recommended

A critical unit test fails on OpenBSD and the Linux fallback documentation needs correction.

Review effort: Lite
Findings: 2 High severity

Open (2)
Resolved since last review (1)
Previously missed (1)

In code that hasn't changed since last review

Low severity Correct inaccurate O_PATH and O_NOFOLLOW explanation

src/​uucore/​src/​lib/​features/​safe_traversal.rs:216

The Linux explanation here is inaccurate: O_PATH does not ignore O_NOFOLLOW; with O_PATH|O_NOFOLLOW it refers to the symlink itself (and combining O_DIRECTORY can reject it), rather than resolving it. The fallback intentionally omits O_NOFOLLOW to preserve Follow semantics, so document that choice directly instead of attributing it to an ignored flag.

This issue also appears on line 230 of the same file.

Comment thread src/uucore/src/lib/features/safe_traversal.rs Outdated
…irectories

Also skip the write-only unit test where neither O_PATH nor O_SEARCH exists.
Copilot AI lite review requested due to automatic review settings October 1, 2026 07:04

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.

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.

install: -D cannot create leading directories in a write-only directory

2 participants