Skip to content

install: label only the directories it creates - #15333

Open
abendrothj wants to merge 2 commits into
uutils:mainfrom
abendrothj:install-context-created-dirs
Open

abendrothj wants to merge 2 commits into
uutils:mainfrom
abendrothj:install-context-created-dirs

Conversation

@abendrothj

@abendrothj abendrothj commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Closes #15332

Based on #15336, which -Z with relative names needs (tests/install/install-Z-selinux).

With -Z or --context, install labelled directories after creating them, by walking up from the target and setting the context on every existing parent too, up to / for an absolute path. GNU labels only what it creates.

Directories are now created under the creation context, through uucore's FsCreateContext as mkdir does, so only new ones are labelled and nothing is relabelled afterwards. It also resolves a relative name whose parents are created by the same command. This also gives new directories under -Z the policy's default type, the directory half of #15091 (except GNU's tmp_t for an absolute name directly in /tmp). As in GNU 9.12, -d -Z still resets an existing target to its default context, and -d --context leaves an existing target alone. An unusable --context now fails before anything is done, as in GNU, also when the target directory exists. With SELinux off, no context is set, as in mkdir.

Checked as root on Fedora 44 (enforcing) against GNU 9.12 for -d and -D with -Z and --context on new and existing directories: labels and exit status match, except that a new directory named by a relative path gets the kernel's default under -Z. That comes from the policy lookup in FsCreateContext, which mkdir shares, and is fixed separately in #15336. Added tests for -d and -D with --context, for the -Z reset of an existing directory, and for relative names with missing parents; each fails without the change.

Copilot AI balanced review requested due to automatic review settings October 14, 2026 05:14

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.

Comment thread src/uu/install/src/install.rs Outdated
match directory_creation_context(&target, b) {
Ok(guard) => guard,
Err(e) => {
show!(e);

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.

Is this stdout? or show_error!?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's stderr: show! prints like show_error! and also sets the exit code to 1, which GNU returns here.

@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

GNU test failed: tests/install/install-Z-selinux. tests/install/install-Z-selinux is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/tail/truncate. tests/tail/truncate is passing on 'main'. Maybe you have to rebase?

Copilot AI balanced review requested due to automatic review settings October 14, 2026 06:02
@abendrothj
abendrothj force-pushed the install-context-created-dirs branch from 3ddad2f to 69c9757 Compare October 14, 2026 06:02

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 Oct 14, 2026 •

Copy link
Copy Markdown

Merging this PR will regress 1 benchmark

⚠️ 123 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

ℹ️ 1 benchmark has no flame graph

The flamegraph could not be generated because too much time was spent in runtime internals, making the visualization not useful for performance analysis.

⚡ 2 improved benchmarks
❌ 1 regressed benchmark
✅ 398 untouched benchmarks
⏩ 70 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ ⚠️ Simulation sort_reverse_utf8_locale 79.2 ms 82 ms -3.39%
⚡ Simulation factor_three_39_bit_primes 567 ms 481.6 ms +17.72%
⚡ Simulation factor_thirteen_39_bit_primes 9.5 s 9.1 s +3.78%

Tip

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


Comparing abendrothj:install-context-created-dirs (c28736c) with main (c76f272)

Open in CodSpeed

Footnotes

  1. 70 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. ↩

#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))]
fn test_selinux_invalid_context_existing_directory() {
if !uucore::selinux::is_selinux_enabled() {
println!("Skipping SELinux test: SELinux is not enabled");

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.

I don't think there's any sense of using println! in tests, what do you think @xtqqczze?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't know, but we do the same in test_selinux.

Comment thread src/uu/install/src/install.rs Outdated
let _selinux_guard = {
let target = dir_strip_dot_for_creation(path);
match directory_creation_context(&target, b) {
Ok(guard) => guard,

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.

dir_strip_dot_for_creation(path) is computed again a few lines below, could be shared?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

// Like GNU, -Z resets an existing target to its default context; --context doesn't.
#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))]
if b.privileged && b.default_context && is_selinux_enabled() {
show_if_err!(set_selinux_security_context(path, None));

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.

why not set_selinux_default_context(path) as before?
and please add a test for this -Z reset of an existing dir

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

set_selinux_default_context doesn't ask the policy: it keeps the dir's own context, so nothing gets reset. set_selinux_security_context(path, None) looks the default up. Added test_selinux_default_context_resets_existing_directory, which fails with the old call.

Comment thread src/uu/install/src/install.rs Outdated
let mode = uucore::libc::S_IFDIR | DEFAULT_MODE as uucore::libc::mode_t;
uucore::selinux::FsCreateContext::new(path, Some(mode), get_context_for_selinux(b))
.map(Some)
.map_err(|e| uucore::error::USimpleError::new(1, e.to_string()))

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.

please use InstallError::SelinuxContextFailed like the other selinux errors here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

Comment thread tests/by-util/test_install.rs Outdated
// parent keeps its context.
#[test]
#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))]
fn test_selinux_context_only_on_created_directories() {

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.

could you please split it into two tests, one for -d and one for -D?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

// -Z looks the name up in the policy, which lists absolute names only: a relative
// name must get the same label as the absolute one.
#[test]
#[cfg(all(feature = "selinux", any(target_os = "linux", target_os = "android")))]

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.

this belongs to #15336, please rebase once it is merged

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, I'll rebase once #15336 is in.

@abendrothj
abendrothj force-pushed the install-context-created-dirs branch from 69c9757 to c28736c Compare October 14, 2026 22:08
Copilot AI balanced review requested due to automatic review settings October 14, 2026 22:08

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/-D with -Z or --context relabels directories that already exist

6 participants