Skip to content

fix(permissions): don't require --allow-run for process.kill on self#34382

Merged
bartlomieju merged 3 commits into
mainfrom
fix/process-kill-self-permission
Jun 16, 2026
Merged

fix(permissions): don't require --allow-run for process.kill on self#34382
bartlomieju merged 3 commits into
mainfrom
fix/process-kill-self-permission

Conversation

@bartlomieju

Copy link
Copy Markdown
Member

Sending a signal to the current process is functionally equivalent to
terminating yourself, which never required permissions in the first
place (Deno.exit, abort, etc.). Tools like signal-exit (used by
vite and many others) re-raise the original signal on process.pid so
the parent shell sees the correct exit status, which forced users to
grant blanket --allow-run just to be able to Ctrl-C a process.

This skips the run-permission check in op_node_process_kill and
op_kill when the target pid is the current process's pid. Signalling
any other pid still requires --allow-run as before.

Fixes #34344

…low-run

Sending a signal to the current process is equivalent to terminating
yourself, which never required permissions in the first place
(Deno.exit, abort, etc.). Tools like signal-exit re-raise the original
signal on process.pid so the parent shell sees the correct exit, which
forced users to grant --allow-run just to Ctrl-C a process.

Skip the run permission check in op_node_process_kill and op_kill when
the target pid equals the current process pid. Killing other pids still
requires --allow-run.

Refs #34344

@fibibot fibibot 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.

No issue found. The self-PID carveout is applied in both op_node_process_kill and op_kill before check_run_all, while every other PID still requires --allow-run. The spec covers the non-terminating signal-0 path through both process.kill(process.pid, 0) and Deno.kill(Deno.pid, 0).

Holding approval until CI is green.

@fibibot fibibot 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.

CI found a real failure on this head: every failing unit shard hits tests/unit/process_test.ts killPermissions, where Deno.kill(Deno.pid, "SIGCONT") no longer throws without run permission after this change.

  1. Update killPermissions to match the new self-PID behavior and keep coverage that non-self PIDs still require --allow-run, or narrow the self-PID carveout so the existing permission contract remains true.

@bartlomieju bartlomieju added this to the 2.9.0 milestone Jun 7, 2026
@bartlomieju
bartlomieju dismissed fibibot’s stale review June 16, 2026 21:25

Addressed in commit d51b70e: killPermissions now asserts against a non-self pid (Deno.pid + 1) so the run-permission contract for other pids is preserved, while the self-pid carveout is exercised by the new killSelfNoPermissions unit test and the process_kill_self spec. CI is green on the current head.

@bartlomieju bartlomieju left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Reviewed the current head (merge of main into the branch). Clean, minimal, and well-tested; the security reasoning holds.

Correctness / security

  • The carveout is pid != std::process::id(), exempting only the exact own pid. Process-group targets stay protected: pid == 0 (caller's group), -1 (all processes), and negative group pids never equal std::process::id(), so they still require --allow-run. No permission hole.
  • Applied symmetrically in both op_node_process_kill and op_kill.
  • The stance is sound: self-signaling is already reachable via Deno.exit/abort and is equivalent to self-termination; it grants no capability over any other process. No escalation.
  • as i32 of the u32 pid is safe; real pids are well within i32 on all supported platforms.
  • Signal 0 is handled cross-platform (Unix None liveness probe, Windows process_is_alive), so the spec test works on Windows too.

Tests

  • killSelfNoPermissions (unit) and process_kill_self (spec) cover the self path through both process.kill and Deno.kill.
  • killPermissions retains the contract for non-self pids via Deno.pid + 1; the permission check runs before kill(), so the signal is never delivered regardless of whether that pid is live. Good.

No blocking issues. The earlier stale CHANGES_REQUESTED (made against the pre-fix commit 3c1e37e, where killPermissions still broke) has been dismissed since the fix landed in d51b70e. LGTM once CI on the merge head is green.

@bartlomieju
bartlomieju enabled auto-merge (squash) June 16, 2026 21:28
@bartlomieju
bartlomieju merged commit 039bcdc into main Jun 16, 2026
136 checks passed
@bartlomieju
bartlomieju deleted the fix/process-kill-self-permission branch June 16, 2026 22:12
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.

process.kill requires full run permissions

2 participants