Skip to content

Reject root-only uinput setup readiness#16

Merged
OneNoted merged 4 commits intouinput-readiness-hardeningfrom
uinput-root-guard
Apr 15, 2026
Merged

Reject root-only uinput setup readiness#16
OneNoted merged 4 commits intouinput-readiness-hardeningfrom
uinput-root-guard

Conversation

@OneNoted
Copy link
Copy Markdown
Owner

Summary

  • reject whispers setup when it is evaluating /dev/uinput readiness as root
  • avoid reporting success from root-only permissions that do not apply to the desktop user
  • lock the regression with a targeted setup test

Verification

  • cargo test setup::tests:: -- --nocapture
  • cargo fmt --all -- --check
  • cargo check --all-targets
  • cargo clippy --all-targets -- -D warnings
  • cargo test

Follow-up stacked on #15.

Prevent `whispers setup` from short-circuiting on root-only `/dev/uinput` readiness, which can otherwise report success without configuring the actual desktop user.

Constraint: Automatic uinput setup should be evaluated for the real desktop user, not sudo-root permissions
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep setup privilege checks explicit so root-only readiness can never masquerade as user readiness
Tested: cargo test setup::tests:: -- --nocapture
Not-tested: Live sudo invocation
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ffcb2ba657

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/setup/side_effects.rs
}

pub(super) fn maybe_setup_injection_access(ui: &SetupUi) -> Result<InjectionSetupOutcome> {
validate_setup_user(unsafe { libc::geteuid() })?;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject root before mutating setup state

maybe_setup_injection_access now errors for uid == 0, but this function is invoked late in run_setup (after config writes and other side effects), so running whispers setup as root can still modify files and then fail at this check. In that scenario users end up with a partially applied, root-owned setup while the command reports failure; the root validation should happen at the start of setup so no state is changed before returning the error.

Useful? React with 👍 / 👎.

Keep the bundled and packaged README links valid by shipping the docs pages it references in release bundles and Cargo package contents.

Constraint: Packaged README links should not point to files that are omitted from shipped artifacts
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If README starts linking to new local docs, add those files to package and release artifact manifests in the same change
Tested: cargo package --list --allow-dirty; scripts/build-release-bundle.sh with temp dist dir (verified docs in tarball)
Not-tested: GitHub release workflow end-to-end
Reject `whispers setup` at the start of the setup flow when it is launched as root so it cannot mutate config or starter files before reporting the privilege error.

Constraint: Root-only setup runs must fail before any local state is written
Rejected: Leave the root guard inside the later injection setup helper | config and starter files can already be mutated before that point
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep the root guard at the top of `run_setup()` so later helpers cannot become the first failing point again
Tested: cargo test setup::tests:: -- --nocapture; cargo fmt --all -- --check; cargo check --all-targets; cargo clippy --all-targets -- -D warnings; cargo test
Not-tested: Live sudo invocation
Make the non-zero clipboard test consume stdin before exiting so CI reliably exercises the intended non-zero exit path instead of racing into a broken-pipe write.

Constraint: The test should still cover the non-zero exit path, not the broken-pipe write path
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep subprocess tests deterministic by making the child process consume the expected I/O before exiting
Tested: cargo test inject::tests:: -- --nocapture; cargo fmt --all -- --check; cargo check --all-targets; cargo clippy --all-targets -- -D warnings; cargo test
Not-tested: GitHub Actions rerun still pending
@OneNoted OneNoted merged commit d87e8b6 into uinput-readiness-hardening Apr 15, 2026
3 checks passed
@OneNoted OneNoted deleted the uinput-root-guard branch April 15, 2026 09:57
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.

1 participant