You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,6 +9,9 @@
9
9
* Shared WASM compilation module `tests/build_utils.py` to enforce `--allow-undefined` linker flags globally across all plugin builds.
10
10
* Automated target binary copying and caching for Linux production builds.
11
11
* Custom structured issue templates (Bug Report, Feature Request, Plugin Submission) and a Pull Request template in `.github/`.
12
+
* Platform-agnostic OS detection FFI `host_get_platform` returning compile-time host platform evaluation (0 for Windows, 1 for Linux) to eliminate brittle environment variable parsing.
13
+
* Linux shell executor backend (`sh.rs`) executing `/bin/sh -c` queries for the `pTerm` plugin.
14
+
* Shell blacklisting security reinforcement: added `dash` shell to the banned executable list in the sandbox to block unauthorized access by untrusted plugins.
12
15
13
16
### Fixed
14
17
* Linux CI cross-compilation failure (`x86_64-pc-windows-gnu` target) — removed orphaned `.cargo/config.toml` that forced incorrect target resolution on Linux runners.
@@ -21,6 +24,10 @@
21
24
* Linux production linker `undefined reference to 'g_headless_mode'` — guarded `extern "C"` declaration in `main_l.cpp` under `#ifdef PLUG_ENABLE_HEADLESS_MODE`; production builds now use `static constexpr bool g_headless_mode = false` with zero runtime cost.
* Process hang on `/e` exit in headless mode — `g_cmd_thread` was blocking indefinitely on `g_cmd_cv.wait()`; `main_l_cleanup()` now sets `g_cmd_thread_running = false`, notifies the CV, and joins the thread before returning so the process exits cleanly within the test timeout window.
27
+
* Headless CI broken pipe (`test_cli_lifecycle`) — moved `g_cmd_thread` and `g_headless_stdin_thread` startup from `on_tick()` frame-clock callback to `on_activate()` so stdin reader is live before any test data arrives; frame-clock callbacks are not guaranteed to fire before GApplication idle-hold expires under `xvfb-run`.
28
+
* Linux `test_sandbox_rules` 120s timeout — plugin directory was hardcoded to `C:\.plug\plugins` (Windows-only); corrected to `$HOME/.plug/plugins` matching `proc.rs``c_init()` runtime logic.
29
+
* FFI Windows-centric symbol leakage — renamed `main_w_add_tab` to platform-neutral `host_add_tab` across `plugin_mgr.rs`, pTerm manifests, source plugin files, and test mocks (`ok_plugin.rs`, `rogue_plugin.rs`, `rogue_plugin_runtime.rs`) to prevent load-time link failures.
30
+
*`pTerm` Linux shell execution compatibility — resolved execution errors on Linux hosts by adding `/sh` routing to the command parser, introducing the Linux shell backend, defaulting shell mode dynamically on Unix targets, and mapping E2E test assertions to platform-specific outputs.
Copy file name to clipboardExpand all lines: docs/ARCHITECTURE.md
+2-34Lines changed: 2 additions & 34 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,9 +18,9 @@ The framework splits operations into two layers connected via C FFI:
18
18
19
19
### C++ Functions (Called by Rust / Plugins)
20
20
-`main_*_print_info(str)` / `main_*_print_error(str)`: Output logs to active text buffers.
21
-
-`main_*_add_tab(name)`: Spawns a new tab context.
21
+
-`main_*_add_tab(name)`: Spawns a new tab context. Note that the WASM FFI layer exposes a platform-neutral import named `host_add_tab` which the host runtime routes to these platform-specific functions.
22
22
-`main_*_set_prompt_visibility(visible)`: Controls standard input prompt fields.
-`main_*_get_tab_owner(idx, buf, max_len)` / `main_*_set_tab_owner(idx, name)`: Syncs tab ownership state. The `get` function writes the owner string into `buf` up to `max_len` to ensure buffer safety and avoid ABI crashes.
24
24
25
25
---
26
26
@@ -29,35 +29,3 @@ The framework splits operations into two layers connected via C FFI:
29
29
Inputs starting with `/` invoke built-in commands (e.g., `/tab` or `/plug`). Other inputs are dispatched to the WASM plugin owning the active tab.
30
30
31
31
If a plugin requests access to sensitive FFI imports (such as `host_exec` to run local shell subprocesses), the runtime validates its manifest permissions list (`plugin.toml`) before delegating the call to the host OS.
32
-
33
-
---
34
-
35
-
## Security Model & Sandbox Limits
36
-
37
-
### 1. The FFI Gate Architecture
38
-
The WebAssembly sandbox isolates memory space and prevents direct OS API execution. System capabilities are exposed exclusively through imported FFI functions. The core runtime acts as a **binary gate**:
39
-
- When a plugin attempts an operation (e.g., `host_exec`), the host runtime checks if the permission is listed in the plugin's manifest.
40
-
-**Escape Vector by Design**: If a plugin is granted `host_exec` permission, the WASM boundary is crossed. A plugin with `host_exec` can potentially launch processes and interact with the host OS, making it a critical capability.
41
-
42
-
### 2. Execution Containment for Untrusted Plugins
43
-
For third-party or untrusted plugins that require `host_exec` to run specific external tasks, the host runtime applies strict validation checks:
44
-
-**Interpreter / LOLBin Ban**: Common shell binaries (`cmd.exe`, `powershell.exe`, `bash`, `python`) and code-execution LOLBins (`rundll32.exe`, `regsvr32.exe`) are explicitly banned.
45
-
-**Canonical-Path Allowlist**: The target binary's canonical path must be explicitly mapped in the plugin manifest's `allowed_commands`.
46
-
-**Regex Argument Filtering**: The command line arguments are evaluated against a linear-time regex pattern declared in the manifest.
47
-
48
-
### 3. Trust Tiers & Shell Emulator Bypass
49
-
Core system utilities (like the shell terminal emulator `pTerm`) require execution of host shells to operate:
50
-
-**Compile-Time Hash Pinning**: During compilation, the builder script computes the SHA-256 hash of the compiled `pTerm.wasm` binary and embeds it directly into the host Rust library (`plugin_mgr.rs` via `pterm_hash.txt`).
51
-
-**Trust Bypass**: If a plugin's SHA-256 matches this hardcoded trust list (`TRUSTED_PLUGIN_HASHES`), it is marked as `is_trusted`. Trusted plugins bypass the interpreter bans and allowlist validations inside `host_exec`.
52
-
-**Tamper Protection**: If a trusted plugin is modified, its hash changes. It falls back to the standard flow, requiring an `.integrity` file, and is blocked if tampered.
53
-
54
-
### 4. Cryptographic Integrity Validation
55
-
-**Single-Read Verification**: To mitigate TOCTOU (Time-of-Check to Time-of-Use) filesystem attacks, plugin binaries are read into memory in a single syscall. The runtime computes the SHA-256 hash of this memory buffer and verifies it against the sidecar before Wasmer compiles it.
56
-
-**Atomic Sidecar Writes**: Plugin installations write both the WASM binary and `.integrity` file to temporary files, followed by an atomic rename to prevent corrupted states.
57
-
-**Registry Hash Pinning**: Remote plugin downloads are validated against SHA-256 hashes pinned in the official registry (`pluglists.json`) to prevent MITM attacks.
58
-
-**Global Migration**: Pre-existing plugins are backfilled with `.integrity` files on startup, and a global marker is written. Post-migration, any loaded plugin lacking a valid `.integrity` sidecar is blocked.
- The unsoundness vulnerability in `memmap2` (`RUSTSEC-2026-0186` for versions `< 0.9.11`) is currently ignored in [.cargo/audit.toml](file:///O:/prj/p01/.wip/plug/plug.app/rt/.cargo/audit.toml) because our current Wasmer version does not invoke the unsound functions (`advise_range` or `flush_range`).
63
-
-**Upgrade Checklist**: Every time `wasmer` is upgraded, the developers must audit if the new Wasmer version invokes these `memmap2` range advising/flushing routines. If it does, `memmap2` must be upgraded to a safe patched version (e.g. `>= 0.9.11`) or Wasmer must be configured to bypass those calls to maintain full system safety.
-`ok_plugin integrity mismatch check` (tampered WASM with stale `.integrity` sidecar is blocked).
96
96
-`Global migration and post-migration bypass checks` (**Plan Cases A & B**: one-time global migration backfill validation and post-migration missing sidecar blocking).
97
-
-`Trusted plugin bypass integrity file check` (**Plan Case C**: verifies `pTerm` with valid compiled hash loads successfully without sidecar and executes a real `dir` command via `host_exec`).
98
-
-`Tampered trusted plugin block check` (**Plan Case D**: verifies tampered `pTerm` is blocked and fails-closed).
97
+
-`Trusted plugin bypass integrity file check`
98
+
-`Tampered trusted plugin block check`
99
99
100
100
### 3.5 End-to-End Tests (`tests/e2e/`)
101
101
-**`test_cli_lifecycle.py`**: Spawns the production compiled `plug` executable under test scenarios using `subprocess.Popen` with `HIDE_CONSOLE=ON` (the standard production build configuration to ensure we test the identical binary shipped).
-**Trust Tier**: Recognized as a trusted core utility by matching the compile-time hardcoded SHA-256 hash list. Bypasses the sandbox interpreter bans (shells block) and canonical-path allowlist checks.
12
12
13
13
---
@@ -27,9 +27,9 @@ The diagram below illustrates the exact control flow when a user runs a shell co
0 commit comments