[GH-ISSUE #6204] [Bug] Linux process sweep fails Java probe cleanup on unrelated non-dumpable or setgid processes #3780

Closed
opened 2026-10-31 00:43:58 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @kaoru0822-kitauji on GitHub (Oct 22, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/6204

Originally assigned to: @kaoru0822-kitauji on GitHub.

Before submitting

  • Searched open/closed issues and PRs for hermes sticky, EACCES environ, environment_errno_EACCES, withheld.
  • No credentials or private targets included.

Area

Process ownership (Ghidra Java probe cleanup), surfacing through rea setup / rea doctor

Observed behavior

On Linux, rea setup --dry-run --json (and doctor) can exit 1 with cleanup_incomplete from ghidra:java, although Java exited 0 and was parsed. The process-ownership sweep finds a live process that started during the probe, is unrelated to the probe, runs under the same effective UID, and whose /proc/<pid>/environ the kernel denies (EACCES):

process ownership token could not be read for 1 live process(es): environment_errno_EACCES=1; live candidates 3850=environment_errno_EACCES

This makes main CI intermittently red in tests/acceptance/setup/hermesClientSetup.test.ts:

  • run 39702707721 (sha 421d527), "Hermes custom sticky-profile selection…", line 300: setup returned the error above (full JSON in the job log). A rerun on the same sha passed.
  • run 39703491153 (sha 13a8640), "Hermes suffix sticky-profile selection…", line 246: plan.exitCode was 1. The test does not print the JSON, so this run's error body was not captured. The ~1.5 s timing matches the same fast failure.

The Hermes profile resolution is deterministic: 20/20 local runs of the suffix scenario passed on macOS (where /usr/bin/java is the stub and the probe has no live JVM).

Reproduction

Linux container (kernel 6.8, Node 24.18.0, OpenJDK 21), running as uid 1000, compiled main (c465ff5a8). Run the suffix-test scenario (HERMES_DATA_DIR_SUFFIX=-dev, ~/.hermes-dev/active_profile = CoDeR, isolated USERPROFILE) through node scripts/rea.mjs setup --client hermes --dry-run --json, 10 times for each case:

Concurrent same-user noise (one new process every ~50 ms, each living 0.3 s) exit 1
none 0/10
python3 calling prctl(PR_SET_DUMPABLE, 0) 6/10
a setgid copy of sleep (egid differs) 9/10

Every failure had the environment_errno_EACCES reason above.

Expected behavior

As for another account's processes and macOS's withheld platform/restricted processes, a known-unrelated candidate whose environment the OS provably withholds should be reported as unverified instead of failing an otherwise clean cleanup. Related candidates (the leader's descendants and owned process groups) should still fail closed.

Analysis or suspected cause

Source-derived: environmentWithheldFromInspection (src/process/ProcessOwnership.ts) only exempts a different effective UID or Darwin's two withheld diagnostics. Linux also denies /proc/<pid>/environ (PTRACE_MODE_READ_FSCREDS) when the target's real or saved UID/GID differs from the caller's (setuid/setgid programs) or the target is non-dumpable. Those same-euid processes fail closed today. The Linux identity read already reads /proc/<pid>/status for token-unreadable candidates, but only keeps the effective UID.

Unverified: I don't know which process was involved in the CI runs (pid 3850). Parallel test workers on the shard are a plausible source.

Originally created by @kaoru0822-kitauji on GitHub (Oct 22, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/6204 Originally assigned to: @kaoru0822-kitauji on GitHub. ### Before submitting - [x] Searched open/closed issues and PRs for `hermes sticky`, `EACCES environ`, `environment_errno_EACCES`, `withheld`. - [x] No credentials or private targets included. ### Area Process ownership (Ghidra Java probe cleanup), surfacing through `rea setup` / `rea doctor` ### Observed behavior On Linux, `rea setup --dry-run --json` (and doctor) can exit 1 with `cleanup_incomplete` from `ghidra:java`, although Java exited 0 and was parsed. The process-ownership sweep finds a live process that started during the probe, is unrelated to the probe, runs under the same effective UID, and whose `/proc/<pid>/environ` the kernel denies (EACCES): ``` process ownership token could not be read for 1 live process(es): environment_errno_EACCES=1; live candidates 3850=environment_errno_EACCES ``` This makes main CI intermittently red in `tests/acceptance/setup/hermesClientSetup.test.ts`: - run 39702707721 (sha 421d527), "Hermes custom sticky-profile selection…", line 300: setup returned the error above (full JSON in the job log). A rerun on the same sha passed. - run 39703491153 (sha 13a8640), "Hermes suffix sticky-profile selection…", line 246: `plan.exitCode` was 1. The test does not print the JSON, so this run's error body was not captured. The ~1.5 s timing matches the same fast failure. The Hermes profile resolution is deterministic: 20/20 local runs of the suffix scenario passed on macOS (where `/usr/bin/java` is the stub and the probe has no live JVM). ### Reproduction Linux container (kernel 6.8, Node 24.18.0, OpenJDK 21), running as uid 1000, compiled `main` (c465ff5a8). Run the suffix-test scenario (`HERMES_DATA_DIR_SUFFIX=-dev`, `~/.hermes-dev/active_profile` = `CoDeR`, isolated `USERPROFILE`) through `node scripts/rea.mjs setup --client hermes --dry-run --json`, 10 times for each case: | Concurrent same-user noise (one new process every ~50 ms, each living 0.3 s) | exit 1 | | --- | --- | | none | 0/10 | | `python3` calling `prctl(PR_SET_DUMPABLE, 0)` | 6/10 | | a setgid copy of `sleep` (egid differs) | 9/10 | Every failure had the `environment_errno_EACCES` reason above. ### Expected behavior As for another account's processes and macOS's withheld platform/restricted processes, a known-unrelated candidate whose environment the OS provably withholds should be reported as `unverified` instead of failing an otherwise clean cleanup. Related candidates (the leader's descendants and owned process groups) should still fail closed. ### Analysis or suspected cause Source-derived: `environmentWithheldFromInspection` (`src/process/ProcessOwnership.ts`) only exempts a different effective UID or Darwin's two withheld diagnostics. Linux also denies `/proc/<pid>/environ` (PTRACE_MODE_READ_FSCREDS) when the target's real or saved UID/GID differs from the caller's (setuid/setgid programs) or the target is non-dumpable. Those same-euid processes fail closed today. The Linux identity read already reads `/proc/<pid>/status` for token-unreadable candidates, but only keeps the effective UID. Unverified: I don't know which process was involved in the CI runs (pid 3850). Parallel test workers on the shard are a plausible source.
bsakaguchi 2026-10-31 00:43:58 +00:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@kaoru0822-kitauji commented on GitHub (Oct 22, 2026):

Reproduced on latest main (c465ff5a8) in a Linux 6.8 container as described above. Main: non-dumpable noise caused 6/10 failures, setgid noise 9/10. With #6220: none 0/20, setgid 0/150, non-dumpable 1/150. #6220 describes the residual race it does not cover.

<!-- gh-comment-id:6331269639 --> @kaoru0822-kitauji commented on GitHub (Oct 22, 2026): Reproduced on latest main (c465ff5a8) in a Linux 6.8 container as described above. Main: non-dumpable noise caused 6/10 failures, setgid noise 9/10. With #6220: none 0/20, setgid 0/150, non-dumpable 1/150. #6220 describes the residual race it does not cover.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3780
No description provided.