Skip to content

Harden daemon: fail closed when COVEN_HOME or the socket is owned by another user#148

Open
maplesyzzurp wants to merge 1 commit into
OpenCoven:mainfrom
maplesyzzurp:harden/daemon-ownership
Open

Harden daemon: fail closed when COVEN_HOME or the socket is owned by another user#148
maplesyzzurp wants to merge 1 commit into
OpenCoven:mainfrom
maplesyzzurp:harden/daemon-ownership

Conversation

@maplesyzzurp
Copy link
Copy Markdown
Contributor

Completes the ownership leg of the docs/AUTH.md "Current hardening gap". That section says the daemon should fail closed when COVEN_HOME "is not owned by the current user" (L131) and that the socket root/dir/socket "must be owned by the current user" (L99). #144 landed the symlink / non-socket checks from the same list; this adds the missing ownership check.

What

ensure_private_coven_home and bind_api_socket now refuse an existing COVEN_HOME or socket whose owner uid differs from the daemon's effective uid — before creating, chmod-ing, or removing it. Without it, another local user who can write the parent directory could pre-plant the socket / status file / SQLite ledger for the daemon to adopt or replace.

How

A small pure helper check_owned_by_current_user(path, owner_uid, euid) bails on mismatch; callers pass metadata.uid() and libc::geteuid(). Keeping the comparison pure makes the refusal unit-testable without a root-owned fixture (which CI can't create).

  • std + libc only — no new dependencies.
  • One unsafe { libc::geteuid() } (always-safe FFI read; matches existing libc use in this file).
  • Group/world-accessible (AUTH.md L132) is already handled by the forced 0o700/0o600; ownership is the piece chmod can't fix.

Tests

  • New unit test for the helper (matching uid → ok, foreign uid → refused).
  • Existing socket/permission tests still pass (current-user happy path unchanged).
  • cargo test --workspace green, clippy -D warnings clean, fmt clean.

Opened against the contribution freeze as a focused security fix, in the same vein as #144 / #145.

…owned

docs/AUTH.md's "Current hardening gap" requires the daemon to refuse state
that is "not owned by the current user". OpenCoven#144 added the symlink / non-socket
checks from that list; this adds the missing ownership leg.

ensure_private_coven_home and bind_api_socket now reject an existing
COVEN_HOME or socket whose owner uid differs from the daemon's effective uid
— before creating, chmod-ing, or removing it — so another local user cannot
pre-plant the socket, status, or SQLite ledger. The owner comparison is a
pure helper, unit-tested without a root-owned fixture. std + libc only.
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