Validate package identity before privileged installs#248
Merged
ilysenko merged 2 commits intoMay 20, 2026
Conversation
Validate package identity before any pkexec-dispatched install or rollback command hands a local file to the system package manager. Constraint: privileged install commands accept a user-supplied --path after polkit authorization Rejected: filename-only validation | deb and rpm metadata can differ from the path, and pacman now verifies metadata after the filename precheck Confidence: high Scope-risk: narrow Directive: keep every privileged package-manager entrypoint behind package-name validation Tested: cargo fmt --all -- --check; cargo test -p codex-update-manager; cargo clippy -p codex-update-manager --all-targets -- -D warnings; bash tests/scripts_smoke.sh; bash -n install.sh scripts/lib/*.sh launcher/start.sh.template scripts/install-deps.sh scripts/build-deb.sh scripts/build-rpm.sh scripts/build-pacman.sh
There was a problem hiding this comment.
Pull request overview
This PR hardens the privileged updater install/rollback paths by verifying that a local package file resolves to the expected Codex Desktop package identity before invoking the system package manager (polkit-backed install-* --path / rollback flows).
Changes:
- Add
ensure_codex_package()guard to.deb,.rpm, and pacman installs and explicit rollback installs. - Implement package-name inspection for
.deb(dpkg-deb -f ... Package),.rpm(rpm -qp --queryformat %{NAME}), and pacman (pacman -Qqp), while retaining the pacman filename/version precheck. - Add unit tests for
ensure_package_name()and a pacman filename rejection case.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
updater/src/install.rs |
Adds package identity validation helpers and applies them to privileged install entrypoints; includes new tests. |
updater/src/install_rollback.rs |
Applies the same package identity validation to privileged rollback install entrypoints. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
207
to
211
| "Debian package not found: {}", | ||
| path.display() | ||
| ); | ||
| ensure_codex_package(path)?; | ||
| ensure_upgrade_path(path)?; |
Comment on lines
+20
to
+24
| @@ -21,6 +21,7 @@ pub fn install_deb(path: &Path) -> Result<()> { | |||
| "Debian rollback package not found: {}", | |||
| path.display() | |||
| ); | |||
| ensure_codex_package(path)?; | |||
Comment on lines
+459
to
+463
| let output = Command::new(program_path(DPKG_DEB_CANDIDATES, "dpkg-deb")) | ||
| .arg("-f") | ||
| .arg(path) | ||
| .arg("Package") | ||
| .output() |
Comment on lines
+496
to
+500
| let output = Command::new(program_path(RPM_CANDIDATES, "rpm")) | ||
| .arg("-qp") | ||
| .arg("--queryformat") | ||
| .arg("%{NAME}") | ||
| .arg(path) |
|
|
||
| fn pacman_package_name(path: &Path) -> Result<String> { | ||
| let output = Command::new(program_path(PACMAN_CANDIDATES, "pacman")) | ||
| .args(["-Qqp"]) |
Privileged install now stages validated package artifacts in a private temp directory, re-validates the staged copy, and passes package paths behind option terminators before invoking package tools. This keeps the exact artifact that passed validation bound to the subsequent root install. Constraint: PR review identified TOCTOU and option-parsing gaps in package install paths. Rejected: Validating only the caller-provided path | it leaves a pathname swap window before the privileged package manager reads it. Confidence: high Scope-risk: narrow Directive: Keep future privileged installs pointed at the staged StablePackage path, not the caller-provided path. Tested: cargo fmt --all -- --check; cargo test -p codex-update-manager; cargo clippy -p codex-update-manager --all-targets -- -D warnings; bash -n install.sh scripts/lib/*.sh launcher/start.sh.template scripts/install-deps.sh scripts/build-deb.sh scripts/build-rpm.sh scripts/build-pacman.sh; bash tests/scripts_smoke.sh Not-tested: Live root package-manager installation against a real system package.
878198c to
b35bbc1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This tightens the privileged updater path so the polkit-backed install commands only hand Codex Desktop packages to the system package manager.
What changed:
.debpackage metadata withdpkg-deb -f ... Package.rpmmetadata withrpm -qp --queryformat %{NAME}pacman -QqpWhy:
The
install-* --pathcommands run behind a Codex Desktop update authorization prompt, so they should not accept an arbitrary local package path after authorization.Validation:
cargo fmt --all -- --checkcargo test -p codex-update-managercargo clippy -p codex-update-manager --all-targets -- -D warningsbash tests/scripts_smoke.shbash -n install.sh scripts/lib/*.sh launcher/start.sh.template scripts/install-deps.sh scripts/build-deb.sh scripts/build-rpm.sh scripts/build-pacman.sh