[PR #7174] feat(process): support FreeBSD hosts #7696

Open
opened 2026-11-03 13:39:43 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/7174
Author: @ocochard
Created: 10/25/2026
Status: 🔄 Open

Base: main ← Head: freebsd


📝 Commits (2)

  • 4cbbed0 feat(ghidra): accept FreeBSD hosts and their native decompiler
  • 74d78d6 feat(process): support FreeBSD process listing and identities

📊 Changes

3 files changed (+131 additions, -5 deletions)

View changed files

📝 src/ghidra/GhidraInstallation.ts (+3 -0)
📝 src/process/ProcessOwnershipObservation.ts (+113 -4)
📝 src/process/capture/ProcessSampling.ts (+15 -1)

📄 Description

Summary

Let the Ghidra provider run on FreeBSD/amd64 hosts. Today rea doctor reports Ghidra as unavailable on FreeBSD
even with a working Ghidra installation, because REA rejects the platform, cannot find the FreeBSD native decomp
iler, and cannot track the processes it launches (the Java probe fails), since process identities are read only
from Linux procfs or the Darwin reader.

Problem and expected behavior

On FreeBSD 16.0-CURRENT amd64 with the ghidra package (GHIDRA_INSTALL_DIR=/usr/local/share/ghidra), rea doc tor reports for Ghidra:

platform,false,unsupported_host,freebsd
architecture,false,unsupported_host,x64
native_decompiler,false,executable_missing,Matching native decompiler for freebsd/x64 was not found
java,false,runtime_unavailable,"java: Process ownership baseline is unavailable on this host"

Underlying causes:

  1. NATIVE_PLATFORMS / NATIVE_TOOL_FORMATS have no freebsd entry, and the JVM os.name check has no FreeBS
    D case. The FreeBSD package ships the decompiler at Ghidra/Features/Decompiler/build/os/freebsd_x86_64/decompil e, a path REA already searches once the platform is mapped.
  2. ps -axo pid=,ppid=,... is procps syntax. BSD ps treats everything after the first = as the column heade
    r, so the process listing returns only PIDs. FreeBSD also has no sess keyword (sid is the session id).
  3. processIdentities / captureBaseline exist only for Linux and Darwin, so owned-process launches that require a baseline (the Ghidra Java probe) fail.

Expected: with a supported Ghidra release and JDK, Ghidra is available: true on FreeBSD/amd64, and owned processes are tracked and cleaned up as on Linux.

Change and scope

  • src/ghidra/GhidraInstallation.ts: map freebsd/x64 to freebsd_x86_64, expect ELF native tools, accept os.name=FreeBSD.
  • src/process/ProcessOwnershipObservation.ts, src/process/capture/ProcessSampling.ts: pass one -o per ps column (valid for both procps and BSD ps), use sid= instead of sess= on FreeBSD.
  • src/process/ProcessOwnershipObservation.ts: add a FreeBSD identity reader based on one ps -o pid= -o ppid= -o pgid= -o uid= -o stat= -o lstart= -p <pids> snapshot. It gives a freebsd-lstart: start identity, the relation (parent, process group), effective UID and lifecycle (Z means zombie, E means exiting). A PID missing from the snapshot is reported absent. FreeBSD ps exits 1 without output when none of the requested PIDs exist, and that case is also treated as all absent. Enable captureBaseline / processIdentities for FreeBSD.

Not included: setup/installer support for FreeBSD, other providers (JADX, NativeAOT and PSP remain Linux-only), arm64 FreeBSD. Accepting newer Ghidra 12.x minors is a separate PR.

Known limitation: lstart has one-second resolution, so the start identity cannot tell apart two processes that get the same PID within the same second. On FreeBSD that needs the PID space to wrap within one second, which is unlikely, but it is weaker than Linux's clock-tick start time. A sysctl kern.proc.pid reader (microsecond ki_start) would be stronger but needs native code.

Follow the contribution scope. Scope decision pending: this adds a new host platform.

Contract and boundary impact

  • Semantic owner and earliest changed stage: createSystemProcessOwnershipHost (process listing and identities) and Ghidra installation inspection. Linux and Darwin paths unchanged apart from the ps argument form.
  • Contribution scope fit and linked maintainer decision: pending (new host platform).
  • CLI and MCP/tool-catalog contract: none.
  • Provider, bridge, target-format, or platform compatibility: adds FreeBSD/amd64 host support for the Ghidra provider.
  • Evidence, artifact, provenance, or reconstruction contract: none.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): process identity and cleanup revalidation on FreeBSD now use ps snapshots, see the limitation above.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact: none.

Expected effects (check known effects; use documentation-only on its own).
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated: none yet. The FreeBSD identity reader has no unit test; that is a gap to close before review.
  • Base reproduction or other evidence: the rea doctor output above, on unpatched main.
  • User-visible CLI/MCP output: after the change, rea doctor reports Ghidra as available: true with native_decompiler,true,null,".../build/os/freebsd_x86_64/decompile reports elf x86_64, which matches freebsd/x64", and rea decompile <elf> square --provider ghidra returns int square(int param_1) { return param_1 * param_1; }. Afterwards no Ghidra or decompiler processes are left running.
  • Remaining proof gaps: no FreeBSD CI; unit tests for the FreeBSD reader; Ghidra 12.1.x on FreeBSD not tested (the host has Ghidra 12.2, see below).

Validation performed

Host: FreeBSD 16.0-CURRENT amd64, Node v24.21.0 (below engines, dependencies installed with --engine-strict=false), OpenJDK 25.0.4, Ghidra 12.2 (FreeBSD package).

  • node scripts/run-typescript.mjs --noEmit on this branch: passed.
  • npx vitest run src/ghidra/GhidraInstallation.test.ts on this branch: 104 passed, 6 failed. The same 6 (keeps JDK registration identity for ...) fail on unpatched main on this host.
  • vitest on 71 files covering process ownership, process capture and Ghidra installation, run on this branch plus the Ghidra 12.x PR: 44 failed / 795 passed / 45 skipped, against 90 failed / 749 passed on unpatched main on the same FreeBSD host. No test fails only with the change. These failures come from the FreeBSD host and are unrelated to this change.
  • Real Ghidra: rea doctor and rea decompile as above. These need Ghidra 12.2 accepted, so they ran with the Ghidra 12.x PR applied.

Compatibility, safety, and release

  • Breaking changes or migration steps: none.
  • Real Hopper/Ghidra, browser, or OS coverage: Ghidra 12.2 on FreeBSD 16.0-CURRENT amd64; Linux and macOS not re-run here.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: process identity on FreeBSD depends on ps output, with a one-second start-time resolution (see limitation).

Author readiness

Human owner: @ocochard

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/7174 **Author:** [@ocochard](https://github.com/ocochard) **Created:** 10/25/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `freebsd` --- ### 📝 Commits (2) - [`4cbbed0`](https://github.com/morluto/rea/commit/4cbbed0667a3095ca7c0860618bea57c364b3e3a) feat(ghidra): accept FreeBSD hosts and their native decompiler - [`74d78d6`](https://github.com/morluto/rea/commit/74d78d6f72cbe54890a3f3cd95c4fc2759587f40) feat(process): support FreeBSD process listing and identities ### 📊 Changes **3 files changed** (+131 additions, -5 deletions) <details> <summary>View changed files</summary> 📝 `src/ghidra/GhidraInstallation.ts` (+3 -0) 📝 `src/process/ProcessOwnershipObservation.ts` (+113 -4) 📝 `src/process/capture/ProcessSampling.ts` (+15 -1) </details> ### 📄 Description <!-- PR title: type(optional-scope): imperative outcome The title becomes the squash-merge commit subject and generated changelog entry. --> ## Summary Let the Ghidra provider run on FreeBSD/amd64 hosts. Today `rea doctor` reports Ghidra as unavailable on FreeBSD even with a working Ghidra installation, because REA rejects the platform, cannot find the FreeBSD native decomp iler, and cannot track the processes it launches (the Java probe fails), since process identities are read only from Linux procfs or the Darwin reader. ## Problem and expected behavior On FreeBSD 16.0-CURRENT amd64 with the `ghidra` package (`GHIDRA_INSTALL_DIR=/usr/local/share/ghidra`), `rea doc tor` reports for Ghidra: ``` platform,false,unsupported_host,freebsd architecture,false,unsupported_host,x64 native_decompiler,false,executable_missing,Matching native decompiler for freebsd/x64 was not found java,false,runtime_unavailable,"java: Process ownership baseline is unavailable on this host" ``` Underlying causes: 1. `NATIVE_PLATFORMS` / `NATIVE_TOOL_FORMATS` have no `freebsd` entry, and the JVM `os.name` check has no FreeBS D case. The FreeBSD package ships the decompiler at `Ghidra/Features/Decompiler/build/os/freebsd_x86_64/decompil e`, a path REA already searches once the platform is mapped. 2. `ps -axo pid=,ppid=,...` is procps syntax. BSD `ps` treats everything after the first `=` as the column heade r, so the process listing returns only PIDs. FreeBSD also has no `sess` keyword (`sid` is the session id). 3. `processIdentities` / `captureBaseline` exist only for Linux and Darwin, so owned-process launches that require a baseline (the Ghidra Java probe) fail. Expected: with a supported Ghidra release and JDK, Ghidra is `available: true` on FreeBSD/amd64, and owned processes are tracked and cleaned up as on Linux. ## Change and scope - `src/ghidra/GhidraInstallation.ts`: map `freebsd/x64` to `freebsd_x86_64`, expect ELF native tools, accept `os.name=FreeBSD`. - `src/process/ProcessOwnershipObservation.ts`, `src/process/capture/ProcessSampling.ts`: pass one `-o` per `ps` column (valid for both procps and BSD `ps`), use `sid=` instead of `sess=` on FreeBSD. - `src/process/ProcessOwnershipObservation.ts`: add a FreeBSD identity reader based on one `ps -o pid= -o ppid= -o pgid= -o uid= -o stat= -o lstart= -p <pids>` snapshot. It gives a `freebsd-lstart:` start identity, the relation (parent, process group), effective UID and lifecycle (`Z` means zombie, `E` means exiting). A PID missing from the snapshot is reported `absent`. FreeBSD `ps` exits 1 without output when none of the requested PIDs exist, and that case is also treated as all absent. Enable `captureBaseline` / `processIdentities` for FreeBSD. Not included: setup/installer support for FreeBSD, other providers (JADX, NativeAOT and PSP remain Linux-only), arm64 FreeBSD. Accepting newer Ghidra 12.x minors is a separate PR. Known limitation: `lstart` has one-second resolution, so the start identity cannot tell apart two processes that get the same PID within the same second. On FreeBSD that needs the PID space to wrap within one second, which is unlikely, but it is weaker than Linux's clock-tick start time. A `sysctl kern.proc.pid` reader (microsecond `ki_start`) would be stronger but needs native code. Follow the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope). Scope decision pending: this adds a new host platform. ## Contract and boundary impact - Semantic owner and earliest changed stage: `createSystemProcessOwnershipHost` (process listing and identities) and Ghidra installation inspection. Linux and Darwin paths unchanged apart from the `ps` argument form. - Contribution scope fit and linked maintainer decision: pending (new host platform). - CLI and MCP/tool-catalog contract: none. - Provider, bridge, target-format, or platform compatibility: adds FreeBSD/amd64 host support for the Ghidra provider. - Evidence, artifact, provenance, or reconstruction contract: none. - Target selection, authority, upstream behavior, and cleanup details (if applicable): process identity and cleanup revalidation on FreeBSD now use `ps` snapshots, see the limitation above. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: none. Expected effects (check known effects; use documentation-only on its own). Unchecked items do not establish absence; leave uncertainties visible. - [ ] Read existing files or captured data. - [X] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: none yet. The FreeBSD identity reader has no unit test; that is a gap to close before review. - Base reproduction or other evidence: the `rea doctor` output above, on unpatched `main`. - User-visible CLI/MCP output: after the change, `rea doctor` reports Ghidra as `available: true` with `native_decompiler,true,null,".../build/os/freebsd_x86_64/decompile reports elf x86_64, which matches freebsd/x64"`, and `rea decompile <elf> square --provider ghidra` returns `int square(int param_1) { return param_1 * param_1; }`. Afterwards no Ghidra or decompiler processes are left running. - Remaining proof gaps: no FreeBSD CI; unit tests for the FreeBSD reader; Ghidra 12.1.x on FreeBSD not tested (the host has Ghidra 12.2, see below). ## Validation performed Host: FreeBSD 16.0-CURRENT amd64, Node v24.21.0 (below `engines`, dependencies installed with `--engine-strict=false`), OpenJDK 25.0.4, Ghidra 12.2 (FreeBSD package). - `node scripts/run-typescript.mjs --noEmit` on this branch: passed. - `npx vitest run src/ghidra/GhidraInstallation.test.ts` on this branch: 104 passed, 6 failed. The same 6 (`keeps JDK registration identity for ...`) fail on unpatched `main` on this host. - `vitest` on 71 files covering process ownership, process capture and Ghidra installation, run on this branch plus the Ghidra 12.x PR: 44 failed / 795 passed / 45 skipped, against 90 failed / 749 passed on unpatched `main` on the same FreeBSD host. No test fails only with the change. These failures come from the FreeBSD host and are unrelated to this change. - Real Ghidra: `rea doctor` and `rea decompile` as above. These need Ghidra 12.2 accepted, so they ran with the Ghidra 12.x PR applied. ## Compatibility, safety, and release - Breaking changes or migration steps: none. - Real Hopper/Ghidra, browser, or OS coverage: Ghidra 12.2 on FreeBSD 16.0-CURRENT amd64; Linux and macOS not re-run here. - Package or release metadata impact: none. - Security, privacy, process, or containment review: process identity on FreeBSD depends on `ps` output, with a one-second start-time resolution (see limitation). ## Author readiness Human owner: @ocochard - [ ] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [ ] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [ ] I declare this PR ready for initial maintainer review. ## Before merge <!-- Draft PRs may leave pending items unchecked. Resolve material scope and authority questions before integration. --> - [ ] This PR addresses a concrete problem or an agreed enhancement. - [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [ ] The PR has one focused outcome and the title follows `type(scope): outcome`. - [ ] Related issue is linked, or the reason for not linking one is stated above. - [ ] Tests cover changed observable behavior and meaningful failure paths. - [ ] Owning docs, contracts, and generated metadata are updated where needed. - [ ] User-visible CLI/MCP changes include representative output. - [ ] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
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#7696
No description provided.