Skip to content

Fix Chrome standalone runtime permissions#962

Merged
ilysenko merged 5 commits into
ilysenko:mainfrom
psypeal:codex/fix-chrome-cli-runtime-permissions
Jul 15, 2026
Merged

Fix Chrome standalone runtime permissions#962
ilysenko merged 5 commits into
ilysenko:mainfrom
psypeal:codex/fix-chrome-cli-runtime-permissions

Conversation

@psypeal

@psypeal psypeal commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Fix the Linux Chrome side-panel native-host failure that occurs when the official managed standalone Codex CLI is created under a cooperative umask 0002 and therefore has group-writable paths.

The implementation now treats this as a CLI execution trust-boundary problem rather than a launcher-wide permission setting. It does not apply a global umask 022 to Electron, app-server, hooks, host commands, or unrelated updater children, and it does not override stricter user policies such as 0027 or 0077.

Current update

Maintainer follow-up commit 2e230fa expands the earlier standalone-only checks into a cross-format CLI trust and recovery model. The current PR changes 15 source, packaging, test, and documentation files.

Launcher trust gate

  • Every generated launcher bundles launcher/cli-launch-path.py, including native packages with or without the updater, AppImage, Nix, and user-local installs.
  • The synchronous, execution-free helper runs before any CLI version probe or Electron startup.
  • It verifies the selected entry, canonical executable, ownership, executable type, and canonical parent chain. Current-user and root ownership are accepted; group/world-writable paths are rejected except for trusted root-owned sticky directories such as /tmp.
  • Managed standalone installs receive a recursive tree check. External or broken symlinks, unsupported file types, unsafe ownership, and group/world-writable content are rejected without execution or in-place repair.
  • Successful validation returns the canonical release binary, so replacing the visible CLI symlink cannot redirect later execution.
  • Standalone provenance is recorded outside the managed tree in ~/.codex-standalone-provenance. Replacing or removing the managed tree cannot silently reclassify an untrusted replacement as an npm or system CLI.
  • npm-managed CLIs are also subjected to executable and parent-chain trust checks. A fresh dedicated prefix such as ~/.codex-cli-npm is the documented recovery/install path for a rejected npm tree.

Standalone installation and recovery

The official standalone installer child runs with the caller's existing mask plus the write restrictions from 0022. A cooperative 0002 therefore becomes 0022, while stricter masks remain intact for the installer and unrelated processes keep the caller's original policy.

After stopping active installers and removing the complete rejected standalone tree, updater-enabled native packages can run:

codex-update-manager recover-standalone-cli --print-path

Non-default locations can be supplied explicitly:

codex-update-manager recover-standalone-cli \
  --codex-home /absolute/path/to/codex-home \
  --install-dir /absolute/path/to/bin \
  --print-path

Recovery:

  • refuses to overwrite an existing standalone tree
  • rejects relative, ambiguous, symlinked, or untrusted recovery paths
  • narrows only current-user-owned directory chains below $HOME that are required for the selected Codex home and command directory
  • resolves installer shells and download tools from trusted root-controlled system directories instead of inheriting potentially attacker-controlled user tools
  • applies the safe mask only to the installer child
  • validates the newly installed tree and returns its canonical executable

Automatic standalone updates likewise reject an unsafe visible-command directory before downloading or executing the installer. AppImage, Nix, and updaterless package users must reinstall through a verified channel into a fresh trusted path because those formats do not ship the recovery command.

Removing write bits from a rejected existing tree is deliberately not considered recovery: its executable may already have been modified. This follows the trust rule established in #852.

Root cause

The Chrome side-panel native host validates codexCliPath and its canonical parents. When the official standalone installer inherits umask 0002, newly created managed CLI paths can be group-writable and are correctly rejected by that host. Permission handling therefore belongs at managed-file creation and CLI execution boundaries, not in the global desktop process environment.

Validation

Current head 2e230fa has passed all required GitHub checks:

  • Rust and smoke tests
  • Debian, RPM, pacman, and Nix package builds
  • upstream DMG application build
  • dependency-install checks on Ubuntu 22.04, Ubuntu 24.04, and Debian 12

The prior head 7edeb8c passed local Rust, shell, formatting, clippy, and cross-format smoke validation. Those local results do not claim to validate the maintainer's later 2e230fa changes; a fresh manual/local full-diff review of the current head remains pending.

Status

This PR remains a draft. The existing changes-requested review predates the maintainer's 2e230fa follow-up and has not yet been cleared. The requested independent local-LLM review of the complete current diff also remains pending.

No final maintainer review or merge is being requested yet.

@ilysenko ilysenko left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for looking into this. The failure is real, but it is a narrow compatibility case: it requires the Chrome side panel, the managed standalone CLI, and a cooperative umask. There are no separate user reports for this exact failure, so it does not justify changing the umask of the entire launcher and all of its child processes.

Please move the fix into the trusted standalone install/update path:

  • Create new managed CLI releases with safe permissions from the start.
  • Treat an existing group/world-writable release as untrusted. Do not make it trusted with chmod, because its executable may already have been modified. Reject or reinstall it from a verified source.
  • Do not set a global umask 022 for Electron, app-server, hooks, and host commands. It weakens stricter masks such as 0077 and changes intentional cooperative 0002 behavior.
  • Do not override a stricter user-manager policy with UMask=0022 in the updater service. Scope permission handling to the managed files being created.
  • Add behavioral tests covering 0002, 0027, 0077, child-process inheritance, and a previously tampered managed CLI.

This repository has already addressed the same trust-boundary rule in #852: removing write bits from an untrusted tree must not “bless” its existing contents.

Please also verify the complete change against CONTRIBUTING.md, run the relevant tests locally before pushing the update, perform an independent full-diff review with a local LLM, and wait for every required CI check to pass before requesting maintainer review or merge.

@Yo-DDV Yo-DDV added risk: high Touches security, privileges, updates, persistence, or multiple package paths. type: bug A reproducible defect or regression in supported behavior. area: launcher and runtime Launcher, process lifecycle, webview, or packaged runtime behavior. area: updater Update detection, rebuild, install, rollback, or updater state. area: integrations Browser, desktop environment, portal, or external integration. labels Jul 14, 2026
@psypeal
psypeal force-pushed the codex/fix-chrome-cli-runtime-permissions branch from 9428d40 to 6908a31 Compare July 14, 2026 10:25
@Yo-DDV Yo-DDV removed risk: high Touches security, privileges, updates, persistence, or multiple package paths. type: bug A reproducible defect or regression in supported behavior. area: launcher and runtime Launcher, process lifecycle, webview, or packaged runtime behavior. area: updater Update detection, rebuild, install, rollback, or updater state. area: integrations Browser, desktop environment, portal, or external integration. labels Jul 14, 2026

@ilysenko ilysenko left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thanks for scoping the umask change to the standalone installer child and preserving stricter user policies. There are still three trust-boundary blockers:

  • Make an unsafe standalone trust failure block the launcher before any CLI version probe or Electron startup. The normal asynchronous preflight currently logs the failure and continues with the rejected CODEX_CLI_PATH.
  • Eliminate the visible CLI symlink race. The code validates the canonical standalone tree but then spawns the original unresolved path. Execute a stable verified target and add replacement/external-symlink regression tests.
  • Provide a recovery flow that remains safe under umask 0002. Directly rerunning the official installer inherits the same mask and recreates group-writable standalone state, so the documented clean reinstall can be rejected again.

Please add focused lifecycle and recovery coverage for these cases.

@psypeal
psypeal force-pushed the codex/fix-chrome-cli-runtime-permissions branch from 6908a31 to 646a296 Compare July 14, 2026 16:45
@psypeal
psypeal requested a review from ilysenko July 15, 2026 02:38
@psypeal
psypeal marked this pull request as ready for review July 15, 2026 02:39

@ilysenko ilysenko left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Reviewed current head 2e230fa. The previous trust-boundary blockers are addressed: unsafe standalone paths now fail before probes/Electron startup, verified canonical launch targets close the visible symlink race, and recovery installs a fresh trusted tree with scoped safe umask handling.

@ilysenko
ilysenko merged commit 29c76a5 into ilysenko:main Jul 15, 2026
10 checks passed
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.

3 participants