From 8c693cd5e31b87bf45bcf15d4b41678f70244a49 Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 08:08:22 -0400 Subject: [PATCH 01/21] docs(plugins): record approved native broker integration direction --- .../complete-plugin-hook-runtime/design.md | 7 + .../native-host-integration.md | 127 ++++++++++++++++++ .../complete-plugin-hook-runtime/tasks.md | 6 + 3 files changed, 140 insertions(+) create mode 100644 openspec/changes/complete-plugin-hook-runtime/native-host-integration.md diff --git a/openspec/changes/complete-plugin-hook-runtime/design.md b/openspec/changes/complete-plugin-hook-runtime/design.md index 298d5da66..403732753 100644 --- a/openspec/changes/complete-plugin-hook-runtime/design.md +++ b/openspec/changes/complete-plugin-hook-runtime/design.md @@ -40,6 +40,13 @@ Inventory every declared P1 event and its existing producer before adding code. ## Delivery and verification +On 2026-10-30 the user approved continuing the Linux descriptor-pinned broker +direction with runtime capability checks for its exact-thread pidfd dependency. +The [native-host integration handoff](native-host-integration.md) records this +decision, ownership sequence and remaining IPC/network compatibility obligations. +This approves the strategy rather than production activation or reduced private +IPC support. Required complete native proof and production acceptance remain. + Deliver separate reviewable increments: confinement proof and enforcement; generation registry/runtime hooks; providers/transforms; scoped prompt callbacks; missing event producers. Each increment includes regression tests, docs and scoped tests/Clippy. Use real processes and OS denial/positive controls, a real server plus scripted provider, cancellation/restart tests, and SDK protocol tests. Run complete relevant native checks before acceptance. A code/security review must examine process escape paths, callback deadlocks/recursion, secret handling, late generations and unknown effects. Do not archive the broader extensibility change merely because this slice is complete. ### File observation Session scopes diff --git a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md new file mode 100644 index 000000000..f7721f82d --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md @@ -0,0 +1,127 @@ +# Native host integration and Linux support decision + +Status: broker direction approved by the user on 2026-10-30. This is the +implementation handoff after the #76 foundations milestone, not production +activation or completed native support acceptance. +The full plugins/hooks, daily-coding and binary-editor scope remains unchanged. + +## Approved implementation direction + +Continue the descriptor-pinned Linux broker toward production integration rather +than making Landlock ABI 9 the only supported Linux mechanism. Require actual +kernel/LSM capability checks, including exact-thread pidfds and descriptor +duplication; report actionable startup refusal when a required operation is +unavailable. Never substitute a process-leader descriptor table for a requesting +thread, retry without confinement, or report refusal as supported execution. + +`PIDFD_THREAD` was introduced in Linux 6.9, according to the +[pidfd_open manual](https://man7.org/linux/man-pages/man2/pidfd_open.2.html). +This is a requirement of this broker strategy, not a claim that every kernel +with that version supports its complete configuration. Backports, LSM policy, +namespace availability and syscall restrictions require feature checks and +positive native startup evidence. The current hosted results cover kernel +7.0.0-1017-azure on x64 and arm64; they do not establish a minimum-kernel matrix. + +The alternative is ABI-9 pathname UNIX mediation, documented by the +[kernel Landlock API](https://docs.kernel.org/userspace-api/landlock.html). +Current retained hosted fixtures report ABI 8 and explicitly refuse that +candidate. Selecting ABI 9 as the sole production path now would leave Linux +positive acceptance unproved. It remains an alternative pending real evidence. + +This decision approves the implementation direction and its support dependency; +it does not accept the current experiment's compatibility restrictions. In +particular, denying all IP bind/listen or silently limiting private UNIX IPC to +stream socketpairs is not the final capability contract. Private scratch IPC, +existing proxy access and all approved runtimes need positive coverage before +activation. If safe pathname/datagram/seqpacket mediation cannot be implemented +under the approved boundary, return that concrete result for review instead of +quietly reducing supported behavior. + +The governing [design](design.md) requires: "If the prototype cannot enforce the +proposed contract on a required platform/runtime, return the evidence and revised +support decision for review before proceeding". No production native activation +or protocol-feature integration crosses that gate before this decision and the +complete required proof have been reviewed. The user selected "Continue the +broker direction" on 2026-10-30 after reviewing this proposal. That closes the +direction decision; the required implementation and acceptance gates remain. + +## Production ownership sequence + +1. The host registry owns a nonrenewable generation for the exact plugin digest, + Location and effective trust/configuration incarnation. Revoke before replacing + or removing that incarnation; fence stale preparation and callback results. +2. Select a reviewed runtime/helper binding independently of project-controlled + PATH/configuration. Bind executable bytes, dependencies and all macOS signing + slices. Preserve executable signatures when copying; a target with the helper's + signing identity is refused before startup. Validate the actual admitted image, + not an earlier source path that may have changed. +3. Prepare the approved package in the protected owner namespace through the + trusted no-descendant copy worker. Inventory private roots and aliases without + opening private regular files in the owner, preserving SQLite-lock behavior. + Bind roots and protected ancestor identities and reject unsafe links/replacement. + Staging, scratch, profiles and runtime resources remain outside untrusted writer + authority for their whole lifetime, including through another admitted plugin. +4. Compose independent read/write/shell grants and the effective network/secret + intersection. Bootstrap reads do not grant Location/home access. Scratch access + does not expose another host's scratch, private owner state or proxy authority. +5. Create the narrowed proxy and immutable policy resources. Perform the final + generation/provenance check and synchronous actual spawn under the commit gate. + A returned future or copied path cannot serve as that commit. +6. Retain the admitted package, runtime/helper, policy, scratch and proxy in the + started-host owner until native tree settlement and proxy disposal acknowledge. + Revoke network authority promptly on cancellation. Unknown wait state retains + resources and quarantines restart; a fresh generation cannot reuse uncertainty + as evidence of successful cleanup. Never signal an uncertain cached PID. + +The library foundations in #76 implement pieces of this sequence. The production +App's legacy launch path does not implement this sequence today. + +## Linux mediation obligations + +- Keep private user/mount/PID/network/IPC namespaces, protected mount ancestry, + dropped capabilities, descriptor sanitation and inherited filesystem policy. + A private network namespace alone cannot hide pathname UNIX endpoints exposed + through readable mounts, as the retained host-socket counterexample demonstrates. +- Use one seccomp notification listener with a separate consumed startup-exec + budget for the exact trusted guest. Subsequent execution with shell disabled + stays denied; shell-enabled descendants retain the complete boundary. +- Pin the requesting thread's actual socket and copy bounded address arguments + before deciding policy. Emulate admitted operations on owned objects instead + of continuing an inspected mutable socket syscall. This follows the + [kernel notification guidance](https://docs.kernel.org/userspace-api/seccomp_filter.html). +- Extend IPC compatibility without admitting ambient endpoints. Pathname checks + must bind the actual endpoint and protected directory provenance, withstand + concurrent replacement/symlinks and cover destination-bearing send operations. + A string-prefix or realpath-then-connect check is insufficient. The current + broker does not yet implement these obligations for general private UNIX IPC. +- Preserve effective proxy/network ceilings. Network-denied hosts cannot reach + ambient host services; host allowlists cannot be bypassed through direct IP, + UDP, alternate socket families or an unrelated UNIX endpoint. A proxy endpoint + grant must bind the exact owned endpoint without exposing neighboring sockets. +- Bound workers, retained descriptors, memory, notifications and cancellation. + Unknown effects are not replayed. Reaping must keep process identity ownership + through settlement, including escaped descendants and parent/runtime shutdown. + +## Implementation and acceptance tasks + +- [x] N1 Review the Linux broker/support direction above; record the decision. +- [ ] N2 Complete required native IPC/network compatibility and adversarial proof, + including private UNIX behavior and proxy endpoint identity. Retain positive + runtime controls and denied ambient access, not only refusal cases. +- [ ] N3 Implement registry-owned generation admission and immutable resource + binding with actual production startup, revocation and quarantine tests. +- [ ] N4 Integrate the native launch owner and independently intersect all + filesystem/shell/network/secret capabilities. Remove the legacy plugin launch + route when accepted native support replaces it; preserve ordinary tool policy. +- [ ] N5 Verify native, Node, Python, Bun and Deno on supported macOS/Linux x64 + and arm64 configurations. Record exact unsupported Windows results and + actionable diagnostics; no universal-refusal acceptance. +- [ ] N6 Run real App/server tool-execution acceptance, malicious direct native + API/constructor/descendant cases, aliases and concurrent replacement, startup + cancellation, crash/restart, trust loss and resource settlement. Include precise + missing-enforcement controls and relevant full CI plus code/security review. +- [ ] N7 Reconcile the support matrix, original parent tasks and public docs, + then continue protocol operations, scoped callbacks and remaining producers. + +No implementation or acceptance item is completed by this proposal. Tasks 2.1–2.4 +and the remaining full-goal work remain open. diff --git a/openspec/changes/complete-plugin-hook-runtime/tasks.md b/openspec/changes/complete-plugin-hook-runtime/tasks.md index 826a7af7d..b31d113fa 100644 --- a/openspec/changes/complete-plugin-hook-runtime/tasks.md +++ b/openspec/changes/complete-plugin-hook-runtime/tasks.md @@ -14,6 +14,12 @@ The full goal scope, order and acceptance gates remain unchanged. See ## 2. Native capability enforcement +The user approved the [Linux broker integration direction](native-host-integration.md) +on 2026-10-30, including capability detection of the exact-thread pidfd dependency +and retaining private IPC/network compatibility as an activation requirement. +Only that direction decision is complete; the parent proof, implementation and +acceptance tasks below remain open. + - [ ] 2.1 Prove a native enforcement mechanism and document runtime bootstrap, read roots, writes without implied broad reads, threads, exec/fork/descendant behavior and OS/runtime support. Present any required design revision before integration. Native CI at `59cae487` passed ten jobs (90 cases) covering Node/Python on macOS/Linux arm64/x86_64 and native Linux executables, including pre-main reads/forks and immutable one-shot exec filtering. Evidence and remaining runtime/platform/integration gates: [native-proof.md](native-proof.md); parent task stays open pending the complete support decisions and acceptance evidence. - [ ] 2.2 Implement plugin-specific confinement, reviewed runtime resolution and descriptor/environment isolation without weakening ordinary tools or protected roots. The content-bound helper copy foundation is documented in [image-preparation.md](image-preparation.md), with packaged macOS entry progress in [packaged-native-entry.md](packaged-native-entry.md) and Linux entry progress in [packaged-linux-entry.md](packaged-linux-entry.md); [Generation-bound final commit](launch-authority.md) adds synchronous revocation/start ordering, and [host bootstrap environment](bootstrap-environment.md) replaces implicit environment inheritance; [Runtime startup isolation](runtime-startup.md) adds package CWD/config selection and prepared workspace resources; [Private-root inventory](private-root-inventory.md) adds bounded metadata-only alias detection; [Native policy composition](native-policy-composition.md) adds the bounded Rust macOS filesystem/process builder and packaged-helper receipts; [Linux protected mount ancestry](linux-mount-protection.md) records five passing primitive cases per Linux architecture, including actual ancestor-move counterexamples and regular-file masks, before [Rust Linux composition](linux-policy-composition.md), which supplies bounded arguments/profile and actual-helper regressions passing on Linux x64/arm64 at `546641f9`; complete owner admission and production native launch integration remain open. - [ ] 2.3 Enforce `fs.read`, `fs.write`, `shell`, network and secret intersections; refuse unsupported confinement with actionable plugin diagnostics. [Linux IPC diagnostic](linux-ipc-proof.md) proves fixture-owned host socket reachability through the composed production boundary; the [isolated socket-family candidate](linux-ipc-candidate.md) passes its fixture matrix but restricts bind/listen, while the [path-scoped ABI-9 alternative](linux-unix9-candidate.md) tests preserving private IP/UNIX functionality without production activation or an approved support-floor change. The [descriptor-pinned broker experiment](linux-socket-broker-candidate.md) now attempts private IP bind/listen/connect with bounded workers and a one-use startup-exec decision. Native and runtime results plus the support/design gate remain required. None closes this task. From 865eb6129e49461fa945cf7f39506983e387b695 Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 08:14:01 -0400 Subject: [PATCH 02/21] test(plugins): verify private UNIX endpoint identity under replacement --- .github/workflows/plugin-linux-ipc.yml | 16 ++ .../linux-socket-broker-candidate.md | 6 +- .../linux-unix-endpoint-identity.md | 48 +++++ .../native-host-integration.md | 4 +- .../linux_unix_endpoint_pin.c | 169 ++++++++++++++++++ .../plugin-native-entry/unix-endpoint.mts | 83 +++++++++ 6 files changed, 323 insertions(+), 3 deletions(-) create mode 100644 openspec/changes/complete-plugin-hook-runtime/linux-unix-endpoint-identity.md create mode 100644 scripts/probes/plugin-native-entry/linux_unix_endpoint_pin.c create mode 100644 scripts/probes/plugin-native-entry/unix-endpoint.mts diff --git a/.github/workflows/plugin-linux-ipc.yml b/.github/workflows/plugin-linux-ipc.yml index abcd41e6c..7a045fcca 100644 --- a/.github/workflows/plugin-linux-ipc.yml +++ b/.github/workflows/plugin-linux-ipc.yml @@ -23,6 +23,8 @@ on: - scripts/probes/plugin-native-entry/linux_unix9_policy.h - scripts/probes/plugin-native-entry/linux_pidfd_probe.c - scripts/probes/plugin-native-entry/pidfd.mts + - scripts/probes/plugin-native-entry/linux_unix_endpoint_pin.c + - scripts/probes/plugin-native-entry/unix-endpoint.mts permissions: contents: read concurrency: @@ -69,6 +71,20 @@ jobs: set -euo pipefail cc -Wall -Wextra -Werror -pthread scripts/probes/plugin-native-entry/linux_pidfd_probe.c -o "$RUNNER_TEMP/pidfd-probe" node --experimental-strip-types scripts/probes/plugin-native-entry/pidfd.mts --probe "$RUNNER_TEMP/pidfd-probe" --report "$RUNNER_TEMP/linux-pidfd.json" + - name: Observe pinned private UNIX endpoint identity + shell: bash + run: | + set -euo pipefail + cc -Wall -Wextra -Werror scripts/probes/plugin-native-entry/linux_unix_endpoint_pin.c -o "$RUNNER_TEMP/unix-endpoint-pin" + node --experimental-strip-types scripts/probes/plugin-native-entry/unix-endpoint.mts --probe "$RUNNER_TEMP/unix-endpoint-pin" --report "$RUNNER_TEMP/linux-unix-endpoint.json" + - name: Retain UNIX endpoint identity observations + if: always() + uses: actions/upload-artifact@v4 + with: + name: linux-unix-endpoint-${{ matrix.os }} + path: ${{ runner.temp }}/linux-unix-endpoint.json + if-no-files-found: warn + retention-days: 14 - name: Retain descriptor prerequisite observations if: always() uses: actions/upload-artifact@v4 diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-socket-broker-candidate.md b/openspec/changes/complete-plugin-hook-runtime/linux-socket-broker-candidate.md index 216f16178..2197147a3 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-socket-broker-candidate.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-socket-broker-candidate.md @@ -81,7 +81,9 @@ three controls have source-bound native receipts on both architectures. The [escaped-descendant namespace fixture](linux-plugin-descendant-proof.md) has source-bound native receipts on both architectures. The [trusted-worker capacity/recovery fixture](linux-socket-broker-capacity.md) -still requires native execution. +has source-bound passing x64/arm64 receipts. The approved +[production integration direction](native-host-integration.md) keeps complete +private IPC/network compatibility and native acceptance required before activation. The kernel's [seccomp notification documentation](https://docs.kernel.org/userspace-api/seccomp_filter.html) requires copied tracee arguments to avoid policy decisions on mutable memory. @@ -97,7 +99,7 @@ shell blocks and embedded Python parse; formatting/diff checks, all 107 strict OpenSpec items and spec lint (zero errors, 25 warnings) pass. The native C SDK build emits two Seatbelt deprecation warnings. Linux candidate compilation, kernel behavior for each revision requires corresponding hosted x64/arm64 jobs. -The new trusted-worker capacity/recovery case/control still requires hosted results. The separate +The capacity/recovery document records the later hosted results. The separate thread-specific receipts below establish that earlier case and corrected report label; the first candidate receipts cannot prove those later changes. diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-unix-endpoint-identity.md b/openspec/changes/complete-plugin-hook-runtime/linux-unix-endpoint-identity.md new file mode 100644 index 000000000..87fad4682 --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/linux-unix-endpoint-identity.md @@ -0,0 +1,48 @@ +# Private UNIX endpoint identity prerequisite + +The approved [broker direction](native-host-integration.md) retains private IPC +compatibility as a requirement. The current broker experiment permits private +stream socketpairs but does not yet implement general scratch pathname IPC. +This fixture tests a necessary object-identity primitive before implementing that +mediation; it does not establish a broker policy or production confinement. + +`linux_unix_endpoint_pin.c` creates only its own mode-0700 temporary fixture +directory and sockets. For stream, datagram and seqpacket sockets it pins the +private endpoint with `openat2` using `O_PATH` and beneath/no-symlink/no-magic-link +resolution, then verifies the selected inode is a socket. It unlinks the original +name and replaces it with a symlink to a second fixture-owned endpoint outside +the scratch subdirectory. The retained descriptor must still identify the now +unlinked original inode. + +The pinned case connects through the trusted process's `/proc/self/fd/` +reference and must exchange a token and acknowledgement with the original private +server. The precise missing-pin control uses the replaced pathname instead and +must exchange them with the second endpoint. Each case checks that the unselected +server has no pending input/connection. These are real socket effects; a successful +open or inode comparison alone cannot satisfy the test. + +Additional actual resolution requests must refuse the replacement symlink, a +parent-directory escape, an absolute path outside the pinned directory and a +directory selected as an endpoint. Every case must complete, retain the original +inode identity and prove the expected two-way exchange. Refusal of every socket +cannot count as prerequisite success. + +The TypeScript driver requires all six unique cases in both the host and private +user/mount/PID/network/IPC namespace contexts. The latter has its own temporary +filesystem and procfs, drops capabilities and disables nested user namespaces. +The driver bounds process time/output and retains source/binary digests, actual +checkout, architecture and kernel alongside observations. Its self-checks reject +missing/duplicate cases, missing replacement/identity guards and a control that +does not actually reach the second fixture-owned endpoint. + +Production obligations remain: exact-thread socket pinning in the real broker, +notification identity and cancellation, scratch-directory provenance, bind and +destination-bearing send mediation, safe concurrent object replacement, private +abstract IPC, exact proxy endpoint authority, network ceilings, resource lifetime +and positive runtime compatibility. Do not expose the trusted endpoint descriptor +or procfs reference to plugin code. The primitive's result cannot stand in for +these unimplemented properties. + +Local macOS verification covers driver self-checks and workflow syntax only; +the Linux C branch and actual kernel operations require hosted x64/arm64 execution. +No native result is claimed yet. No production policy or #76 head changes. diff --git a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md index f7721f82d..cc451755c 100644 --- a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md @@ -107,7 +107,9 @@ App's legacy launch path does not implement this sequence today. - [x] N1 Review the Linux broker/support direction above; record the decision. - [ ] N2 Complete required native IPC/network compatibility and adversarial proof, including private UNIX behavior and proxy endpoint identity. Retain positive - runtime controls and denied ambient access, not only refusal cases. + runtime controls and denied ambient access, not only refusal cases. The + [endpoint identity prerequisite](linux-unix-endpoint-identity.md) tests the first + pathname-object binding step; it does not complete this task. - [ ] N3 Implement registry-owned generation admission and immutable resource binding with actual production startup, revocation and quarantine tests. - [ ] N4 Integrate the native launch owner and independently intersect all diff --git a/scripts/probes/plugin-native-entry/linux_unix_endpoint_pin.c b/scripts/probes/plugin-native-entry/linux_unix_endpoint_pin.c new file mode 100644 index 000000000..33d7169ed --- /dev/null +++ b/scripts/probes/plugin-native-entry/linux_unix_endpoint_pin.c @@ -0,0 +1,169 @@ +/* Owned-fixture endpoint identity prerequisite; not a confinement boundary. */ +#define _GNU_SOURCE +#ifdef __linux__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int endpoint(int directory, const char *name) { + struct open_how how = { .flags = O_PATH | O_CLOEXEC, + .resolve = RESOLVE_BENEATH | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS }; + int fd = (int)syscall(SYS_openat2, directory, name, &how, sizeof(how)); + if (fd < 0) return -1; + struct stat info; + if (fstat(fd, &info) != 0 || !S_ISSOCK(info.st_mode)) { + close(fd); + errno = ENOTSOCK; + return -1; + } + return fd; +} +static int address(struct sockaddr_un *value, const char *path) { + memset(value, 0, sizeof(*value)); + value->sun_family = AF_UNIX; + int size = snprintf(value->sun_path, sizeof(value->sun_path), "%s", path); + return size > 0 && (size_t)size < sizeof(value->sun_path) ? 0 : -1; +} +static int bound(int type, const char *path) { + struct sockaddr_un value; + if (address(&value, path) != 0) return -1; + int fd = socket(AF_UNIX, type | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); + if (fd < 0) return -1; + if (bind(fd, (struct sockaddr *)&value, sizeof(value)) != 0 || + (type != SOCK_DGRAM && listen(fd, 1) != 0)) { + int error = errno; + close(fd); + errno = error; + return -1; + } + return fd; +} +static int ready(int fd) { + struct pollfd value = { .fd = fd, .events = POLLIN }; + int result; + do { result = poll(&value, 1, 1000); } while (result < 0 && errno == EINTR); + return result == 1 && (value.revents & POLLIN) != 0; +} +static int exchange(int client, int listener, int type) { + int peer = listener; + if (type != SOCK_DGRAM) { + peer = accept4(listener, NULL, NULL, SOCK_CLOEXEC | SOCK_NONBLOCK); + if (peer < 0) return 0; + } + const char token = 'T', ack = 'A'; + char received = 0; + struct sockaddr_un sender; + socklen_t length = sizeof(sender); + int passed = send(client, &token, 1, MSG_NOSIGNAL) == 1 && ready(peer) && + recvfrom(peer, &received, 1, 0, (struct sockaddr *)&sender, &length) == 1 && + received == token; + if (passed) { + ssize_t sent = type == SOCK_DGRAM + ? sendto(peer, &ack, 1, MSG_NOSIGNAL, (struct sockaddr *)&sender, length) + : send(peer, &ack, 1, MSG_NOSIGNAL); + passed = sent == 1 && ready(client) && recv(client, &received, 1, 0) == 1 && + received == ack; + } + if (peer != listener) close(peer); + return passed; +} +static int refused(int directory, const char *path, int expected) { + int fd = endpoint(directory, path); + int error = errno; + if (fd >= 0) close(fd); + return fd < 0 && error == expected; +} +static int observe(int type, const char *label, int pinned) { + char root[] = "/tmp/cyber-unix-pin-XXXXXX"; + if (mkdtemp(root) == NULL) return 0; + char scratch[108], selected[108], ambient[108], client_path[108]; + snprintf(scratch, sizeof(scratch), "%s/scratch", root); + snprintf(selected, sizeof(selected), "%s/scratch/endpoint", root); + snprintf(ambient, sizeof(ambient), "%s/ambient", root); + snprintf(client_path, sizeof(client_path), "%s/scratch/client", root); + int directory = -1, private = -1, outside = -1, client = -1, pin = -1; + int replaced = 0, linked_refused = 0, escape_refused = 0, absolute_refused = 0; + int kind_refused = 0, identity_retained = 0, private_received = 0, ambient_received = 0; + int roundtrip = 0, error = 0; + const char *stage = "setup"; + if (mkdir(scratch, 0700) != 0) goto done; + directory = open(scratch, O_PATH | O_DIRECTORY | O_CLOEXEC); + private = bound(type, selected); + outside = bound(type, ambient); + if (directory < 0 || private < 0 || outside < 0) goto done; + pin = endpoint(directory, "endpoint"); + struct stat before, after; + if (pin < 0 || fstat(pin, &before) != 0) goto done; + kind_refused = refused(directory, ".", ENOTSOCK); + escape_refused = refused(directory, "../ambient", EXDEV); + absolute_refused = refused(directory, ambient, EXDEV); + stage = "replace"; + if (unlink(selected) != 0 || symlink("../ambient", selected) != 0) goto done; + replaced = 1; + linked_refused = refused(directory, "endpoint", ELOOP); + identity_retained = fstat(pin, &after) == 0 && before.st_dev == after.st_dev && + before.st_ino == after.st_ino && after.st_nlink == 0; + stage = "connect"; + client = socket(AF_UNIX, type | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); + struct sockaddr_un local, target; + if (client < 0 || address(&local, client_path) != 0 || + bind(client, (struct sockaddr *)&local, sizeof(local)) != 0) goto done; + char reference[64]; + snprintf(reference, sizeof(reference), "/proc/self/fd/%d", pin); + if (address(&target, pinned ? reference : selected) != 0 || + connect(client, (struct sockaddr *)&target, sizeof(target)) != 0) goto done; + /* The missing-pin control deliberately resolves the replaced pathname. All + endpoints are this fixture's own dummy sockets, never ambient services. */ + int chosen = pinned ? private : outside; + roundtrip = exchange(client, chosen, type); + private_received = pinned && roundtrip; + ambient_received = !pinned && roundtrip; + struct pollfd other = { .fd = pinned ? outside : private, .events = POLLIN }; + if (poll(&other, 1, 0) != 0) roundtrip = 0; + stage = "complete"; +done: + error = strcmp(stage, "complete") == 0 ? 0 : errno; + if (pin >= 0) close(pin); + if (client >= 0) close(client); + if (outside >= 0) close(outside); + if (private >= 0) close(private); + if (directory >= 0) close(directory); + unlink(client_path); unlink(selected); unlink(ambient); + rmdir(scratch); rmdir(root); + int passed = error == 0 && replaced && linked_refused && escape_refused && + absolute_refused && kind_refused && identity_retained && roundtrip && + private_received == pinned && ambient_received == !pinned; + printf("{\"type\":\"%s\",\"pinned\":%s,\"stage\":\"%s\",\"errno\":%d," + "\"replaced\":%s,\"symlink_refused\":%s,\"escape_refused\":%s," + "\"absolute_refused\":%s,\"kind_refused\":%s,\"identity_retained\":%s," + "\"private_received\":%s,\"ambient_received\":%s,\"roundtrip\":%s,\"passed\":%s}\n", + label, pinned ? "true" : "false", stage, error, + replaced ? "true" : "false", linked_refused ? "true" : "false", + escape_refused ? "true" : "false", absolute_refused ? "true" : "false", + kind_refused ? "true" : "false", identity_retained ? "true" : "false", + private_received ? "true" : "false", ambient_received ? "true" : "false", + roundtrip ? "true" : "false", passed ? "true" : "false"); + return passed; +} +int main(void) { + const int types[] = {SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET}; + const char *labels[] = {"stream", "datagram", "seqpacket"}; + int passed = 1; + for (size_t i = 0; i < sizeof(types) / sizeof(types[0]); ++i) + for (int pinned = 0; pinned <= 1; ++pinned) + passed &= observe(types[i], labels[i], pinned); + return passed ? 0 : 1; +} +#else +int main(void) { return 77; } +#endif diff --git a/scripts/probes/plugin-native-entry/unix-endpoint.mts b/scripts/probes/plugin-native-entry/unix-endpoint.mts new file mode 100644 index 000000000..185438e47 --- /dev/null +++ b/scripts/probes/plugin-native-entry/unix-endpoint.mts @@ -0,0 +1,83 @@ +/** Endpoint identity prerequisite, not a production broker or confinement test. */ +import assert from "node:assert/strict"; +import { spawnSync } from "node:child_process"; +import { createHash } from "node:crypto"; +import { readFileSync, writeFileSync } from "node:fs"; +import { release } from "node:os"; +import { parseArgs } from "node:util"; + +type Observation = { + type: "stream" | "datagram" | "seqpacket"; + pinned: boolean; stage: string; errno: number; + replaced: boolean; symlink_refused: boolean; escape_refused: boolean; + absolute_refused: boolean; kind_refused: boolean; identity_retained: boolean; + private_received: boolean; ambient_received: boolean; roundtrip: boolean; passed: boolean; +}; +function verify(rows: Observation[]): void { + const expected = new Set(["stream", "datagram", "seqpacket"].flatMap(type => + [false, true].map(pinned => `${type}:${pinned}`))); + assert.equal(rows.length, expected.size); + for (const row of rows) { + assert.equal(typeof row.pinned, "boolean"); + assert(expected.delete(`${row.type}:${row.pinned}`), "missing, duplicate or unexpected case"); + assert.equal(row.stage, "complete"); assert.equal(row.errno, 0); + for (const key of ["replaced", "symlink_refused", "escape_refused", "absolute_refused", + "kind_refused", "identity_retained", "roundtrip", "passed"] as const) { + assert.equal(row[key], true, `${row.type} ${row.pinned}: ${key}`); + } + assert.equal(row.private_received, row.pinned, "pinned identity must select the private endpoint"); + assert.equal(row.ambient_received, !row.pinned, "re-resolving must expose the fixture counterexample"); + } + assert.equal(expected.size, 0); +} +function selfTest(): void { + const rows: Observation[] = (["stream", "datagram", "seqpacket"] as const).flatMap(type => + [false, true].map(pinned => ({ type, pinned, stage: "complete", errno: 0, + replaced: true, symlink_refused: true, escape_refused: true, absolute_refused: true, + kind_refused: true, identity_retained: true, private_received: pinned, + ambient_received: !pinned, roundtrip: true, passed: true }))); + verify(rows); + assert.throws(() => verify(rows.slice(1))); + assert.throws(() => verify(rows.map(row => ({ ...row, ambient_received: false })))); + assert.throws(() => verify(rows.map(row => ({ ...row, identity_retained: false })))); + assert.throws(() => verify(rows.map(row => ({ ...row, symlink_refused: false })))); + assert.throws(() => verify([...rows.slice(1), rows[1]])); +} +const { values } = parseArgs({ options: { probe: { type: "string" }, report: { type: "string" }, + "self-test": { type: "boolean" } } }); +selfTest(); +if (!values["self-test"]) { + assert.equal(process.platform, "linux"); assert(values.probe && values.report); + const rows: { mode: string; status: number | null; observed: Observation[] }[] = []; + let passed = false; + try { + for (const mode of ["host", "private-namespaces"]) { + const program = mode === "host" ? values.probe : "/usr/bin/bwrap"; + const args = mode === "host" ? [] : ["--die-with-parent", "--unshare-user", "--unshare-pid", + "--unshare-net", "--unshare-ipc", "--unshare-uts", "--disable-userns", "--cap-drop", "ALL", + "--ro-bind", "/", "/", "--proc", "/proc", "--dev", "/dev", "--tmpfs", "/tmp", + "--", values.probe]; + const result = spawnSync(program, args, { encoding: "utf8", timeout: 20_000, + maxBuffer: 64 * 1024, env: { PATH: "/usr/bin:/bin" } }); + assert(!result.error, `native observation failed: ${result.error}`); + const observed = result.stdout.trim().split("\n").filter(Boolean) + .map(line => JSON.parse(line) as Observation); + rows.push({ mode, status: result.status, observed }); + assert.equal(result.status, 0, result.stderr || result.stdout); + verify(observed); + } + passed = true; + } finally { + const sources = ["scripts/probes/plugin-native-entry/linux_unix_endpoint_pin.c", + "scripts/probes/plugin-native-entry/unix-endpoint.mts", ".github/workflows/plugin-linux-ipc.yml"]; + const hash = createHash("sha256"); + for (const path of sources) hash.update(path + "\0").update(readFileSync(path)); + writeFileSync(values.report, JSON.stringify({ platform: process.platform, architecture: process.arch, + kernel_release: release(), checkout: process.env.GITHUB_SHA ?? null, run_id: process.env.GITHUB_RUN_ID ?? null, + passed, sources, source_sha256: hash.digest("hex"), + probe_sha256: createHash("sha256").update(readFileSync(values.probe)).digest("hex"), rows, + scope: "Owned-fixture O_PATH/openat2 endpoint identity and replacement counterexample only. No syscall broker integration, full IPC policy or production acceptance." }, null, 2) + "\n"); + console.log(JSON.stringify({ passed, native_policy_acceptance: false, + cases: rows.map(row => ({ mode: row.mode, count: row.observed.length })) })); + } +} From 959223bf890f0ec133644080bb44c2898818a90f Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 08:17:46 -0400 Subject: [PATCH 03/21] docs(plugins): retain private UNIX endpoint identity receipts --- .../linux-unix-endpoint-identity.md | 30 ++- .../arm64/linux-unix-endpoint.json | 222 ++++++++++++++++++ .../x64/linux-unix-endpoint.json | 222 ++++++++++++++++++ 3 files changed, 473 insertions(+), 1 deletion(-) create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-unix-endpoint-e968c44e/arm64/linux-unix-endpoint.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-unix-endpoint-e968c44e/x64/linux-unix-endpoint.json diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-unix-endpoint-identity.md b/openspec/changes/complete-plugin-hook-runtime/linux-unix-endpoint-identity.md index 87fad4682..28759584e 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-unix-endpoint-identity.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-unix-endpoint-identity.md @@ -45,4 +45,32 @@ these unimplemented properties. Local macOS verification covers driver self-checks and workflow syntax only; the Linux C branch and actual kernel operations require hosted x64/arm64 execution. -No native result is claimed yet. No production policy or #76 head changes. +No production policy or #76 head changes. + +## Native result + +The endpoint identity steps in +[run 41053828357](https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41053828357) +passed on x64 (job 124056240517) and arm64 (job 124056240704). Each original +report contains six unique cases in each of the host and private namespace +contexts: 12 cases per architecture, 24 total. All require actual token/ack +exchange, including the missing-pin controls reaching the second fixture endpoint. +Every guard and pinned inode-retention assertion passed. The rest of that broader +workflow remains separately pending; these step results do not claim its completion. + +Reports are retained unchanged at +`scripts/probes/plugin-native-entry/evidence/linux-unix-endpoint-e968c44e/{x64,arm64}/linux-unix-endpoint.json`. +Both bind checkout `e968c44e0c0d4d54d578630350a4ed9b65f0f02e`, kernel +`7.0.0-1017-azure` and source manifest SHA-256 +`fccc9972e359ce3ecbfc5c240d8b2a6327a152b1ff40c53999773da234ca6f34`. +That manifest was independently recomputed from the exact Git tree before +retaining the reports. Binary digests remain in each original report; later +revisions do not inherit these observations automatically. + +The scoped review covers owned fixture paths, exclusive temporary creation, +bounded nonblocking socket I/O, cleanup, actual endpoint selection and reverse +acknowledgement, exact missing-pin effects, strict case uniqueness and negative +driver self-checks, private namespaces and retained source bindings. The positive +result permits trying this primitive in the real broker. It does not complete +general private IPC, notification ownership, bind/send mediation, network/proxy +intersections or production activation acceptance. diff --git a/scripts/probes/plugin-native-entry/evidence/linux-unix-endpoint-e968c44e/arm64/linux-unix-endpoint.json b/scripts/probes/plugin-native-entry/evidence/linux-unix-endpoint-e968c44e/arm64/linux-unix-endpoint.json new file mode 100644 index 000000000..cfcf01894 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-unix-endpoint-e968c44e/arm64/linux-unix-endpoint.json @@ -0,0 +1,222 @@ +{ + "platform": "linux", + "architecture": "arm64", + "kernel_release": "7.0.0-1017-azure", + "checkout": "e968c44e0c0d4d54d578630350a4ed9b65f0f02e", + "run_id": "41053828357", + "passed": true, + "sources": [ + "scripts/probes/plugin-native-entry/linux_unix_endpoint_pin.c", + "scripts/probes/plugin-native-entry/unix-endpoint.mts", + ".github/workflows/plugin-linux-ipc.yml" + ], + "source_sha256": "fccc9972e359ce3ecbfc5c240d8b2a6327a152b1ff40c53999773da234ca6f34", + "probe_sha256": "5cbca7e7512f2c1e6dd95b4919c50fc4500aa5bf2cb862af1afc1b6a86a7e3cb", + "rows": [ + { + "mode": "host", + "status": 0, + "observed": [ + { + "type": "stream", + "pinned": false, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": false, + "ambient_received": true, + "roundtrip": true, + "passed": true + }, + { + "type": "stream", + "pinned": true, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": true, + "ambient_received": false, + "roundtrip": true, + "passed": true + }, + { + "type": "datagram", + "pinned": false, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": false, + "ambient_received": true, + "roundtrip": true, + "passed": true + }, + { + "type": "datagram", + "pinned": true, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": true, + "ambient_received": false, + "roundtrip": true, + "passed": true + }, + { + "type": "seqpacket", + "pinned": false, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": false, + "ambient_received": true, + "roundtrip": true, + "passed": true + }, + { + "type": "seqpacket", + "pinned": true, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": true, + "ambient_received": false, + "roundtrip": true, + "passed": true + } + ] + }, + { + "mode": "private-namespaces", + "status": 0, + "observed": [ + { + "type": "stream", + "pinned": false, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": false, + "ambient_received": true, + "roundtrip": true, + "passed": true + }, + { + "type": "stream", + "pinned": true, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": true, + "ambient_received": false, + "roundtrip": true, + "passed": true + }, + { + "type": "datagram", + "pinned": false, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": false, + "ambient_received": true, + "roundtrip": true, + "passed": true + }, + { + "type": "datagram", + "pinned": true, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": true, + "ambient_received": false, + "roundtrip": true, + "passed": true + }, + { + "type": "seqpacket", + "pinned": false, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": false, + "ambient_received": true, + "roundtrip": true, + "passed": true + }, + { + "type": "seqpacket", + "pinned": true, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": true, + "ambient_received": false, + "roundtrip": true, + "passed": true + } + ] + } + ], + "scope": "Owned-fixture O_PATH/openat2 endpoint identity and replacement counterexample only. No syscall broker integration, full IPC policy or production acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-unix-endpoint-e968c44e/x64/linux-unix-endpoint.json b/scripts/probes/plugin-native-entry/evidence/linux-unix-endpoint-e968c44e/x64/linux-unix-endpoint.json new file mode 100644 index 000000000..dd350aec9 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-unix-endpoint-e968c44e/x64/linux-unix-endpoint.json @@ -0,0 +1,222 @@ +{ + "platform": "linux", + "architecture": "x64", + "kernel_release": "7.0.0-1017-azure", + "checkout": "e968c44e0c0d4d54d578630350a4ed9b65f0f02e", + "run_id": "41053828357", + "passed": true, + "sources": [ + "scripts/probes/plugin-native-entry/linux_unix_endpoint_pin.c", + "scripts/probes/plugin-native-entry/unix-endpoint.mts", + ".github/workflows/plugin-linux-ipc.yml" + ], + "source_sha256": "fccc9972e359ce3ecbfc5c240d8b2a6327a152b1ff40c53999773da234ca6f34", + "probe_sha256": "56f1afbe327df08381a54b6416a9b65c2617c0c67a412257dd3886d2ed477985", + "rows": [ + { + "mode": "host", + "status": 0, + "observed": [ + { + "type": "stream", + "pinned": false, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": false, + "ambient_received": true, + "roundtrip": true, + "passed": true + }, + { + "type": "stream", + "pinned": true, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": true, + "ambient_received": false, + "roundtrip": true, + "passed": true + }, + { + "type": "datagram", + "pinned": false, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": false, + "ambient_received": true, + "roundtrip": true, + "passed": true + }, + { + "type": "datagram", + "pinned": true, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": true, + "ambient_received": false, + "roundtrip": true, + "passed": true + }, + { + "type": "seqpacket", + "pinned": false, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": false, + "ambient_received": true, + "roundtrip": true, + "passed": true + }, + { + "type": "seqpacket", + "pinned": true, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": true, + "ambient_received": false, + "roundtrip": true, + "passed": true + } + ] + }, + { + "mode": "private-namespaces", + "status": 0, + "observed": [ + { + "type": "stream", + "pinned": false, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": false, + "ambient_received": true, + "roundtrip": true, + "passed": true + }, + { + "type": "stream", + "pinned": true, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": true, + "ambient_received": false, + "roundtrip": true, + "passed": true + }, + { + "type": "datagram", + "pinned": false, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": false, + "ambient_received": true, + "roundtrip": true, + "passed": true + }, + { + "type": "datagram", + "pinned": true, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": true, + "ambient_received": false, + "roundtrip": true, + "passed": true + }, + { + "type": "seqpacket", + "pinned": false, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": false, + "ambient_received": true, + "roundtrip": true, + "passed": true + }, + { + "type": "seqpacket", + "pinned": true, + "stage": "complete", + "errno": 0, + "replaced": true, + "symlink_refused": true, + "escape_refused": true, + "absolute_refused": true, + "kind_refused": true, + "identity_retained": true, + "private_received": true, + "ambient_received": false, + "roundtrip": true, + "passed": true + } + ] + } + ], + "scope": "Owned-fixture O_PATH/openat2 endpoint identity and replacement counterexample only. No syscall broker integration, full IPC policy or production acceptance." +} From 7b842177c60650311f29a205b3908bb508022fdf Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 08:18:18 -0400 Subject: [PATCH 04/21] docs(plugins): record completed Linux prerequisite workflow --- .../linux-unix-endpoint-identity.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-unix-endpoint-identity.md b/openspec/changes/complete-plugin-hook-runtime/linux-unix-endpoint-identity.md index 28759584e..191b43c75 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-unix-endpoint-identity.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-unix-endpoint-identity.md @@ -55,8 +55,9 @@ passed on x64 (job 124056240517) and arm64 (job 124056240704). Each original report contains six unique cases in each of the host and private namespace contexts: 12 cases per architecture, 24 total. All require actual token/ack exchange, including the missing-pin controls reaching the second fixture endpoint. -Every guard and pinned inode-retention assertion passed. The rest of that broader -workflow remains separately pending; these step results do not claim its completion. +Every guard and pinned inode-retention assertion passed. The broader workflow +also completed successfully on both architectures, including its existing broker +and runtime checks; that does not extend this primitive's proof beyond its cases. Reports are retained unchanged at `scripts/probes/plugin-native-entry/evidence/linux-unix-endpoint-e968c44e/{x64,arm64}/linux-unix-endpoint.json`. From cf28d62f704eb451a99f82a6420f887c179898a0 Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 08:50:26 -0400 Subject: [PATCH 05/21] feat(plugins): integrate pinned private streams in confinement candidate --- .github/workflows/plugin-linux-ipc.yml | 34 +++++- .../examples/plugin_unix_socket_probe.rs | 34 +++++- .../tests/fixtures/plugin_unix_socket.c | 38 +++++- .../linux-private-stream-integration.md | 66 +++++++++++ .../native-host-integration.md | 3 +- scripts/probes/plugin-confinement/run.mts | 6 +- .../build_socket_candidate.py | 30 ++++- .../plugin-native-entry/linux_socket_broker.h | 51 +++++++- .../linux_socket_private_stream.h | 30 +++++ .../linux_socket_private_unix.h | 112 ++++++++++++++++++ 10 files changed, 387 insertions(+), 17 deletions(-) create mode 100644 openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md create mode 100644 scripts/probes/plugin-native-entry/linux_socket_private_stream.h create mode 100644 scripts/probes/plugin-native-entry/linux_socket_private_unix.h diff --git a/.github/workflows/plugin-linux-ipc.yml b/.github/workflows/plugin-linux-ipc.yml index 7a045fcca..471f7a49a 100644 --- a/.github/workflows/plugin-linux-ipc.yml +++ b/.github/workflows/plugin-linux-ipc.yml @@ -17,6 +17,8 @@ on: - .github/workflows/plugin-linux-ipc.yml - scripts/probes/plugin-native-entry/linux_socket_candidate.h - scripts/probes/plugin-native-entry/linux_socket_broker.h + - scripts/probes/plugin-native-entry/linux_socket_private_stream.h + - scripts/probes/plugin-native-entry/linux_socket_private_unix.h - scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h - scripts/probes/plugin-native-entry/build_socket_candidate.py - scripts/probes/plugin-native-entry/linux_socket_landlock9.h @@ -105,6 +107,9 @@ jobs: python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/socket-broker-audit" broker-audit python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/socket-broker-no-cancel" broker-audit-no-cancel python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/socket-broker-wrong-cap" broker-audit-wrong-cap + for variant in broker-private-stream broker-private-stream-no-makesock broker-private-stream-no-refer; do + python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/$variant" "$variant" + done for mode in mutation mutation-no-pin mutation-no-copy mutation-continue; do python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/socket-broker-$mode" "broker-$mode" done @@ -122,6 +127,29 @@ jobs: target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/socket-broker-mutation" "$RUNNER_TEMP/linux-ipc-broker-mutation.json" --broker-mutation target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/socket-broker" "$RUNNER_TEMP/linux-ipc-broker-escape.json" --broker-escape target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/socket-broker-audit" "$RUNNER_TEMP/linux-ipc-broker-saturation.json" --broker-saturation + target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/broker-private-stream" "$RUNNER_TEMP/linux-ipc-broker-private-stream.json" --broker-private-stream + - name: Reject missing private socket creation and file-move compatibility guards + shell: bash + run: | + set -euo pipefail + for control in no-makesock no-refer; do + log="$RUNNER_TEMP/broker-private-stream-$control.log" + if target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/broker-private-stream-$control" "$RUNNER_TEMP/linux-ipc-private-stream-$control.json" --broker-private-stream > "$log" 2>&1; then + echo "Private stream control unexpectedly passed: $control" >&2 + exit 1 + fi + python3 - "$log" "$control" <<'PY' + from pathlib import Path + import sys + text = Path(sys.argv[1]).read_text() + if sys.argv[2] == 'no-makesock': + assert 'private pair escape: pair_bind: public read=false write=true' in text, text + assert '"pair_bind":true' in text, text + else: + assert 'private IPC layer changed ordinary file moves:' in text, text + assert 'write=true' in text and '"regular_reparent":false' in text, text + PY + done - name: Reject blanket bind denial as broker acceptance shell: bash run: | @@ -299,7 +327,7 @@ jobs: set -euo pipefail mkdir -p "$RUNNER_TEMP/socket-runtime" status=0 - for policy in seccomp broker unix9; do + for policy in seccomp broker private-stream unix9; do if [[ "$policy" == unix9 && '${{ steps.abi.outputs.supported }}' != true ]]; then echo 'UNVERIFIED: skipping ABI-9 runtime matrix on this unsupported kernel.' continue @@ -307,10 +335,12 @@ jobs: mkdir -p "$RUNNER_TEMP/socket-runtime/$policy" helper="$RUNNER_TEMP/socket-candidate" if [[ "$policy" == broker ]]; then helper="$RUNNER_TEMP/socket-broker"; fi + if [[ "$policy" == private-stream ]]; then helper="$RUNNER_TEMP/broker-private-stream"; fi if [[ "$policy" == unix9 ]]; then helper="$RUNNER_TEMP/unix9-candidate"; fi for runtime in node python bun deno native; do args=(--runtime "$runtime" --initial-exec --packaged-helper "$helper" --report "$RUNNER_TEMP/socket-runtime/$policy/$runtime.json" --trace "$RUNNER_TEMP/socket-runtime/$policy/trace-$runtime") if [[ "$policy" == broker ]]; then args+=(--socket-broker); fi + if [[ "$policy" == private-stream ]]; then args+=(--socket-broker --broker-private-stream); fi if [[ "$policy" == unix9 ]]; then args+=(--unix-scratch-policy); fi if [[ "$runtime" == python ]]; then args+=(--python "$(command -v python3)") @@ -335,6 +365,8 @@ jobs: ${{ runner.temp }}/unix9-missing-resolve.log ${{ runner.temp }}/unix9-unavailable.log ${{ runner.temp }}/broker-no-bind.log + ${{ runner.temp }}/broker-private-stream-no-makesock.log + ${{ runner.temp }}/broker-private-stream-no-refer.log ${{ runner.temp }}/broker-no-thread.log ${{ runner.temp }}/broker-no-cancel.log ${{ runner.temp }}/broker-mutation-*.log diff --git a/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs b/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs index 8bf69eec0..ad48e4982 100644 --- a/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs +++ b/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs @@ -72,6 +72,7 @@ mod probe { BrokerEscape, BrokerEscapeNoPid, BrokerSaturation, + BrokerPrivateStream, Unix9, } impl Mode { @@ -85,6 +86,7 @@ mod probe { | Self::BrokerEscape | Self::BrokerEscapeNoPid | Self::BrokerSaturation + | Self::BrokerPrivateStream ) } fn broker(self) -> bool { @@ -96,6 +98,7 @@ mod probe { | Self::BrokerEscape | Self::BrokerEscapeNoPid | Self::BrokerSaturation + | Self::BrokerPrivateStream ) } fn escape(self) -> Option { @@ -109,7 +112,7 @@ mod probe { fn observe(policy: &LinuxPolicy<'_>, mode: Mode) -> Value { let mut plan = policy.compose().unwrap(); - if mode == Mode::Unix9 { + if matches!(mode, Mode::Unix9 | Mode::BrokerPrivateStream) { plan.landlock .push_str(&format!("U\t{}\n", policy.scratch.display())); } @@ -153,10 +156,25 @@ mod probe { for key in ["connected", "pair_reconnect", "pair_bind"] { assert_eq!( observed[key], false, - "private pair escape: {key}: {observed}" + "private pair escape: {key}: {label} read={} write={}: {observed}", + pair_policy.fs_read, pair_policy.fs_write, ); } check_pair_support(&observed, mode); + if mode == Mode::BrokerPrivateStream { + assert_eq!( + observed["regular_reparent"], pair_policy.fs_write, + "private IPC layer changed ordinary file moves: {label} read={} write={}: {observed}", + pair_policy.fs_read, pair_policy.fs_write, + ); + if label == "public" && pair_policy.fs_write { + assert_eq!( + observed["cross_mount_alias_errno"], + libc::EXDEV, + "a host socket alias crossed the private scratch mount: {observed}" + ); + } + } let delivered = receipt(listener, &observed); assert!(!delivered, "pair reached host: {observed}"); json!({"socket": label, "fs_read": pair_policy.fs_read, "fs_write": pair_policy.fs_write, @@ -164,13 +182,18 @@ mod probe { } fn check_pair_support(observed: &Value, mode: Mode) { - for key in ["datagram_pair", "seqpacket_pair", "scratch_unix_roundtrip"] { + for key in ["datagram_pair", "seqpacket_pair"] { assert_eq!( observed[key], mode == Mode::Unix9, "pair/local support: {key}: {observed}" ); } + assert_eq!( + observed["scratch_unix_roundtrip"], + matches!(mode, Mode::Unix9 | Mode::BrokerPrivateStream), + "private scratch stream roundtrip: {observed}" + ); assert_eq!( observed["tcp_roundtrip"], mode.ip_servers(), @@ -245,6 +268,7 @@ mod probe { Some("--broker-escape") => Mode::BrokerEscape, Some("--broker-escape-no-pid") => Mode::BrokerEscapeNoPid, Some("--broker-saturation") => Mode::BrokerSaturation, + Some("--broker-private-stream") => Mode::BrokerPrivateStream, Some("--landlock9") => Mode::Unix9, _ => panic!("unknown candidate mode"), }; @@ -373,6 +397,8 @@ mod probe { "scripts/probes/plugin-native-entry/linux_socket_candidate.h", "scripts/probes/plugin-native-entry/linux_socket_broker.h", "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", "scripts/probes/plugin-native-entry/linux_unix9_policy.h", "scripts/probes/plugin-native-entry/build_socket_candidate.py", @@ -385,7 +411,7 @@ mod probe { } let report = json!({"platform": std::env::consts::OS, "architecture": std::env::consts::ARCH, "checkout": std::env::var("GITHUB_SHA").ok(), "run_id": std::env::var("GITHUB_RUN_ID").ok(), - "candidate": candidate, "landlock9": mode == Mode::Unix9, "socket_broker": mode.broker(), "cancellation_probe": mode == Mode::BrokerCancel, "mutation_probe": mode == Mode::BrokerMutation, "escape_probe": mode.escape(), "saturation_probe": mode == Mode::BrokerSaturation, "sources": sources, "source_sha256": format!("{:x}", hash.finalize()), + "candidate": candidate, "landlock9": mode == Mode::Unix9, "socket_broker": mode.broker(), "private_stream_probe": mode == Mode::BrokerPrivateStream, "cancellation_probe": mode == Mode::BrokerCancel, "mutation_probe": mode == Mode::BrokerMutation, "escape_probe": mode.escape(), "saturation_probe": mode == Mode::BrokerSaturation, "sources": sources, "source_sha256": format!("{:x}", hash.finalize()), "helper_sha256": format!("{:x}", Sha256::digest(std::fs::read(helper).unwrap())), "rows": rows, "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance."}); std::fs::write( diff --git a/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c b/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c index e646ba2f3..fabc7c329 100644 --- a/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c +++ b/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,28 @@ static int thread_local_exchange(void) { static int thread_local_exchange(void) { return 0; } #endif +static int regular_reparent(const char *data_path) { + char first[512], second[512], source[544], target[544]; + int a = snprintf(first, sizeof(first), "%s-move-a", data_path); + int b = snprintf(second, sizeof(second), "%s-move-b", data_path); + if (a <= 0 || b <= 0 || (size_t)a >= sizeof(first) || (size_t)b >= sizeof(second)) return 0; + snprintf(source, sizeof(source), "%s/entry", first); + snprintf(target, sizeof(target), "%s/entry", second); + int ok = 0, fd = -1; + struct stat before, after, old; + if (mkdir(first, 0700) != 0 || mkdir(second, 0700) != 0) goto done; + fd = open(source, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0600); + if (fd < 0 || write(fd, "T", 1) != 1 || fstat(fd, &before) != 0) goto done; + close(fd); fd = -1; + ok = rename(source, target) == 0 && lstat(target, &after) == 0 && + S_ISREG(after.st_mode) && before.st_dev == after.st_dev && before.st_ino == after.st_ino && + lstat(source, &old) < 0 && errno == ENOENT; +done: + if (fd >= 0) close(fd); + unlink(source); unlink(target); rmdir(first); rmdir(second); + return ok; +} + static int pair_probe(const struct sockaddr_un *address, socklen_t length, const char *data_path, const char *scratch_socket) { int pair[2]; @@ -134,18 +157,29 @@ static int pair_probe(const struct sockaddr_un *address, socklen_t length, int tcp = scratch_socket != NULL && local_exchange(AF_INET, NULL, -1); int thread_tcp = scratch_socket != NULL && thread_local_exchange(); int scratch_ipc = scratch_socket != NULL && local_exchange(AF_UNIX, scratch_socket, -1); + int moved = regular_reparent(data_path); + int alias_error = 0; + if (scratch_socket != NULL) { + char alias[512]; + int size = snprintf(alias, sizeof(alias), "%s-alias", scratch_socket); + if (size <= 0 || (size_t)size >= sizeof(alias)) return 2; + if (link(address->sun_path, alias) == 0) unlink(alias); + else alias_error = errno; + } printf("{\"started\":true,\"connected\":%s,\"sent\":%s,\"project_read\":%s," "\"pair_roundtrip\":%s,\"pair_disconnect\":%s,\"pair_reconnect\":%s," "\"pair_bind\":%s,\"pair_listen\":%s,\"pair_sendto\":%s,\"pair_sendmsg\":%s," "\"datagram_pair\":%s,\"seqpacket_pair\":%s,\"landlock_abi\":%d," - "\"tcp_roundtrip\":%s,\"thread_tcp_roundtrip\":%s,\"scratch_unix_roundtrip\":%s}\n", + "\"tcp_roundtrip\":%s,\"thread_tcp_roundtrip\":%s,\"scratch_unix_roundtrip\":%s,\"regular_reparent\":%s," + "\"cross_mount_alias_errno\":%d}\n", (connected || reconnected) ? "true" : "false", sent ? "true" : "false", readable ? "true" : "false", roundtrip ? "true" : "false", disconnected ? "true" : "false", reconnected ? "true" : "false", bound ? "true" : "false", listening ? "true" : "false", sent_to ? "true" : "false", sent_message ? "true" : "false", datagram ? "true" : "false", sequence ? "true" : "false", abi(), - tcp ? "true" : "false", thread_tcp ? "true" : "false", scratch_ipc ? "true" : "false"); + tcp ? "true" : "false", thread_tcp ? "true" : "false", scratch_ipc ? "true" : "false", + moved ? "true" : "false", alias_error); return 0; } diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md new file mode 100644 index 000000000..705815e11 --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md @@ -0,0 +1,66 @@ +# Private pathname stream integration in the broker candidate + +This implements the first real broker use of the +[endpoint identity primitive](linux-unix-endpoint-identity.md), under the approved +[integration direction](native-host-integration.md). It is an isolated candidate +increment, not completed private IPC or production activation. Datagram, +seqpacket and full runtime/owner acceptance remain required. + +The copied helper's explicit `U` profile record selects one fresh, canonical, +protected scratch directory bound as its own mount. Only explicitly owner-created +proxy endpoints may be present before guest startup. The caller must establish +that origin and protect the profile/root ancestry; the candidate's bounded +parser, no-follow directory open and pinned descriptor do not supply admission. +The guest never inherits the trusted root or endpoint descriptors. + +For this phase the family filter permits new UNIX stream sockets and stream +pairs, while retaining the current IP families. UNIX datagram/seqpacket creation +remains denied pending destination-bearing send mediation. Native bind/listen +operate in the private network namespace. An additional Landlock layer restricts +pathname socket creation to scratch, preserving the original bound pathname +instead of replacing it with a broker-internal path. + +That layer explicitly handles and grants `REFER` at the root so it does not +silently remove ordinary file moves permitted by the outer filesystem policy. +All existing filesystem restrictions still intersect it. Fresh scratch is its own +mount, so writable project sockets cannot be hard-linked into it; this origin +precondition is essential, including after a source pathname is unlinked. + +Connect notifications still pin the exact requesting thread's socket. For an +absolute scratch pathname the broker uses beneath/no-symlink/no-magic-link +resolution and checks the actual endpoint inode, retaining its O_PATH descriptor +through the worker operation. The worker keeps only socket, result pipe and +endpoint handles at fixed slots, then connects through its own procfs reference. +It never continues a mutable inspected pathname or re-resolves a guest descriptor. +Private abstract stream destinations rely on the mandatory private net namespace. + +The existing native matrix adds a distinct private-stream mode: 16 host endpoint +denials and 16 pair cases must retain read isolation, private stream/socketpair +communication and private IP/thread-local exchanges. Ordinary regular-file +reparenting must match `fs.write`, without requiring content reads. Writable +public-socket cases must independently observe EXDEV when attempting a hard link +into scratch. The old broker, cancellation, mutation, descendant and capacity +matrices remain and must rerun because worker handle ownership changed. + +Two precise temporary controls omit either the socket-creation layer or its +REFER compatibility grant. The first must bind a fixture socket in the writable +public Location and fail the named private-creation assertion. The second must +fail the named ordinary-file-move assertion in a writable Location. Neither an +unrelated setup failure nor blanket refusal counts as either counterexample. +The runtime workflow adds the five-family startup/capability matrix for this +helper; those existing rows do not themselves prove runtime pathname IPC. + +Local checks pass Rust example Clippy with warnings denied, portable fixture C +syntax (excluding its Linux-only branches), TypeScript/Python syntax, workflow +shell/embedded Python, formatting/diff and all 16 temporary builder transformations +with compiler interception. The native SDK emits two Seatbelt deprecation +warnings. Linux C compilation, kernel behavior and the new controls require +fresh hosted x64/arm64 results; no such result is claimed yet. + +Still required before complete IPC/production acceptance: actual post-pin +pathname replacement in this broker, relative/alias forms, datagram/seqpacket and +destination-bearing sends, ancillary FD/credential and peer-identity behavior, +exact proxy endpoint ownership and network ceilings, full runtime IPC controls, +immutable admission, generation quarantine and complete resource settlement. +Task N2 and parent tasks 2.1–2.4 remain open. No ordinary tool or production helper +policy is changed by these copied-source experiments. diff --git a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md index cc451755c..b73d57161 100644 --- a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md @@ -109,7 +109,8 @@ App's legacy launch path does not implement this sequence today. including private UNIX behavior and proxy endpoint identity. Retain positive runtime controls and denied ambient access, not only refusal cases. The [endpoint identity prerequisite](linux-unix-endpoint-identity.md) tests the first - pathname-object binding step; it does not complete this task. + pathname-object binding step; the [private stream candidate integration](linux-private-stream-integration.md) + applies that primitive in real connect notifications. Neither completes this task. - [ ] N3 Implement registry-owned generation admission and immutable resource binding with actual production startup, revocation and quarantine tests. - [ ] N4 Integrate the native launch owner and independently intersect all diff --git a/scripts/probes/plugin-confinement/run.mts b/scripts/probes/plugin-confinement/run.mts index 40ddc9809..22856c631 100644 --- a/scripts/probes/plugin-confinement/run.mts +++ b/scripts/probes/plugin-confinement/run.mts @@ -364,7 +364,7 @@ function check(root: string, artifacts: Artifacts, runtime: Runtime, name: strin function main() { assert(["darwin", "linux"].includes(process.platform), "native proof requires macOS or Linux; other platforms are unproved"); - const { values } = parseArgs({ options: { runtime: { type: "string", default: "python" }, "packaged-helper": { type: "string" }, python: { type: "string" }, executable: { type: "string" }, report: { type: "string" }, trace: { type: "string" }, "initial-exec": { type: "boolean", default: false }, "unix-scratch-policy": { type: "boolean", default: false }, "socket-broker": { type: "boolean", default: false }, "macos-staged-native": { type: "boolean", default: false }, "macos-signing-native": { type: "boolean", default: false }, "macos-signing-runtime": { type: "boolean", default: false } } }); + const { values } = parseArgs({ options: { runtime: { type: "string", default: "python" }, "packaged-helper": { type: "string" }, python: { type: "string" }, executable: { type: "string" }, report: { type: "string" }, trace: { type: "string" }, "initial-exec": { type: "boolean", default: false }, "unix-scratch-policy": { type: "boolean", default: false }, "socket-broker": { type: "boolean", default: false }, "broker-private-stream": { type: "boolean", default: false }, "macos-staged-native": { type: "boolean", default: false }, "macos-signing-native": { type: "boolean", default: false }, "macos-signing-runtime": { type: "boolean", default: false } } }); assert(["python", "node", "bun", "deno", "native"].includes(values.runtime), "runtime must be python, node, bun, deno or native"); if (values.runtime === "bun" || values.runtime === "deno") assert(values.executable, "supply an explicit trusted Bun/Deno executable"); const stagedPlatform = values["macos-staged-native"]; @@ -383,6 +383,7 @@ function main() { if (values.runtime === "python") assert(values.python, "supply an explicit trusted Python; embedding additionally requires development headers and a dynamic library"); assert(!values["unix-scratch-policy"] || (isLinux && initialExec && packagedHelper), "unix scratch experiment requires a Linux packaged initial-exec helper"); assert(!values["socket-broker"] || (isLinux && initialExec && packagedHelper && !values["unix-scratch-policy"]), "socket broker experiment requires a Linux packaged initial-exec helper without the UNIX-9 alternative"); + assert(!values["broker-private-stream"] || values["socket-broker"], "private stream candidate requires the socket-broker reporting mode"); const root = realpathSync(mkdtempSync(join(tmpdir(), "cyber-plugin-native-proof-"))); try { const runtime: Runtime = values.runtime === "node" ? nodeInfo() : values.runtime === "bun" || values.runtime === "deno" @@ -397,7 +398,7 @@ function main() { // Literal exec admission must name the same physical executable the kernel // resolves, including framework Python's executable symlinks. if (signingRuntime && runtime.kind !== "native") runtime.executable = realpathSync(runtime.executable); - const artifacts: Artifacts = { ...build(root, runtime, initialExec, signingRuntime, packagedHelper), trace: values.trace, packaged: Boolean(packagedHelper), unixScratch: values["unix-scratch-policy"] }; + const artifacts: Artifacts = { ...build(root, runtime, initialExec, signingRuntime, packagedHelper), trace: values.trace, packaged: Boolean(packagedHelper), unixScratch: values["unix-scratch-policy"] || values["broker-private-stream"] }; if (signingRuntime) { artifacts.signingIdentifier = `com.cyberdyne.probe.bootstrap.${randomUUID()}`; command("/usr/bin/codesign", ["--force", "--sign", "-", "--identifier", artifacts.signingIdentifier, "--timestamp=none", artifacts.executable]); @@ -435,6 +436,7 @@ function main() { private_copy: true, direct_runtime: true, } : undefined, socket_broker_candidate: values["socket-broker"], + private_stream_candidate: values["broker-private-stream"], mechanism: values["socket-broker"] ? "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter" : signingRuntime ? "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate" : stagedPlatform ? "ad-hoc-staged native image + system platform launcher Seatbelt policy before first target instruction; platform-subject exact-path exec admission" : initialExec ? "bubblewrap private mounts + Landlock/seccomp before first target instruction + one-shot exec admission; closed listener and immutable filter" : isLinux ? "bubblewrap private mounts + Landlock before runtime startup + synchronized seccomp before fixture execution" : "trusted native/runtime bootstrap followed by native sandbox_init before fixture execution", limitation: packagedHelper ? "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required" : "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", unsupported_cases, rows }; if (values.report) writeFileSync(values.report, JSON.stringify(report, null, 2) + "\n", { mode: 0o600 }); diff --git a/scripts/probes/plugin-native-entry/build_socket_candidate.py b/scripts/probes/plugin-native-entry/build_socket_candidate.py index 418e7f24d..b49baee6d 100644 --- a/scripts/probes/plugin-native-entry/build_socket_candidate.py +++ b/scripts/probes/plugin-native-entry/build_socket_candidate.py @@ -10,16 +10,33 @@ mode = sys.argv[2] if len(sys.argv) == 3 else "seccomp" assert mode in {"seccomp", "broker", "broker-no-bind", "broker-no-thread", "broker-audit", "broker-audit-no-cancel", "broker-audit-wrong-cap", "broker-mutation", "broker-mutation-no-pin", "broker-mutation-no-copy", "broker-mutation-continue", + "broker-private-stream", "broker-private-stream-no-makesock", "broker-private-stream-no-refer", "landlock9", "landlock9-no-resolve"} unix9 = mode.startswith("landlock9") +private_stream = mode.startswith("broker-private-stream") with tempfile.TemporaryDirectory(prefix="cyber-socket-candidate-") as temporary: target = Path(temporary) for name in ["linux_plugin_exec.c", "linux_filter.h", "linux_initial_exec.h"]: shutil.copyfile(root / "crates/cyber-sandbox/native" / name, target / name) - family = "linux_socket_landlock9.h" if unix9 else "linux_socket_candidate.h" + family = "linux_socket_landlock9.h" if unix9 else ( + "linux_socket_private_stream.h" if private_stream else "linux_socket_candidate.h") shutil.copyfile(Path(__file__).with_name(family), target / "socket_candidate.h") if mode.startswith("broker"): shutil.copyfile(Path(__file__).with_name("linux_socket_broker.h"), target / "socket_broker.h") + if private_stream: + shutil.copyfile(Path(__file__).with_name("linux_socket_private_unix.h"), target / "socket_private_unix.h") + if mode == "broker-private-stream-no-makesock": + header = target / "socket_private_unix.h" + text = header.read_text() + before = " if (result == 0) result = syscall(SYS_landlock_restrict_self, ruleset, 0);" + assert text.count(before) == 1 + header.write_text(text.replace(before, " /* Missing-rule control: do not install scratch-only MAKE_SOCK. */")) + if mode == "broker-private-stream-no-refer": + header = target / "socket_private_unix.h" + text = header.read_text() + before = ' if (result == 0) result = add_path(ruleset, "/", LANDLOCK_ACCESS_FS_REFER);' + assert text.count(before) == 1 + header.write_text(text.replace(before, " /* Missing compatibility grant: REFER remains denied. */")) if mode == "broker-audit-wrong-cap": broker = target / "socket_broker.h" text = broker.read_text() @@ -90,6 +107,8 @@ socket_header = target / "socket_candidate.h" text = socket_header.read_text() for name in ["bind", "listen"]: + if private_stream: + continue if mode == "broker-no-bind" and name == "bind": continue line = f" CYBER_DENY(SYS_{name}), \\\n" @@ -111,17 +130,22 @@ notify = "".join( f" BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SYS_{name}, 0, 1),\n" " BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_USER_NOTIF),\n" - for name in ["bind", "listen", "connect"]) + for name in (["connect"] if private_stream else ["bind", "listen", "connect"])) initial_header.write_text(text.replace(before, before + notify)) source = target / "linux_plugin_exec.c" text = source.read_text() + if private_stream: + before = " if ((line[0] != 'R' && line[0] != 'W')" + assert text.count(before) == 1 + text = text.replace(before, " if (line[0] == 'U') continue;\n" + before) marker = "int cyber_plugin_exec(int argc, const char *const argv[]) {" assert text.count(marker) == 1 prefix, entry = text.split(marker) boundary = " if (!single_threaded() || confine(argv[1]) != 0) {" assert entry.count(boundary) == 1 and entry.endswith("}\n") arguments = entry.split(boundary)[0] - source.write_text(prefix + '#include "socket_broker.h"\n\n' + marker + arguments + + private_define = '#define CYBER_PRIVATE_UNIX_STREAM 1\n' if private_stream else '' + source.write_text(prefix + private_define + '#include "socket_broker.h"\n\n' + marker + arguments + ' if (!single_threaded() || syscall(SYS_close_range, 3U, UINT_MAX, 0) != 0) return 2;\n' ' return broker_entry(argv, shell);\n}\n') if unix9: diff --git a/scripts/probes/plugin-native-entry/linux_socket_broker.h b/scripts/probes/plugin-native-entry/linux_socket_broker.h index f35401f7f..80dbeadc4 100644 --- a/scripts/probes/plugin-native-entry/linux_socket_broker.h +++ b/scripts/probes/plugin-native-entry/linux_socket_broker.h @@ -16,12 +16,17 @@ struct broker_result { int value; int error; }; struct broker_job { pid_t pid; int pipe; uint64_t id; }; struct broker_call { int socket; + int endpoint; int operation; int backlog; socklen_t length; struct sockaddr_storage address; }; +#ifdef CYBER_PRIVATE_UNIX_STREAM +#include "socket_private_unix.h" +#endif + static void broker_tick(int signal_number) { (void)signal_number; } static void broker_reply(int listener, uint64_t id, int value, int error) { @@ -36,6 +41,7 @@ static void broker_reply(int listener, uint64_t id, int value, int error) { static int broker_copy(int listener, const struct seccomp_notif *request, struct broker_call *call) { call->socket = -1; + call->endpoint = -1; call->operation = request->data.nr; if (request->flags != 0 || request->pid == 0 || request->data.arch != CYBER_ARCH || (call->operation != SYS_bind && call->operation != SYS_listen && @@ -54,7 +60,13 @@ static int broker_copy(int listener, const struct seccomp_notif *request, size != sizeof(int)) goto failed; size = sizeof(int); if (getsockopt(socket, SOL_SOCKET, SO_TYPE, &type, &size) != 0 || - size != sizeof(int) || (domain != AF_INET && domain != AF_INET6) || + size != sizeof(int)) goto failed; +#ifdef CYBER_PRIVATE_UNIX_STREAM + if (domain == AF_UNIX) { + if (type != SOCK_STREAM || call->operation != SYS_connect) goto failed; + } else +#endif + if ((domain != AF_INET && domain != AF_INET6) || (type != SOCK_STREAM && type != SOCK_DGRAM)) goto failed; if (call->operation == SYS_listen) { if (type != SOCK_STREAM) goto failed; @@ -75,6 +87,12 @@ static int broker_copy(int listener, const struct seccomp_notif *request, } int family = call->address.ss_family; error = EPERM; +#ifdef CYBER_PRIVATE_UNIX_STREAM + if (domain == AF_UNIX) { + error = private_endpoint(&call->address, call->length, &call->endpoint); + if (error != 0) goto failed; + } else +#endif if (family == AF_UNSPEC && call->operation == SYS_connect) { /* Only IP objects reach here; UNIX pairs cannot disconnect/rebind. */ } else if (family != domain || @@ -86,6 +104,7 @@ static int broker_copy(int listener, const struct seccomp_notif *request, call->socket = socket; return 0; failed: + if (call->endpoint >= 0) { close(call->endpoint); call->endpoint = -1; } close(socket); return error; } @@ -93,11 +112,23 @@ static int broker_copy(int listener, const struct seccomp_notif *request, static void broker_worker(struct broker_call call, int result_pipe, pid_t parent) { if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0) != 0 || getppid() != parent) _exit(125); /* Duplicate above both fixed slots first, avoiding dup2 alias clobbering. */ - int socket = fcntl(call.socket, F_DUPFD_CLOEXEC, 5); - int output = fcntl(result_pipe, F_DUPFD_CLOEXEC, 5); + int socket = fcntl(call.socket, F_DUPFD_CLOEXEC, 6); + int output = fcntl(result_pipe, F_DUPFD_CLOEXEC, 6); + int endpoint = call.endpoint < 0 ? -1 : fcntl(call.endpoint, F_DUPFD_CLOEXEC, 6); if (socket < 0 || output < 0 || dup2(socket, 3) != 3 || dup2(output, 4) != 4 || - syscall(SYS_close_range, 5U, UINT_MAX, 0) != 0) _exit(125); + (call.endpoint >= 0 && (endpoint < 0 || dup2(endpoint, 5) != 5)) || + syscall(SYS_close_range, 6U, UINT_MAX, 0) != 0) _exit(125); + if (call.endpoint < 0) close(5); close(0); close(1); close(2); +#ifdef CYBER_PRIVATE_UNIX_STREAM + if (call.endpoint >= 0) { + struct sockaddr_un *address = (struct sockaddr_un *)&call.address; + memset(address, 0, sizeof(*address)); + address->sun_family = AF_UNIX; + strcpy(address->sun_path, "/proc/self/fd/5"); + call.length = sizeof(*address); + } +#endif int value; if (call.operation == SYS_bind) value = bind(3, (struct sockaddr *)&call.address, call.length); else if (call.operation == SYS_listen) value = listen(3, call.backlog); @@ -120,6 +151,7 @@ static int broker_start(int listener, const struct seccomp_notif *request, if (pipe2(channel, O_CLOEXEC | O_NONBLOCK) != 0) { error = errno; close(call.socket); + if (call.endpoint >= 0) close(call.endpoint); return error; } pid_t parent = getpid(); @@ -127,6 +159,7 @@ static int broker_start(int listener, const struct seccomp_notif *request, error = errno; if (worker == 0) broker_worker(call, channel[1], parent); close(call.socket); + if (call.endpoint >= 0) close(call.endpoint); close(channel[1]); if (worker < 0) { close(channel[0]); return error; } jobs[slot] = (struct broker_job){ .pid = worker, .pipe = channel[0], .id = request->id }; @@ -244,6 +277,9 @@ static int broker_loop(int listener, pid_t guest, int shell) { } static int broker_entry(const char *const argv[], int shell) { +#ifdef CYBER_PRIVATE_UNIX_STREAM + if (private_initialize(argv[1]) != 0) return 2; +#endif int channel[2]; struct sigaction child_action = { .sa_handler = SIG_DFL }; sigemptyset(&child_action.sa_mask); @@ -262,6 +298,10 @@ static int broker_entry(const char *const argv[], int shell) { close(channel[0]); if (prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0) != 0 || getppid() != parent || prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) != 0 || confine(argv[1]) != 0) _exit(2); +#ifdef CYBER_PRIVATE_UNIX_STREAM + if (private_make_sock() != 0) _exit(2); + close(private_root); +#endif int listener = initial_filter(shell); int sent = listener < 0 ? -1 : transfer_listener(channel[1], listener); if (listener >= 0) close(listener); @@ -276,6 +316,9 @@ static int broker_entry(const char *const argv[], int shell) { if (listener < 0) { (void)kill(guest, SIGKILL); broker_reap(guest); return 2; } int result = broker_loop(listener, guest, shell); close(listener); +#ifdef CYBER_PRIVATE_UNIX_STREAM + close(private_root); +#endif return result; } #endif diff --git a/scripts/probes/plugin-native-entry/linux_socket_private_stream.h b/scripts/probes/plugin-native-entry/linux_socket_private_stream.h new file mode 100644 index 000000000..f1a26afd2 --- /dev/null +++ b/scripts/probes/plugin-native-entry/linux_socket_private_stream.h @@ -0,0 +1,30 @@ +/* Private-stream candidate only. Datagram/seqpacket mediation remains required. */ +#ifndef CYBER_SOCKET_PRIVATE_STREAM_H +#define CYBER_SOCKET_PRIVATE_STREAM_H +#include + +/* Every UNIX object created here is a stream. Destination-bearing sendmsg on + * such an object cannot establish a new peer; datagram creation stays denied. + * Native bind is constrained by a separate scratch-only MAKE_SOCK ruleset. */ +#define CYBER_SOCKET_FAMILIES \ + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SYS_socket, 0, 10), \ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, args[0])), \ + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AF_INET, 7, 0), \ + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AF_INET6, 6, 0), \ + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AF_UNIX, 1, 0), \ + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | EPERM), \ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, args[1])), \ + BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~(SOCK_CLOEXEC | SOCK_NONBLOCK)), \ + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SOCK_STREAM, 1, 0), \ + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | EPERM), \ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)), \ + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SYS_socketpair, 0, 8), \ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, args[0])), \ + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AF_UNIX, 1, 0), \ + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | EPERM), \ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, args[1])), \ + BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~(SOCK_CLOEXEC | SOCK_NONBLOCK)), \ + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, SOCK_STREAM, 1, 0), \ + BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | EPERM), \ + BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)) +#endif diff --git a/scripts/probes/plugin-native-entry/linux_socket_private_unix.h b/scripts/probes/plugin-native-entry/linux_socket_private_unix.h new file mode 100644 index 000000000..d90fff1ed --- /dev/null +++ b/scripts/probes/plugin-native-entry/linux_socket_private_unix.h @@ -0,0 +1,112 @@ +/* Isolated broker extension. Requires a fresh scratch tree bound as its own + * mount, with only explicitly owned proxy endpoints initially present, and + * protected profile/root provenance. No foreign socket may already be linked + * into it. This is not an owner admission API or complete IPC support. */ +#ifndef CYBER_SOCKET_PRIVATE_UNIX_H +#define CYBER_SOCKET_PRIVATE_UNIX_H +#include +#include + +static int private_root = -1; +static char private_path[4096]; + +static int private_initialize(const char *profile) { + int fd = open(profile, O_RDONLY | O_NOFOLLOW | O_CLOEXEC | O_NONBLOCK | O_NOCTTY); + struct stat info; + if (fd < 0 || fstat(fd, &info) != 0 || !S_ISREG(info.st_mode) || + info.st_nlink != 1 || info.st_size <= 0 || info.st_size > 65536) { + if (fd >= 0) close(fd); + return -1; + } + size_t size = (size_t)info.st_size, offset = 0; + char *text = calloc(size + 1, 1); + if (text == NULL) { close(fd); return -1; } + while (offset < size) { + ssize_t count = read(fd, text + offset, size - offset); + if (count < 0 && errno == EINTR) continue; + if (count <= 0) { free(text); close(fd); return -1; } + offset += (size_t)count; + } + close(fd); + int found = 0, valid = strlen(text) == size; + char *state = NULL; + for (char *line = strtok_r(text, "\n", &state); valid && line; + line = strtok_r(NULL, "\n", &state)) { + if (line[0] != 'U') continue; + size_t length = strlen(line); + if (found || length < 4 || line[1] != '\t' || line[2] != '/' || + length - 2 >= sizeof(private_path) || line[length - 1] == '/') { + valid = 0; break; + } + for (size_t i = 2; i < length; ++i) { + unsigned char byte = (unsigned char)line[i]; + if (byte < 32 || byte == 127) valid = 0; + } + if (!valid) break; + strcpy(private_path, line + 2); + if (strstr(private_path, "//") != NULL) valid = 0; + /* The owner supplies a canonical root; no lexical . or .. aliases. */ + char copy[sizeof(private_path)]; + strcpy(copy, private_path); + char *part_state = NULL; + for (char *part = strtok_r(copy, "/", &part_state); part; + part = strtok_r(NULL, "/", &part_state)) { + if (strcmp(part, ".") == 0 || strcmp(part, "..") == 0) valid = 0; + } + found = 1; + } + free(text); + if (!valid || !found) return -1; + private_root = open(private_path, O_PATH | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); + return private_root < 0 ? -1 : 0; +} + +static int private_make_sock(void) { + struct landlock_ruleset_attr attributes = { + .handled_access_fs = LANDLOCK_ACCESS_FS_MAKE_SOCK | LANDLOCK_ACCESS_FS_REFER, + }; + int ruleset = syscall(SYS_landlock_create_ruleset, &attributes, + sizeof(attributes.handled_access_fs), 0); + if (ruleset < 0) return -1; + struct landlock_path_beneath_attr rule = { + .allowed_access = LANDLOCK_ACCESS_FS_MAKE_SOCK, .parent_fd = private_root, + }; + int result = syscall(SYS_landlock_add_rule, ruleset, LANDLOCK_RULE_PATH_BENEATH, &rule, 0); + /* REFER is implicitly denied even by a MAKE_SOCK-only layer. Preserve the + * outer filesystem policy's regular reparenting grants; this layer narrows + * only socket creation. Separate scratch mounts prevent cross-root links. */ + if (result == 0) result = add_path(ruleset, "/", LANDLOCK_ACCESS_FS_REFER); + if (result == 0) result = syscall(SYS_landlock_restrict_self, ruleset, 0); + close(ruleset); + return result; +} + +/* The real socket descriptor was already pinned for the exact notifying thread. + * Return a pinned pathname endpoint, or -1 for a private abstract/UNSPEC address. */ +static int private_endpoint(struct sockaddr_storage *storage, socklen_t length, int *endpoint) { + *endpoint = -1; + if (storage->ss_family == AF_UNSPEC) return 0; + if (length <= offsetof(struct sockaddr_un, sun_path) || + length > sizeof(struct sockaddr_un) || storage->ss_family != AF_UNIX) return EINVAL; + struct sockaddr_un *address = (struct sockaddr_un *)storage; + if (address->sun_path[0] == '\0') return 0; /* Mandatory private net namespace. */ + char path[sizeof(address->sun_path) + 1]; + size_t count = length - offsetof(struct sockaddr_un, sun_path); + memcpy(path, address->sun_path, count); + path[count] = '\0'; + size_t prefix = strlen(private_path); + if (prefix >= strlen(path) || strncmp(path, private_path, prefix) != 0 || + path[prefix] != '/') return EPERM; + struct open_how how = { .flags = O_PATH | O_CLOEXEC, + .resolve = RESOLVE_BENEATH | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS }; + int fd = syscall(SYS_openat2, private_root, path + prefix + 1, &how, sizeof(how)); + if (fd < 0) return errno; + struct stat info; + if (fstat(fd, &info) != 0 || !S_ISSOCK(info.st_mode)) { + close(fd); + return ENOTSOCK; + } + *endpoint = fd; + return 0; +} +#endif From 739ec2034f2bdee6ef7edb932764f23e3b8066b4 Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 09:26:40 -0400 Subject: [PATCH 06/21] docs(plugins): record foundations merge and private stream evidence --- docs/goal-delivery.md | 16 +- .../linux-private-stream-integration.md | 33 +- .../complete-plugin-hook-runtime/tasks.md | 3 + .../broker-private-stream-no-makesock.log | 6 + .../arm64/broker-private-stream-no-refer.log | 6 + .../linux-ipc-broker-private-stream.json | 751 ++++++++++++++++++ .../socket-runtime/private-stream/bun.json | 487 ++++++++++++ .../socket-runtime/private-stream/deno.json | 438 ++++++++++ .../socket-runtime/private-stream/native.json | 474 +++++++++++ .../socket-runtime/private-stream/node.json | 438 ++++++++++ .../socket-runtime/private-stream/python.json | 429 ++++++++++ .../x64/broker-private-stream-no-makesock.log | 6 + .../x64/broker-private-stream-no-refer.log | 6 + .../x64/linux-ipc-broker-private-stream.json | 751 ++++++++++++++++++ .../socket-runtime/private-stream/bun.json | 487 ++++++++++++ .../socket-runtime/private-stream/deno.json | 438 ++++++++++ .../socket-runtime/private-stream/native.json | 474 +++++++++++ .../socket-runtime/private-stream/node.json | 438 ++++++++++ .../socket-runtime/private-stream/python.json | 429 ++++++++++ 19 files changed, 6105 insertions(+), 5 deletions(-) create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/broker-private-stream-no-makesock.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/broker-private-stream-no-refer.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/linux-ipc-broker-private-stream.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/bun.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/deno.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/native.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/node.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/python.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/broker-private-stream-no-makesock.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/broker-private-stream-no-refer.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/linux-ipc-broker-private-stream.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/bun.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/deno.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/native.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/node.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/python.json diff --git a/docs/goal-delivery.md b/docs/goal-delivery.md index 1cbdd8f66..3a7d86412 100644 --- a/docs/goal-delivery.md +++ b/docs/goal-delivery.md @@ -45,9 +45,19 @@ separate review. This changes delivery granularity, not feature scope or accepta to finish a PR. Merge only with user authorization; the conditional approval above applies to #76. -As of consolidation, native confinement foundations and regressions exist, but +PR [#76](https://github.com/CyberdyneCorp/cybercode-cli/pull/76) merged on +2026-10-30 at `ec31ff9fc7627a3a9262d99f0fc0606394368423`, after all 70 applicable +checks passed and the optional diagnostic was intentionally skipped. Its merge +tree matches the reviewed/tested `e6fd3d2f` tree. The user approved continuing the +[Linux broker direction](../openspec/changes/complete-plugin-hook-runtime/native-host-integration.md) +with runtime kernel capability checks and full private IPC/network compatibility +remaining required before activation. Continue on the single +`feat/plugin-native-host-admission` follow-up branch/PR, retaining its original +tested sources on `evidence/plugin-native-host-pre-76-merge` across rebase. + +Native confinement foundations and regressions exist, but production enforcement and the remaining plugin/hook scope are incomplete. The Linux UNIX-socket diagnostic found a real host-reachability gap. Its experimental -filter and runtime checks are under investigation; no support revision or host -activation is accepted. Daily coding and binary editor implementation have not +filter and runtime checks remain experimental. The broker direction is approved; +complete support acceptance and host activation remain pending. Daily coding and binary editor implementation have not started. The linked task lists remain authoritative for completion. diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md index 705815e11..6fba2fdfa 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md @@ -54,8 +54,37 @@ Local checks pass Rust example Clippy with warnings denied, portable fixture C syntax (excluding its Linux-only branches), TypeScript/Python syntax, workflow shell/embedded Python, formatting/diff and all 16 temporary builder transformations with compiler interception. The native SDK emits two Seatbelt deprecation -warnings. Linux C compilation, kernel behavior and the new controls require -fresh hosted x64/arm64 results; no such result is claimed yet. +warnings. The hosted result below supplies Linux compilation/kernel evidence for +the exact tested source, rather than assigning local macOS checks that scope. + +## Native result for 2b86ac8b + +[Run 41058437042](https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41058437042) +passed on Linux x64 and arm64. Each architecture's private-stream report contains +32 cases: 16 ambient endpoint denials and 16 pair cases with successful scratch +stream/IP/thread-local exchanges, independent read/write expectations and regular +file moves matching `fs.write`. Both writable public-socket cases observe EXDEV +for the cross-mount alias attempt. The exact missing-MAKE_SOCK and missing-REFER +controls fail their named assertions after positive startup and scratch exchange. + +Each architecture's five private-stream runtime reports contain nine cases, +including an unconfined control, with no unsupported rows: 45 cases per +architecture. These are startup/capability regressions, not full runtime IPC +acceptance. The workflow also passes its existing broker cancellation, mutation, +descendant and worker-capacity checks after the worker descriptor changes. + +Original reports, both control logs and the five runtime JSON reports are retained +under `scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/{x64,arm64}`. +They bind original checkout `2b86ac8b8ea70bb2c5030ca6b22e948b345e3f7b`, kernel +`7.0.0-1017-azure`, socket source manifest SHA-256 +`1f096940494d0a1bb9756ff4c020fc7fd75a591f377557b1cd791c8d837f9b59` +and runtime source manifest SHA-256 +`52bcf7e1df59d36b59b85de1181c2e85d7dfcc79bfa3cf728c06e65b75831630`. +Both manifests were independently recomputed from that exact Git tree. Every +runtime report's input/executed helper digest matches its architecture's socket +report. The tested commits remain on `evidence/plugin-native-host-pre-76-merge` +when the implementation branch is rebased onto the #76 squash merge. These +original receipts are not relabeled as execution of the rebased head. Still required before complete IPC/production acceptance: actual post-pin pathname replacement in this broker, relative/alias forms, datagram/seqpacket and diff --git a/openspec/changes/complete-plugin-hook-runtime/tasks.md b/openspec/changes/complete-plugin-hook-runtime/tasks.md index b31d113fa..9c390bfa8 100644 --- a/openspec/changes/complete-plugin-hook-runtime/tasks.md +++ b/openspec/changes/complete-plugin-hook-runtime/tasks.md @@ -4,6 +4,9 @@ Delivery rule updated by the user on 2026-10-29: normally one open goal PR, maximum two only for independently reviewable work. #70–#75 were consolidated into #76 against `main`. On 2026-10-30 the user authorized merging that foundations milestone after green CI and merge review, then continuing in one follow-up PR. +PR #76 merged at `ec31ff9f` after 70 passing checks and one intentional diagnostic +skip. Its tree matches the tested `e6fd3d2f` tree. Continue on the single native +host admission follow-up; the foundations milestone does not complete task 2. The full goal scope, order and acceptance gates remain unchanged. See [goal delivery rules](../../../docs/goal-delivery.md). diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/broker-private-stream-no-makesock.log b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/broker-private-stream-no-makesock.log new file mode 100644 index 000000000..5fa6149fa --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/broker-private-stream-no-makesock.log @@ -0,0 +1,6 @@ + +thread 'main' (5213) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:157:13: +assertion `left == right` failed: private pair escape: pair_bind: public read=false write=true: {"started":true,"connected":false,"sent":false,"project_read":false,"pair_roundtrip":true,"pair_disconnect":false,"pair_reconnect":false,"pair_bind":true,"pair_listen":true,"pair_sendto":false,"pair_sendmsg":false,"datagram_pair":false,"seqpacket_pair":false,"landlock_abi":8,"tcp_roundtrip":true,"thread_tcp_roundtrip":true,"scratch_unix_roundtrip":true,"regular_reparent":true,"cross_mount_alias_errno":18} + left: Bool(true) + right: false +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/broker-private-stream-no-refer.log b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/broker-private-stream-no-refer.log new file mode 100644 index 000000000..deb754505 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/broker-private-stream-no-refer.log @@ -0,0 +1,6 @@ + +thread 'main' (5300) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:165:13: +assertion `left == right` failed: private IPC layer changed ordinary file moves: outside read=false write=true: {"started":true,"connected":false,"sent":false,"project_read":false,"pair_roundtrip":true,"pair_disconnect":false,"pair_reconnect":false,"pair_bind":false,"pair_listen":false,"pair_sendto":false,"pair_sendmsg":false,"datagram_pair":false,"seqpacket_pair":false,"landlock_abi":8,"tcp_roundtrip":true,"thread_tcp_roundtrip":true,"scratch_unix_roundtrip":true,"regular_reparent":false,"cross_mount_alias_errno":18} + left: Bool(false) + right: true +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/linux-ipc-broker-private-stream.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/linux-ipc-broker-private-stream.json new file mode 100644 index 000000000..a6e4b7c41 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/linux-ipc-broker-private-stream.json @@ -0,0 +1,751 @@ +{ + "platform": "linux", + "architecture": "aarch64", + "checkout": "2b86ac8b8ea70bb2c5030ca6b22e948b345e3f7b", + "run_id": "41058437042", + "candidate": true, + "landlock9": false, + "socket_broker": true, + "private_stream_probe": true, + "cancellation_probe": false, + "mutation_probe": false, + "escape_probe": null, + "saturation_probe": false, + "sources": [ + "crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", + "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", + "crates/cyber-sandbox/src/plugin_policy.rs", + "crates/cyber-sandbox/src/plugin_policy/linux.rs", + "crates/cyber-sandbox/native/linux_plugin_exec.c", + "crates/cyber-sandbox/native/linux_filter.h", + "crates/cyber-sandbox/native/linux_initial_exec.h", + "crates/cyber-sandbox/src/native_exec.rs", + "crates/cyber-sandbox/src/bin/cyber-sandbox-exec.rs", + "crates/cyber-sandbox/build.rs", + "crates/cyber-sandbox/Cargo.toml", + "Cargo.lock", + ".github/workflows/plugin-linux-ipc.yml", + "scripts/probes/plugin-native-entry/linux_socket_candidate.h", + "scripts/probes/plugin-native-entry/linux_socket_broker.h", + "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", + "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", + "scripts/probes/plugin-native-entry/linux_unix9_policy.h", + "scripts/probes/plugin-native-entry/build_socket_candidate.py" + ], + "source_sha256": "1f096940494d0a1bb9756ff4c020fc7fd75a591f377557b1cd791c8d837f9b59", + "helper_sha256": "00accc611b52f5eb0cda61120c905630dbfedad105b50bbd076983010860f821", + "rows": [ + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + } + ], + "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/bun.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/bun.json new file mode 100644 index 000000000..014c191f1 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/bun.json @@ -0,0 +1,487 @@ +{ + "recorded_at": "2026-10-30T12:53:25.089Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "52bcf7e1df59d36b59b85de1181c2e85d7dfcc79bfa3cf728c06e65b75831630", + "platform": "linux", + "architecture": "arm64", + "runtime": "bun", + "version": "1.4.4", + "startup_control": { + "preload": true, + "dotenv": true + }, + "packaged_helper": { + "input_sha256": "00accc611b52f5eb0cda61120c905630dbfedad105b50bbd076983010860f821", + "executed_sha256": "00accc611b52f5eb0cda61120c905630dbfedad105b50bbd076983010860f821", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "filter_replacement_denied": false, + "proc_root_reads": [ + true, + true + ], + "proc_init_list": true + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/deno.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/deno.json new file mode 100644 index 000000000..93490e3b6 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/deno.json @@ -0,0 +1,438 @@ +{ + "recorded_at": "2026-10-30T12:53:27.446Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "52bcf7e1df59d36b59b85de1181c2e85d7dfcc79bfa3cf728c06e65b75831630", + "platform": "linux", + "architecture": "arm64", + "runtime": "deno", + "version": "2.9.8", + "packaged_helper": { + "input_sha256": "00accc611b52f5eb0cda61120c905630dbfedad105b50bbd076983010860f821", + "executed_sha256": "00accc611b52f5eb0cda61120c905630dbfedad105b50bbd076983010860f821", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "filter_replacement_denied": false + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/native.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/native.json new file mode 100644 index 000000000..47755241e --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/native.json @@ -0,0 +1,474 @@ +{ + "recorded_at": "2026-10-30T12:53:27.843Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "52bcf7e1df59d36b59b85de1181c2e85d7dfcc79bfa3cf728c06e65b75831630", + "platform": "linux", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "packaged_helper": { + "input_sha256": "00accc611b52f5eb0cda61120c905630dbfedad105b50bbd076983010860f821", + "executed_sha256": "00accc611b52f5eb0cda61120c905630dbfedad105b50bbd076983010860f821", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": true, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": false + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/node.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/node.json new file mode 100644 index 000000000..a60bb1cc6 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/node.json @@ -0,0 +1,438 @@ +{ + "recorded_at": "2026-10-30T12:53:23.172Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "52bcf7e1df59d36b59b85de1181c2e85d7dfcc79bfa3cf728c06e65b75831630", + "platform": "linux", + "architecture": "arm64", + "runtime": "node", + "version": "22.23.4", + "packaged_helper": { + "input_sha256": "00accc611b52f5eb0cda61120c905630dbfedad105b50bbd076983010860f821", + "executed_sha256": "00accc611b52f5eb0cda61120c905630dbfedad105b50bbd076983010860f821", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "filter_replacement_denied": false + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/python.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/python.json new file mode 100644 index 000000000..4e7ca5d3d --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/arm64/socket-runtime/private-stream/python.json @@ -0,0 +1,429 @@ +{ + "recorded_at": "2026-10-30T12:53:24.161Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "52bcf7e1df59d36b59b85de1181c2e85d7dfcc79bfa3cf728c06e65b75831630", + "platform": "linux", + "architecture": "arm64", + "runtime": "python", + "version": "3.13.17", + "packaged_helper": { + "input_sha256": "00accc611b52f5eb0cda61120c905630dbfedad105b50bbd076983010860f821", + "executed_sha256": "00accc611b52f5eb0cda61120c905630dbfedad105b50bbd076983010860f821", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "cannot_relax": null, + "child_reads": [ + true, + true + ], + "filter_replacement_denied": false, + "hardlink_private": true, + "inherited_descriptor": true, + "native_child_reads": [ + true, + true + ], + "native_fork": true, + "package_read": true, + "private_list": true, + "private_read": true, + "private_write": true, + "project_list": true, + "project_read": true, + "project_rename": true, + "project_write": true, + "protected_read": true, + "protected_write": true, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/broker-private-stream-no-makesock.log b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/broker-private-stream-no-makesock.log new file mode 100644 index 000000000..7d543d3bf --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/broker-private-stream-no-makesock.log @@ -0,0 +1,6 @@ + +thread 'main' (5100) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:157:13: +assertion `left == right` failed: private pair escape: pair_bind: public read=false write=true: {"started":true,"connected":false,"sent":false,"project_read":false,"pair_roundtrip":true,"pair_disconnect":false,"pair_reconnect":false,"pair_bind":true,"pair_listen":true,"pair_sendto":false,"pair_sendmsg":false,"datagram_pair":false,"seqpacket_pair":false,"landlock_abi":8,"tcp_roundtrip":true,"thread_tcp_roundtrip":true,"scratch_unix_roundtrip":true,"regular_reparent":true,"cross_mount_alias_errno":18} + left: Bool(true) + right: false +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/broker-private-stream-no-refer.log b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/broker-private-stream-no-refer.log new file mode 100644 index 000000000..ed6d173c5 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/broker-private-stream-no-refer.log @@ -0,0 +1,6 @@ + +thread 'main' (5187) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:165:13: +assertion `left == right` failed: private IPC layer changed ordinary file moves: outside read=false write=true: {"started":true,"connected":false,"sent":false,"project_read":false,"pair_roundtrip":true,"pair_disconnect":false,"pair_reconnect":false,"pair_bind":false,"pair_listen":false,"pair_sendto":false,"pair_sendmsg":false,"datagram_pair":false,"seqpacket_pair":false,"landlock_abi":8,"tcp_roundtrip":true,"thread_tcp_roundtrip":true,"scratch_unix_roundtrip":true,"regular_reparent":false,"cross_mount_alias_errno":18} + left: Bool(false) + right: true +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/linux-ipc-broker-private-stream.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/linux-ipc-broker-private-stream.json new file mode 100644 index 000000000..6c631e578 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/linux-ipc-broker-private-stream.json @@ -0,0 +1,751 @@ +{ + "platform": "linux", + "architecture": "x86_64", + "checkout": "2b86ac8b8ea70bb2c5030ca6b22e948b345e3f7b", + "run_id": "41058437042", + "candidate": true, + "landlock9": false, + "socket_broker": true, + "private_stream_probe": true, + "cancellation_probe": false, + "mutation_probe": false, + "escape_probe": null, + "saturation_probe": false, + "sources": [ + "crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", + "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", + "crates/cyber-sandbox/src/plugin_policy.rs", + "crates/cyber-sandbox/src/plugin_policy/linux.rs", + "crates/cyber-sandbox/native/linux_plugin_exec.c", + "crates/cyber-sandbox/native/linux_filter.h", + "crates/cyber-sandbox/native/linux_initial_exec.h", + "crates/cyber-sandbox/src/native_exec.rs", + "crates/cyber-sandbox/src/bin/cyber-sandbox-exec.rs", + "crates/cyber-sandbox/build.rs", + "crates/cyber-sandbox/Cargo.toml", + "Cargo.lock", + ".github/workflows/plugin-linux-ipc.yml", + "scripts/probes/plugin-native-entry/linux_socket_candidate.h", + "scripts/probes/plugin-native-entry/linux_socket_broker.h", + "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", + "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", + "scripts/probes/plugin-native-entry/linux_unix9_policy.h", + "scripts/probes/plugin-native-entry/build_socket_candidate.py" + ], + "source_sha256": "1f096940494d0a1bb9756ff4c020fc7fd75a591f377557b1cd791c8d837f9b59", + "helper_sha256": "a845788e0110e7f30db62c5c4d579a8a96a43843f9bde7837187fd63c475a0fd", + "rows": [ + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + } + ], + "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/bun.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/bun.json new file mode 100644 index 000000000..cf79c6a30 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/bun.json @@ -0,0 +1,487 @@ +{ + "recorded_at": "2026-10-30T12:53:01.250Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "52bcf7e1df59d36b59b85de1181c2e85d7dfcc79bfa3cf728c06e65b75831630", + "platform": "linux", + "architecture": "x64", + "runtime": "bun", + "version": "1.4.4", + "startup_control": { + "preload": true, + "dotenv": true + }, + "packaged_helper": { + "input_sha256": "a845788e0110e7f30db62c5c4d579a8a96a43843f9bde7837187fd63c475a0fd", + "executed_sha256": "a845788e0110e7f30db62c5c4d579a8a96a43843f9bde7837187fd63c475a0fd", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "filter_replacement_denied": false, + "proc_root_reads": [ + true, + true + ], + "proc_init_list": true + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/deno.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/deno.json new file mode 100644 index 000000000..3f0fd0a89 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/deno.json @@ -0,0 +1,438 @@ +{ + "recorded_at": "2026-10-30T12:53:02.985Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "52bcf7e1df59d36b59b85de1181c2e85d7dfcc79bfa3cf728c06e65b75831630", + "platform": "linux", + "architecture": "x64", + "runtime": "deno", + "version": "2.9.8", + "packaged_helper": { + "input_sha256": "a845788e0110e7f30db62c5c4d579a8a96a43843f9bde7837187fd63c475a0fd", + "executed_sha256": "a845788e0110e7f30db62c5c4d579a8a96a43843f9bde7837187fd63c475a0fd", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "filter_replacement_denied": false + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/native.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/native.json new file mode 100644 index 000000000..51d2ccb8f --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/native.json @@ -0,0 +1,474 @@ +{ + "recorded_at": "2026-10-30T12:53:03.281Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "52bcf7e1df59d36b59b85de1181c2e85d7dfcc79bfa3cf728c06e65b75831630", + "platform": "linux", + "architecture": "x64", + "runtime": "native", + "version": "fixture-v2", + "packaged_helper": { + "input_sha256": "a845788e0110e7f30db62c5c4d579a8a96a43843f9bde7837187fd63c475a0fd", + "executed_sha256": "a845788e0110e7f30db62c5c4d579a8a96a43843f9bde7837187fd63c475a0fd", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": true, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": false + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/node.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/node.json new file mode 100644 index 000000000..6f319da0e --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/node.json @@ -0,0 +1,438 @@ +{ + "recorded_at": "2026-10-30T12:52:59.820Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "52bcf7e1df59d36b59b85de1181c2e85d7dfcc79bfa3cf728c06e65b75831630", + "platform": "linux", + "architecture": "x64", + "runtime": "node", + "version": "22.23.4", + "packaged_helper": { + "input_sha256": "a845788e0110e7f30db62c5c4d579a8a96a43843f9bde7837187fd63c475a0fd", + "executed_sha256": "a845788e0110e7f30db62c5c4d579a8a96a43843f9bde7837187fd63c475a0fd", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "filter_replacement_denied": false + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "filter_replacement_denied": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/python.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/python.json new file mode 100644 index 000000000..fb5d5db81 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-2b86ac8b/x64/socket-runtime/private-stream/python.json @@ -0,0 +1,429 @@ +{ + "recorded_at": "2026-10-30T12:53:00.557Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "52bcf7e1df59d36b59b85de1181c2e85d7dfcc79bfa3cf728c06e65b75831630", + "platform": "linux", + "architecture": "x64", + "runtime": "python", + "version": "3.13.17", + "packaged_helper": { + "input_sha256": "a845788e0110e7f30db62c5c4d579a8a96a43843f9bde7837187fd63c475a0fd", + "executed_sha256": "a845788e0110e7f30db62c5c4d579a8a96a43843f9bde7837187fd63c475a0fd", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "cannot_relax": null, + "child_reads": [ + true, + true + ], + "filter_replacement_denied": false, + "hardlink_private": true, + "inherited_descriptor": true, + "native_child_reads": [ + true, + true + ], + "native_fork": true, + "package_read": true, + "private_list": true, + "private_read": true, + "private_write": true, + "project_list": true, + "project_read": true, + "project_rename": true, + "project_write": true, + "protected_read": true, + "protected_write": true, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + } + ] +} From 9bb0fb6040af2b9f0a0e3767148a2c889afd9c73 Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 10:57:57 -0400 Subject: [PATCH 07/21] test(plugins): exercise private endpoint replacement in broker --- .github/workflows/plugin-linux-ipc.yml | 24 ++++- .../examples/plugin_unix_socket_probe.rs | 24 ++++- .../examples/support/plugin_socket_cancel.rs | 92 +++++++++++++++++-- .../tests/fixtures/plugin_unix_mutation.h | 71 ++++++++++++++ .../tests/fixtures/plugin_unix_socket.c | 2 + docs/goal-delivery.md | 3 +- .../linux-private-stream-integration.md | 7 +- .../linux-private-stream-mutation.md | 48 ++++++++++ .../build_socket_candidate.py | 22 ++++- 9 files changed, 274 insertions(+), 19 deletions(-) create mode 100644 crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h create mode 100644 openspec/changes/complete-plugin-hook-runtime/linux-private-stream-mutation.md diff --git a/.github/workflows/plugin-linux-ipc.yml b/.github/workflows/plugin-linux-ipc.yml index 471f7a49a..9e48d8697 100644 --- a/.github/workflows/plugin-linux-ipc.yml +++ b/.github/workflows/plugin-linux-ipc.yml @@ -7,6 +7,7 @@ on: - crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c - crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h - crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h + - crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h - crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h - crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h - crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs @@ -107,7 +108,7 @@ jobs: python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/socket-broker-audit" broker-audit python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/socket-broker-no-cancel" broker-audit-no-cancel python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/socket-broker-wrong-cap" broker-audit-wrong-cap - for variant in broker-private-stream broker-private-stream-no-makesock broker-private-stream-no-refer; do + for variant in broker-private-stream broker-private-stream-no-makesock broker-private-stream-no-refer broker-private-stream-mutation broker-private-stream-mutation-no-endpoint; do python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/$variant" "$variant" done for mode in mutation mutation-no-pin mutation-no-copy mutation-continue; do @@ -128,6 +129,26 @@ jobs: target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/socket-broker" "$RUNNER_TEMP/linux-ipc-broker-escape.json" --broker-escape target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/socket-broker-audit" "$RUNNER_TEMP/linux-ipc-broker-saturation.json" --broker-saturation target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/broker-private-stream" "$RUNNER_TEMP/linux-ipc-broker-private-stream.json" --broker-private-stream + target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/broker-private-stream-mutation" "$RUNNER_TEMP/linux-ipc-broker-private-stream-mutation.json" --broker-private-stream-mutation + - name: Reject pathname re-resolution after private endpoint pinning + shell: bash + run: | + set -euo pipefail + log="$RUNNER_TEMP/private-stream-no-endpoint.log" + if target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/broker-private-stream-mutation-no-endpoint" "$RUNNER_TEMP/linux-ipc-private-no-endpoint.json" --broker-private-stream-mutation > "$log" 2>&1; then + echo 'Missing private endpoint pin unexpectedly passed' >&2 + exit 1 + fi + python3 - "$log" <<'PY' + from pathlib import Path + import sys + text = Path(sys.argv[1]).read_text() + assert 'private UNIX mutation escaped the pinned endpoint' in text, text + for token in ['"fd_replaced":true', '"address_changed":true', '"path_replaced":true', + '"original_unlinked":true', '"result_ok":true', '"sent":true', + '"private_roundtrip":false', '"host_received_fixture":true', 'BPIN ']: + assert token in text, text + PY - name: Reject missing private socket creation and file-move compatibility guards shell: bash run: | @@ -367,6 +388,7 @@ jobs: ${{ runner.temp }}/broker-no-bind.log ${{ runner.temp }}/broker-private-stream-no-makesock.log ${{ runner.temp }}/broker-private-stream-no-refer.log + ${{ runner.temp }}/private-stream-no-endpoint.log ${{ runner.temp }}/broker-no-thread.log ${{ runner.temp }}/broker-no-cancel.log ${{ runner.temp }}/broker-mutation-*.log diff --git a/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs b/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs index ad48e4982..dca56e69a 100644 --- a/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs +++ b/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs @@ -73,6 +73,7 @@ mod probe { BrokerEscapeNoPid, BrokerSaturation, BrokerPrivateStream, + BrokerPrivateStreamMutation, Unix9, } impl Mode { @@ -87,6 +88,7 @@ mod probe { | Self::BrokerEscapeNoPid | Self::BrokerSaturation | Self::BrokerPrivateStream + | Self::BrokerPrivateStreamMutation ) } fn broker(self) -> bool { @@ -99,6 +101,13 @@ mod probe { | Self::BrokerEscapeNoPid | Self::BrokerSaturation | Self::BrokerPrivateStream + | Self::BrokerPrivateStreamMutation + ) + } + fn private_stream(self) -> bool { + matches!( + self, + Self::BrokerPrivateStream | Self::BrokerPrivateStreamMutation ) } fn escape(self) -> Option { @@ -112,7 +121,7 @@ mod probe { fn observe(policy: &LinuxPolicy<'_>, mode: Mode) -> Value { let mut plan = policy.compose().unwrap(); - if matches!(mode, Mode::Unix9 | Mode::BrokerPrivateStream) { + if mode == Mode::Unix9 || mode.private_stream() { plan.landlock .push_str(&format!("U\t{}\n", policy.scratch.display())); } @@ -161,7 +170,7 @@ mod probe { ); } check_pair_support(&observed, mode); - if mode == Mode::BrokerPrivateStream { + if mode.private_stream() { assert_eq!( observed["regular_reparent"], pair_policy.fs_write, "private IPC layer changed ordinary file moves: {label} read={} write={}: {observed}", @@ -191,7 +200,7 @@ mod probe { } assert_eq!( observed["scratch_unix_roundtrip"], - matches!(mode, Mode::Unix9 | Mode::BrokerPrivateStream), + mode == Mode::Unix9 || mode.private_stream(), "private scratch stream roundtrip: {observed}" ); assert_eq!( @@ -216,6 +225,11 @@ mod probe { mode: Mode, ) -> Vec { let mut rows = Vec::new(); + if mode == Mode::BrokerPrivateStreamMutation && label == "outside" { + let observed = super::cancellation::observe_unix_mutation(&policy, listener); + rows.push(json!({"mode":"unix-mutation","socket":label, + "fs_read":policy.fs_read,"fs_write":policy.fs_write,"shell":false,"observed":observed})); + } if mode == Mode::BrokerSaturation && label == "outside" { let observed = super::cancellation::observe_saturation(&policy); rows.push( @@ -269,6 +283,7 @@ mod probe { Some("--broker-escape-no-pid") => Mode::BrokerEscapeNoPid, Some("--broker-saturation") => Mode::BrokerSaturation, Some("--broker-private-stream") => Mode::BrokerPrivateStream, + Some("--broker-private-stream-mutation") => Mode::BrokerPrivateStreamMutation, Some("--landlock9") => Mode::Unix9, _ => panic!("unknown candidate mode"), }; @@ -380,6 +395,7 @@ mod probe { "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h", "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", @@ -411,7 +427,7 @@ mod probe { } let report = json!({"platform": std::env::consts::OS, "architecture": std::env::consts::ARCH, "checkout": std::env::var("GITHUB_SHA").ok(), "run_id": std::env::var("GITHUB_RUN_ID").ok(), - "candidate": candidate, "landlock9": mode == Mode::Unix9, "socket_broker": mode.broker(), "private_stream_probe": mode == Mode::BrokerPrivateStream, "cancellation_probe": mode == Mode::BrokerCancel, "mutation_probe": mode == Mode::BrokerMutation, "escape_probe": mode.escape(), "saturation_probe": mode == Mode::BrokerSaturation, "sources": sources, "source_sha256": format!("{:x}", hash.finalize()), + "candidate": candidate, "landlock9": mode == Mode::Unix9, "socket_broker": mode.broker(), "private_stream_probe": mode.private_stream(), "unix_mutation_probe": mode == Mode::BrokerPrivateStreamMutation, "cancellation_probe": mode == Mode::BrokerCancel, "mutation_probe": mode == Mode::BrokerMutation, "escape_probe": mode.escape(), "saturation_probe": mode == Mode::BrokerSaturation, "sources": sources, "source_sha256": format!("{:x}", hash.finalize()), "helper_sha256": format!("{:x}", Sha256::digest(std::fs::read(helper).unwrap())), "rows": rows, "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance."}); std::fs::write( diff --git a/crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs b/crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs index 969584d1e..9735dd9f7 100644 --- a/crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs +++ b/crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs @@ -3,6 +3,7 @@ use cyber_sandbox::plugin_policy::LinuxPolicy; use serde_json::{Value, json}; use std::collections::BTreeSet; use std::io::{BufRead, BufReader, Read, Write}; +use std::os::unix::net::UnixListener; use std::process::{Child, ChildStdin, Command, ExitStatus, Stdio}; use std::sync::mpsc::{self, Receiver, Sender}; use std::time::{Duration, Instant}; @@ -17,6 +18,7 @@ enum Message { enum Case { Cancellation, Mutation, + UnixMutation, Escape, Saturation, } @@ -25,6 +27,7 @@ impl Case { match self { Self::Cancellation => "cancel", Self::Mutation => "mutation", + Self::UnixMutation => "unix-mutation", Self::Escape => "escape", Self::Saturation => "saturation", } @@ -92,6 +95,7 @@ struct Trace { owner_exited_before_cleanup: Option, pressure: Option, pressure_cancelled: Option, + host_received: Option, } impl Trace { fn record(&mut self, message: Message) -> Result<(), String> { @@ -160,7 +164,7 @@ impl Trace { if matches!(case, Case::Escape) { return false; } - if matches!(case, Case::Mutation) { + if matches!(case, Case::Mutation | Case::UnixMutation) { let Some(tid) = self.pinned else { return false; }; @@ -202,12 +206,14 @@ impl Trace { json!({"ready":self.ready,"finished":self.finished,"cancelled_pid":self.cancelled, "pinned_tid":self.pinned,"started":self.started,"reaped":self.reaped,"audit":self.audit, "stdout_closed_before_cleanup":self.closed_before_cleanup,"owner_exited_before_cleanup":self.owner_exited_before_cleanup, - "pressure":self.pressure,"pressure_cancelled":self.pressure_cancelled,"cancelled_workers":self.cancelled_workers}) + "pressure":self.pressure,"pressure_cancelled":self.pressure_cancelled,"cancelled_workers":self.cancelled_workers, + "host_received_fixture":self.host_received}) } fn verify(&self, case: Case, released: bool, status: ExitStatus) { match case { Case::Cancellation => self.verify_cancel(released, status), Case::Mutation => self.verify_mutation(released, status), + Case::UnixMutation => self.verify_unix_mutation(released, status), Case::Escape => self.verify_escape(status), Case::Saturation => self.verify_pressure(released, status), } @@ -256,6 +262,33 @@ impl Trace { self.report() ); } + fn verify_unix_mutation(&self, released: bool, status: ExitStatus) { + assert!( + released, + "missing UNIX post-pin handshake: {}", + self.report() + ); + let finished = self + .finished + .as_ref() + .expect("missing UNIX mutation result"); + let correct = [ + "fd_replaced", + "address_changed", + "path_replaced", + "original_unlinked", + "result_ok", + "sent", + "private_roundtrip", + ] + .iter() + .all(|key| finished[key] == true); + assert!( + status.success() && correct && self.host_received == Some(false), + "private UNIX mutation escaped the pinned endpoint: {}", + self.report() + ); + } fn verify_escape(&self, status: ExitStatus) { assert_eq!( self.ready.as_ref().expect("missing descendant receipt")["controlled_stdin"], @@ -369,29 +402,51 @@ fn drive( } pub fn observe(policy: &LinuxPolicy<'_>) -> Value { - observe_case(policy, Case::Cancellation, true) + observe_case(policy, Case::Cancellation, true, None) } pub fn observe_mutation(policy: &LinuxPolicy<'_>) -> Value { - observe_case(policy, Case::Mutation, true) + observe_case(policy, Case::Mutation, true, None) +} +pub fn observe_unix_mutation(policy: &LinuxPolicy<'_>, listener: &UnixListener) -> Value { + observe_case(policy, Case::UnixMutation, true, Some(listener)) } pub fn observe_escape(policy: &LinuxPolicy<'_>, private_pid: bool) -> Value { - observe_case(policy, Case::Escape, private_pid) + observe_case(policy, Case::Escape, private_pid, None) } pub fn observe_saturation(policy: &LinuxPolicy<'_>) -> Value { - observe_case(policy, Case::Saturation, true) + observe_case(policy, Case::Saturation, true, None) } -fn observe_case(policy: &LinuxPolicy<'_>, case: Case, private_pid: bool) -> Value { - let args = [ +fn observe_case( + policy: &LinuxPolicy<'_>, + case: Case, + private_pid: bool, + listener: Option<&UnixListener>, +) -> Value { + let mut args = vec![ policy.target_args[0].clone(), policy.target_args[1].clone(), case.argument().into(), ]; + if matches!(case, Case::UnixMutation) { + args.push( + policy + .scratch + .join("mutation.sock") + .to_str() + .unwrap() + .into(), + ); + } let policy = LinuxPolicy { target_args: &args, shell: matches!(case, Case::Escape) || policy.shell, ..*policy }; let mut plan = policy.compose().unwrap(); + if matches!(case, Case::UnixMutation) { + plan.landlock + .push_str(&format!("U\t{}\n", policy.scratch.display())); + } if !private_pid { assert_eq!( plan.arguments @@ -462,6 +517,27 @@ fn observe_case(policy: &LinuxPolicy<'_>, case: Case, private_pid: bool) -> Valu "fixture protocol failed: {outcome:?} {errors:?}: {}", trace.report() ); + if let Some(listener) = listener { + trace.host_received = Some(host_receipt(listener)); + } trace.verify(case, handshakes == case.handshakes(), status); trace.report() } + +fn host_receipt(listener: &UnixListener) -> bool { + match listener.accept() { + Ok((mut stream, _)) => { + stream + .set_read_timeout(Some(Duration::from_secs(1))) + .unwrap(); + let mut token = [0; 12]; + stream.read_exact(&mut token).unwrap(); + assert_eq!(&token, b"fixture-only"); + true + } + Err(error) => { + assert_eq!(error.kind(), std::io::ErrorKind::WouldBlock); + false + } + } +} diff --git a/crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h b/crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h new file mode 100644 index 000000000..655c928cb --- /dev/null +++ b/crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h @@ -0,0 +1,71 @@ +/* Real post-pin pathname mutation; all endpoints are owned fixture sockets. */ +#ifdef __linux__ +#include +struct unix_mutation_call { int fd, result; struct sockaddr_un address; }; +static void *unix_mutation_connect(void *argument) { + struct unix_mutation_call *call = argument; + printf("{\"phase\":\"mutation-ready\",\"request_tid\":%ld}\n", syscall(SYS_gettid)); + fflush(stdout); + /* Full sockaddr_un size is the audit fixture's unique pause selector. */ + call->result = connect(call->fd, (struct sockaddr *)&call->address, sizeof(call->address)); + return NULL; +} +static int unix_mutation_probe(const char *host, const char *path) { + struct sockaddr_un address = { .sun_family = AF_UNIX }; + if (strlen(host) >= sizeof(address.sun_path) || strlen(path) >= sizeof(address.sun_path)) return 3; + int parent = syscall(SYS_pidfd_open, getppid(), 0); + int server = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); + int client = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (parent < 0 || server < 0 || client < 0) return 3; + strcpy(address.sun_path, path); + if (bind(server, (struct sockaddr *)&address, sizeof(address)) != 0 || listen(server, 1) != 0) return 3; + int identity = open(path, O_PATH | O_NOFOLLOW | O_CLOEXEC); + struct stat before, after, replacement; + if (identity < 0 || fstat(identity, &before) != 0 || !S_ISSOCK(before.st_mode)) return 3; + int fd = fcntl(client, F_DUPFD_CLOEXEC, 128); + int kept = fcntl(client, F_DUPFD_CLOEXEC, 129); + close(client); + if (fd < 0 || kept < 0) return 3; + struct unix_mutation_call call = { .fd = fd, .result = -1, .address = address }; + pthread_t thread; + if (pthread_create(&thread, NULL, unix_mutation_connect, &call) != 0) return 3; + if (getchar() != 'R') _exit(3); + int different = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (different < 0 || dup2(different, fd) != fd) _exit(3); + close(different); + memset(&call.address, 0, sizeof(call.address)); + call.address.sun_family = AF_UNIX; + strcpy(call.address.sun_path, host); + if (unlink(path) != 0 || symlink(host, path) != 0) _exit(3); + int path_replaced = lstat(path, &replacement) == 0 && S_ISLNK(replacement.st_mode) && + (before.st_dev != replacement.st_dev || before.st_ino != replacement.st_ino); + int original_unlinked = fstat(identity, &after) == 0 && before.st_dev == after.st_dev && + before.st_ino == after.st_ino && after.st_nlink == 0; + atomic_thread_fence(memory_order_seq_cst); + if (syscall(SYS_pidfd_send_signal, parent, SIGUSR2, NULL, 0) != 0 || + pthread_join(thread, NULL) != 0) _exit(3); + int domain = 0; + socklen_t length = sizeof(domain); + int fd_replaced = getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &domain, &length) == 0 && domain == AF_INET; + int sent = call.result == 0 && send(kept, "fixture-only", 12, MSG_NOSIGNAL) == 12; + int peer = accept4(server, NULL, NULL, SOCK_CLOEXEC | SOCK_NONBLOCK); + char token[12], ack = 0; + int roundtrip = sent && peer >= 0 && recv(peer, token, sizeof(token), MSG_DONTWAIT) == 12 && + memcmp(token, "fixture-only", 12) == 0 && send(peer, "A", 1, MSG_NOSIGNAL) == 1 && + recv(kept, &ack, 1, MSG_DONTWAIT) == 1 && ack == 'A'; + printf("{\"phase\":\"mutation-finished\",\"fd_replaced\":%s,\"address_changed\":%s," + "\"path_replaced\":%s,\"original_unlinked\":%s,\"result_ok\":%s,\"sent\":%s,\"private_roundtrip\":%s}\n", + fd_replaced ? "true" : "false", strcmp(call.address.sun_path, host) == 0 ? "true" : "false", + path_replaced ? "true" : "false", original_unlinked ? "true" : "false", + call.result == 0 ? "true" : "false", sent ? "true" : "false", roundtrip ? "true" : "false"); + if (peer >= 0) close(peer); + close(parent); close(identity); close(fd); close(kept); close(server); unlink(path); + /* The owner verifies endpoint selection, including the deliberate host + delivery counterexample, after all fixture processes/pipes settle. */ + return 0; +} +#else +static int unix_mutation_probe(const char *host, const char *path) { + (void)host; (void)path; return 3; +} +#endif diff --git a/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c b/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c index fabc7c329..b9970818c 100644 --- a/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c +++ b/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c @@ -186,6 +186,7 @@ static int pair_probe(const struct sockaddr_un *address, socklen_t length, #include "plugin_socket_cancel.h" #include "plugin_socket_saturation.h" #include "plugin_socket_mutation.h" +#include "plugin_unix_mutation.h" #include "plugin_process_escape.h" int main(int argc, char **argv) { @@ -198,6 +199,7 @@ int main(int argc, char **argv) { if (argc == 4 && strcmp(argv[3], "mutation") == 0) return mutation_probe(); if (argc == 4 && strcmp(argv[3], "escape") == 0) return escape_probe(); if (argc == 4 && strcmp(argv[3], "saturation") == 0) return saturation_probe(); + if (argc == 5 && strcmp(argv[3], "unix-mutation") == 0) return unix_mutation_probe(argv[1], argv[4]); if (argc >= 4) { if (strcmp(argv[3], "pair") != 0) return 2; return pair_probe(&address, diff --git a/docs/goal-delivery.md b/docs/goal-delivery.md index 3a7d86412..774866df4 100644 --- a/docs/goal-delivery.md +++ b/docs/goal-delivery.md @@ -52,7 +52,8 @@ tree matches the reviewed/tested `e6fd3d2f` tree. The user approved continuing t [Linux broker direction](../openspec/changes/complete-plugin-hook-runtime/native-host-integration.md) with runtime kernel capability checks and full private IPC/network compatibility remaining required before activation. Continue on the single -`feat/plugin-native-host-admission` follow-up branch/PR, retaining its original +[draft #80](https://github.com/CyberdyneCorp/cybercode-cli/pull/80), branch +`feat/plugin-native-host-admission`, retaining its original tested sources on `evidence/plugin-native-host-pre-76-merge` across rebase. Native confinement foundations and regressions exist, but diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md index 6fba2fdfa..3ac3ed30c 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md @@ -86,8 +86,11 @@ report. The tested commits remain on `evidence/plugin-native-host-pre-76-merge` when the implementation branch is rebased onto the #76 squash merge. These original receipts are not relabeled as execution of the rebased head. -Still required before complete IPC/production acceptance: actual post-pin -pathname replacement in this broker, relative/alias forms, datagram/seqpacket and +The [real broker pathname replacement case](linux-private-stream-mutation.md) +now tests the post-pin race; its new hosted evidence is pending. + +Still required before complete IPC/production acceptance: verified post-pin +replacement, relative/alias forms, datagram/seqpacket and destination-bearing sends, ancillary FD/credential and peer-identity behavior, exact proxy endpoint ownership and network ceilings, full runtime IPC controls, immutable admission, generation quarantine and complete resource settlement. diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-mutation.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-mutation.md new file mode 100644 index 000000000..0e2181cb3 --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-mutation.md @@ -0,0 +1,48 @@ +# Real broker private-endpoint replacement case + +This extends the approved broker work and the +[private stream integration](linux-private-stream-integration.md). The standalone +endpoint prerequisite cannot prove that the real notification path retains its +endpoint handle. This case exercises that path with an actual blocked caller. +Production activation and the complete native/IPC requirements remain open. + +The target binds a private scratch stream server and retains an independent +O_PATH reference to its inode. A pthread reports its actual TID, then connects +using a full sockaddr_un and a client descriptor duplicated at a high slot. +The temporary helper's audit hook pauses after copying arguments, pinning the +exact thread's socket and pathname endpoint, and validating the notification. +The fixed-fixture driver releases mutation only after the ready TID matches the +real helper BPIN event. SIGUSR2 is masked before publishing that event. + +The target replaces the descriptor number with an IP socket, changes the address +buffer to the fixture-owned host endpoint, unlinks the original private pathname +and replaces it with a symlink to that host endpoint. It verifies a different +pathname inode and that the retained original inode is now unlinked. It signals +the paused helper through a pinned parent pidfd, then joins the caller thread. + +The positive case must complete through the original client object and original +private server, exchanging a token and acknowledgement through real sockets. +The unchanged host listener must receive no connection/token. Descriptor, +address and pathname changes, original-inode retention and successful syscall +completion must all be observed; refusal is not a passing result. + +The precise copied-helper control closes only the endpoint reference after the +pause. Its original socket and copied address remain pinned/owned. Re-resolving +that pathname must actually deliver the fixture token to the host listener, +with no private-server roundtrip. The driver records that real host receipt +after all fixture processes and pipes settle, then fails the named endpoint +assertion. An unrelated error, missing mutation or absence of actual host +delivery cannot satisfy the control. + +All endpoints are fixture-owned, and only the fixed fixture emits the audit +markers; this is not an authenticated production protocol. The shared owner keeps +its existing bounded readers, deadline and cleanup-before-assertion path. The +matrix adds four real mutation cases across read/write combinations, plus the +32 ordinary private-stream cases. Existing cancellation, IP mutation, escaped +descendant and saturation cases still exercise the changed shared driver. + +Local Rust example Clippy, portable C fixture syntax, Python/workflow syntax, +18 compiler-intercepted temporary source transformations, formatting/diff and +strict OpenSpec are required before push. These local checks do not compile the +Linux C branch or prove kernel behavior. Hosted x64/arm64 execution is pending. +No parent task is closed by this fixture or its source review. diff --git a/scripts/probes/plugin-native-entry/build_socket_candidate.py b/scripts/probes/plugin-native-entry/build_socket_candidate.py index b49baee6d..255bf08ae 100644 --- a/scripts/probes/plugin-native-entry/build_socket_candidate.py +++ b/scripts/probes/plugin-native-entry/build_socket_candidate.py @@ -11,9 +11,11 @@ assert mode in {"seccomp", "broker", "broker-no-bind", "broker-no-thread", "broker-audit", "broker-audit-no-cancel", "broker-audit-wrong-cap", "broker-mutation", "broker-mutation-no-pin", "broker-mutation-no-copy", "broker-mutation-continue", "broker-private-stream", "broker-private-stream-no-makesock", "broker-private-stream-no-refer", + "broker-private-stream-mutation", "broker-private-stream-mutation-no-endpoint", "landlock9", "landlock9-no-resolve"} unix9 = mode.startswith("landlock9") private_stream = mode.startswith("broker-private-stream") +unix_mutation = mode.startswith("broker-private-stream-mutation") with tempfile.TemporaryDirectory(prefix="cyber-socket-candidate-") as temporary: target = Path(temporary) for name in ["linux_plugin_exec.c", "linux_filter.h", "linux_initial_exec.h"]: @@ -49,7 +51,7 @@ before = "syscall(SYS_pidfd_open, request->pid, PIDFD_THREAD)" assert text.count(before) == 1 broker.write_text(text.replace(before, "syscall(SYS_pidfd_open, request->pid, 0)")) - if mode.startswith("broker-audit") or mode.startswith("broker-mutation"): + if mode.startswith("broker-audit") or mode.startswith("broker-mutation") or unix_mutation: # Fixture-only receipts from the actual worker owner. Logging is # injected solely into this temporary copy, never the base helper. broker = target / "socket_broker.h" @@ -65,8 +67,14 @@ assert text.count(before) == 1 text = text.replace(before, ' fprintf(stderr, "BREAP %d\\n", (int)job->pid);\n' + before) broker.write_text(text) - if mode.startswith("broker-mutation"): + if mode.startswith("broker-mutation") or unix_mutation: shutil.copyfile(Path(__file__).with_name("linux_socket_broker_mutation.h"), target / "socket_mutation.h") + if unix_mutation: + hook = target / "socket_mutation.h" + text = hook.read_text() + before = ' if (request->data.nr != SYS_bind || request->data.args[2] != sizeof(struct sockaddr_storage)) return 0;' + assert text.count(before) == 1 + hook.write_text(text.replace(before, ' if (request->data.nr != SYS_connect || request->data.args[2] != sizeof(struct sockaddr_un)) return 0;')) broker = target / "socket_broker.h" text = broker.read_text() before = "static void broker_tick(int signal_number)" @@ -75,7 +83,15 @@ before = " call->socket = socket;\n return 0;" assert text.count(before) == 1 mutation = ''' int mutated = broker_mutation_pause(request); - if (mutated < 0) { close(socket); return EIO; } + if (mutated < 0) { + if (call->endpoint >= 0) close(call->endpoint); + close(socket); return EIO; + } +''' + if mode == "broker-private-stream-mutation-no-endpoint": + mutation += ''' if (mutated && call->endpoint >= 0) { + close(call->endpoint); call->endpoint = -1; + } ''' if mode == "broker-mutation-no-pin": mutation += ''' if (mutated) { From b227c83329acf58b50a1239b937e25fc68475a5f Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 11:49:10 -0400 Subject: [PATCH 08/21] feat(plugins): bind relative private sockets to caller cwd --- .github/workflows/plugin-linux-ipc.yml | 29 + .../examples/plugin_unix_socket_probe.rs | 64 +- .../tests/fixtures/plugin_unix_relative.h | 39 + .../tests/fixtures/plugin_unix_socket.c | 15 +- .../linux-private-relative-paths.md | 51 + .../linux-private-stream-integration.md | 4 +- .../linux-private-stream-mutation.md | 24 +- .../build_socket_candidate.py | 14 + ...ux-ipc-broker-private-stream-mutation.json | 921 ++++++++++++++++++ .../arm64/private-stream-no-endpoint.log | 4 + ...ux-ipc-broker-private-stream-mutation.json | 921 ++++++++++++++++++ .../x64/private-stream-no-endpoint.log | 4 + .../plugin-native-entry/linux_socket_broker.h | 2 +- .../linux_socket_private_unix.h | 61 +- 14 files changed, 2120 insertions(+), 33 deletions(-) create mode 100644 crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h create mode 100644 openspec/changes/complete-plugin-hook-runtime/linux-private-relative-paths.md create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/arm64/linux-ipc-broker-private-stream-mutation.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/arm64/private-stream-no-endpoint.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/x64/linux-ipc-broker-private-stream-mutation.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/x64/private-stream-no-endpoint.log diff --git a/.github/workflows/plugin-linux-ipc.yml b/.github/workflows/plugin-linux-ipc.yml index 9e48d8697..cc8adc751 100644 --- a/.github/workflows/plugin-linux-ipc.yml +++ b/.github/workflows/plugin-linux-ipc.yml @@ -8,6 +8,7 @@ on: - crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h - crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h - crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h + - crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h - crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h - crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h - crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs @@ -111,6 +112,9 @@ jobs: for variant in broker-private-stream broker-private-stream-no-makesock broker-private-stream-no-refer broker-private-stream-mutation broker-private-stream-mutation-no-endpoint; do python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/$variant" "$variant" done + for variant in wrong-cwd no-beneath; do + python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/broker-private-stream-$variant" "broker-private-stream-$variant" + done for mode in mutation mutation-no-pin mutation-no-copy mutation-continue; do python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/socket-broker-$mode" "broker-$mode" done @@ -149,6 +153,29 @@ jobs: '"private_roundtrip":false', '"host_received_fixture":true', 'BPIN ']: assert token in text, text PY + - name: Reject wrong relative context and missing scratch traversal boundary + shell: bash + run: | + set -euo pipefail + for control in wrong-cwd no-beneath; do + log="$RUNNER_TEMP/private-stream-$control.log" + if target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/broker-private-stream-$control" "$RUNNER_TEMP/linux-ipc-private-$control.json" --broker-private-stream > "$log" 2>&1; then + echo "Private relative-path control unexpectedly passed: $control" >&2 + exit 1 + fi + python3 - "$log" "$control" <<'PY' + from pathlib import Path + import sys + text = Path(sys.argv[1]).read_text() + if sys.argv[2] == 'wrong-cwd': + assert 'private relative stream exchange: relative_root_roundtrip' in text, text + assert '"scratch_unix_roundtrip":true' in text and '"relative_root_roundtrip":false' in text, text + else: + assert 'private relative path escaped scratch:' in text, text + for token in ['"host_received_fixture":true', '"relative_escape_connected":true', '"relative_escape_sent":true']: + assert token in text, text + PY + done - name: Reject missing private socket creation and file-move compatibility guards shell: bash run: | @@ -389,6 +416,8 @@ jobs: ${{ runner.temp }}/broker-private-stream-no-makesock.log ${{ runner.temp }}/broker-private-stream-no-refer.log ${{ runner.temp }}/private-stream-no-endpoint.log + ${{ runner.temp }}/private-stream-wrong-cwd.log + ${{ runner.temp }}/private-stream-no-beneath.log ${{ runner.temp }}/broker-no-thread.log ${{ runner.temp }}/broker-no-cancel.log ${{ runner.temp }}/broker-mutation-*.log diff --git a/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs b/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs index dca56e69a..c0925efec 100644 --- a/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs +++ b/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs @@ -41,10 +41,13 @@ mod probe { fn receipt(listener: &UnixListener, observed: &Value) -> bool { assert_eq!(observed["started"], true); + let connected = + observed["connected"] == true || observed["relative_escape_connected"] == true; + let sent = observed["sent"] == true || observed["relative_escape_sent"] == true; match listener.accept() { Ok((mut stream, _)) => { - assert_eq!(observed["connected"], true); - assert_eq!(observed["sent"], true); + assert!(connected); + assert!(sent); stream .set_read_timeout(Some(Duration::from_secs(1))) .unwrap(); @@ -55,8 +58,8 @@ mod probe { } Err(error) => { assert_eq!(error.kind(), std::io::ErrorKind::WouldBlock); - assert_eq!(observed["connected"], false); - assert_eq!(observed["sent"], false); + assert!(!connected); + assert!(!sent); false } } @@ -154,6 +157,10 @@ mod probe { ..policy }; let observed = observe(&pair_policy, mode); + let delivered = receipt(listener, &observed); + if mode.private_stream() { + check_private_stream(&observed, &pair_policy, label, delivered); + } assert_eq!( observed["project_read"], pair_policy.fs_read, "native pair read control: {observed}" @@ -170,26 +177,44 @@ mod probe { ); } check_pair_support(&observed, mode); - if mode.private_stream() { - assert_eq!( - observed["regular_reparent"], pair_policy.fs_write, - "private IPC layer changed ordinary file moves: {label} read={} write={}: {observed}", - pair_policy.fs_read, pair_policy.fs_write, - ); - if label == "public" && pair_policy.fs_write { - assert_eq!( - observed["cross_mount_alias_errno"], - libc::EXDEV, - "a host socket alias crossed the private scratch mount: {observed}" - ); - } - } - let delivered = receipt(listener, &observed); assert!(!delivered, "pair reached host: {observed}"); json!({"socket": label, "fs_read": pair_policy.fs_read, "fs_write": pair_policy.fs_write, "shell": false, "mode": "pair", "host_received_fixture": delivered, "observed": observed}) } + fn check_private_stream( + observed: &Value, + policy: &LinuxPolicy<'_>, + label: &str, + delivered: bool, + ) { + assert!( + !delivered, + "private relative path escaped scratch: {}", + json!({"host_received_fixture":delivered,"observed":observed}) + ); + for key in ["relative_root_roundtrip", "relative_parent_roundtrip"] { + assert_eq!( + observed[key], true, + "private relative stream exchange: {key}: {observed}" + ); + } + assert_eq!(observed["relative_escape_connected"], false); + assert_eq!(observed["relative_escape_sent"], false); + assert_eq!( + observed["regular_reparent"], policy.fs_write, + "private IPC layer changed ordinary file moves: {label} read={} write={}: {observed}", + policy.fs_read, policy.fs_write, + ); + if label == "public" && policy.fs_write { + assert_eq!( + observed["cross_mount_alias_errno"], + libc::EXDEV, + "a host socket alias crossed the private scratch mount: {observed}" + ); + } + } + fn check_pair_support(observed: &Value, mode: Mode) { for key in ["datagram_pair", "seqpacket_pair"] { assert_eq!( @@ -396,6 +421,7 @@ mod probe { "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", "crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h", "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", diff --git a/crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h b/crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h new file mode 100644 index 000000000..cd3633a0f --- /dev/null +++ b/crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h @@ -0,0 +1,39 @@ +/* Relative names must resolve from the guest's CWD, never the broker's. */ +struct relative_result { int root, parent, escape_connected, escape_sent; }; +#ifdef __linux__ +static struct relative_result relative_probe(const char *scratch_socket) { + struct relative_result result = {0}; + if (scratch_socket == NULL || strlen(scratch_socket) >= 512) return result; + char scratch[512]; + strcpy(scratch, scratch_socket); + char *last = strrchr(scratch, '/'); + if (last == NULL) return result; + *last = '\0'; + int previous = open(".", O_PATH | O_DIRECTORY | O_CLOEXEC); + int root = open(scratch, O_PATH | O_DIRECTORY | O_CLOEXEC); + int outside = -1; + if (previous < 0 || root < 0 || fchdir(root) != 0) goto done; + result.root = local_exchange(AF_UNIX, "relative.sock", -1); + if (mkdir("relative-dir", 0700) != 0 || chdir("relative-dir") != 0) goto done; + result.parent = local_exchange(AF_UNIX, "../parent.sock", -1); + if (fchdir(root) != 0) _exit(3); + struct sockaddr_un address = { .sun_family = AF_UNIX }; + strcpy(address.sun_path, "../host.sock"); + outside = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + result.escape_connected = outside >= 0 && connect(outside, (struct sockaddr *)&address, + (socklen_t)(offsetof(struct sockaddr_un, sun_path) + strlen(address.sun_path) + 1)) == 0; + result.escape_sent = result.escape_connected && send(outside, "fixture-only", 12, MSG_NOSIGNAL) == 12; +done: + if (outside >= 0) close(outside); + if (root >= 0) { unlinkat(root, "relative-dir", AT_REMOVEDIR); close(root); } + if (previous >= 0) { + if (fchdir(previous) != 0) _exit(3); + close(previous); + } + return result; +} +#else +static struct relative_result relative_probe(const char *scratch_socket) { + (void)scratch_socket; return (struct relative_result){0}; +} +#endif diff --git a/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c b/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c index b9970818c..f84949045 100644 --- a/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c +++ b/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c @@ -48,9 +48,10 @@ static int local_exchange(int family, const char *path, int server) { client = socket(family, SOCK_STREAM, 0); if (client < 0 || connect(client, (struct sockaddr *)&storage, length) != 0) goto done; peer = accept(server, NULL, NULL); - char token[12]; + char token[12], ack = 0; ok = peer >= 0 && send(client, "fixture-only", 12, MSG_NOSIGNAL) == 12 && - recv(peer, token, sizeof(token), MSG_WAITALL) == 12 && memcmp(token, "fixture-only", 12) == 0; + recv(peer, token, sizeof(token), MSG_WAITALL) == 12 && memcmp(token, "fixture-only", 12) == 0 && + send(peer, "A", 1, MSG_NOSIGNAL) == 1 && recv(client, &ack, 1, MSG_WAITALL) == 1 && ack == 'A'; done: if (peer >= 0) close(peer); if (client >= 0) close(client); @@ -59,6 +60,8 @@ static int local_exchange(int family, const char *path, int server) { return ok; } +#include "plugin_unix_relative.h" + #ifdef __linux__ struct thread_exchange { int descriptor; int roundtrip; }; static void *thread_exchange(void *argument) { @@ -157,6 +160,7 @@ static int pair_probe(const struct sockaddr_un *address, socklen_t length, int tcp = scratch_socket != NULL && local_exchange(AF_INET, NULL, -1); int thread_tcp = scratch_socket != NULL && thread_local_exchange(); int scratch_ipc = scratch_socket != NULL && local_exchange(AF_UNIX, scratch_socket, -1); + struct relative_result relative = relative_probe(scratch_socket); int moved = regular_reparent(data_path); int alias_error = 0; if (scratch_socket != NULL) { @@ -171,7 +175,8 @@ static int pair_probe(const struct sockaddr_un *address, socklen_t length, "\"pair_bind\":%s,\"pair_listen\":%s,\"pair_sendto\":%s,\"pair_sendmsg\":%s," "\"datagram_pair\":%s,\"seqpacket_pair\":%s,\"landlock_abi\":%d," "\"tcp_roundtrip\":%s,\"thread_tcp_roundtrip\":%s,\"scratch_unix_roundtrip\":%s,\"regular_reparent\":%s," - "\"cross_mount_alias_errno\":%d}\n", + "\"cross_mount_alias_errno\":%d,\"relative_root_roundtrip\":%s,\"relative_parent_roundtrip\":%s," + "\"relative_escape_connected\":%s,\"relative_escape_sent\":%s}\n", (connected || reconnected) ? "true" : "false", sent ? "true" : "false", readable ? "true" : "false", roundtrip ? "true" : "false", disconnected ? "true" : "false", reconnected ? "true" : "false", @@ -179,7 +184,9 @@ static int pair_probe(const struct sockaddr_un *address, socklen_t length, sent_to ? "true" : "false", sent_message ? "true" : "false", datagram ? "true" : "false", sequence ? "true" : "false", abi(), tcp ? "true" : "false", thread_tcp ? "true" : "false", scratch_ipc ? "true" : "false", - moved ? "true" : "false", alias_error); + moved ? "true" : "false", alias_error, + relative.root ? "true" : "false", relative.parent ? "true" : "false", + relative.escape_connected ? "true" : "false", relative.escape_sent ? "true" : "false"); return 0; } diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-relative-paths.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-relative-paths.md new file mode 100644 index 000000000..3c8724f81 --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-relative-paths.md @@ -0,0 +1,51 @@ +# Caller-bound relative private UNIX paths + +The private-stream candidate now resolves relative names using the actual +notifying thread's working directory. This extends the approved broker scope; +it is not production admission or complete pathname/IPC acceptance. + +The broker opens the thread's procfs CWD as an owned directory handle, reads that +handle's kernel pathname and matches it to a beneath-root directory open in the +protected scratch tree. It compares directory type, inode, device and mount ID +from handle-based [statx](https://man7.org/linux/man-pages/man2/statx.2.html). +A missing identity field, mismatch, replacement or outside-scratch context is +refused. A caller-supplied string or the broker's own CWD cannot supply authority. + +The relative name is combined with that verified scratch-relative context and +opened with RESOLVE_BENEATH, NO_MAGICLINKS and NO_SYMLINKS from the pinned scratch +root. Parent components that remain inside scratch work; traversal above the +scratch root does not. The socket endpoint is pinned and type-checked before +the final notification check and worker operation. Temporary context handles +close before worker startup; the owned endpoint handle remains through connect. +Existing fresh-root, separate-mount, protected-ancestry and proxy-origin +obligations are unchanged. + +The native fixture changes its CWD independently of the broker, then requires +real token/acknowledgement exchange from the scratch root and from a nested CWD +using `../parent.sock`. It also attempts `../host.sock`, a real fixture-owned host +endpoint outside scratch. The owner records actual listener delivery before +asserting denial, instead of relying only on the target's reported errno. +The fixture restores its original directory handle before subsequent checks. + +Two precise temporary controls use the broker's CWD or omit only the final +beneath-root lookup constraint. The wrong-CWD control must fail relative exchange +while absolute scratch exchange still works. The missing-beneath control must +actually connect and deliver the fixture token to the owned host listener before +failing the named escape assertion. Startup refusal or an unrelated failure does +not satisfy either counterexample. Existing mutation and compatibility controls +remain in the workflow. + +The diagnostic verifier groups private-stream assertions in a separate helper; +all assertions remain. The Rust example passes the repository's Clippy complexity +limit after this extraction. The cognitive-complexity skill has no Rust analyzer, +so the project-native Clippy gate supplies the Rust measurement. + +Local checks cover Rust example Clippy, portable C fixture syntax excluding Linux +branches, Python/workflow syntax, 20 compiler-intercepted builder transformations +and formatting/diff. Actual Linux C compilation, mount/CWD semantics and both +controls require hosted x64/arm64 execution; no new native result is claimed yet. + +Relative names beginning from outside scratch, supported symlink/alias forms, +datagram/seqpacket and destination-bearing sends, ancillary/peer-credential +behavior, proxy/network intersections and production ownership remain required. +The full native proof/activation gate and task N2 remain open. diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md index 3ac3ed30c..309bb7b71 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md @@ -87,7 +87,9 @@ when the implementation branch is rebased onto the #76 squash merge. These original receipts are not relabeled as execution of the rebased head. The [real broker pathname replacement case](linux-private-stream-mutation.md) -now tests the post-pin race; its new hosted evidence is pending. +has source-bound passing x64/arm64 evidence. The +[caller-bound relative-path extension](linux-private-relative-paths.md) now adds +scratch-relative handling; its native evidence remains pending. Still required before complete IPC/production acceptance: verified post-pin replacement, relative/alias forms, datagram/seqpacket and diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-mutation.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-mutation.md index 0e2181cb3..8ce6fe0fd 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-mutation.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-mutation.md @@ -43,6 +43,24 @@ descendant and saturation cases still exercise the changed shared driver. Local Rust example Clippy, portable C fixture syntax, Python/workflow syntax, 18 compiler-intercepted temporary source transformations, formatting/diff and -strict OpenSpec are required before push. These local checks do not compile the -Linux C branch or prove kernel behavior. Hosted x64/arm64 execution is pending. -No parent task is closed by this fixture or its source review. +strict OpenSpec passed before push. These local checks do not compile the +Linux C branch or prove kernel behavior. The native result below supplies that +case-specific evidence. No parent task is closed by this fixture or source review. + +## Native result for 9bb0fb60 + +[Run 41076338785](https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41076338785) +passed on Linux x64 and arm64. Each report contains 36 rows, including four +actual mutation cases across the read/write combinations. All observe matching +ready/pinned TIDs, descriptor/address/path replacement, the original inode now +unlinked, successful syscall completion and private token/ack exchange, with no +host receipt. The exact missing-endpoint control instead records actual host +delivery, successful send and no private roundtrip after the same mutations. + +Original reports and control logs are retained under +`scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/{x64,arm64}`. +They bind tested merge `0aed910c2e00671ecf2dd3d88fb98b028fdba546` and source manifest +SHA-256 `a59ac3e0c8fed62905517f9ce468b13810f8f6d79955de4b902ee4f04db7b643`. +The manifest was independently recomputed from that exact tree, which was also +verified equal to branch head `9bb0fb6040af2b9f0a0e3767148a2c889afd9c73`. +These receipts do not establish later relative-path handling or full IPC support. diff --git a/scripts/probes/plugin-native-entry/build_socket_candidate.py b/scripts/probes/plugin-native-entry/build_socket_candidate.py index 255bf08ae..572bb6120 100644 --- a/scripts/probes/plugin-native-entry/build_socket_candidate.py +++ b/scripts/probes/plugin-native-entry/build_socket_candidate.py @@ -12,6 +12,7 @@ "broker-mutation", "broker-mutation-no-pin", "broker-mutation-no-copy", "broker-mutation-continue", "broker-private-stream", "broker-private-stream-no-makesock", "broker-private-stream-no-refer", "broker-private-stream-mutation", "broker-private-stream-mutation-no-endpoint", + "broker-private-stream-wrong-cwd", "broker-private-stream-no-beneath", "landlock9", "landlock9-no-resolve"} unix9 = mode.startswith("landlock9") private_stream = mode.startswith("broker-private-stream") @@ -39,6 +40,19 @@ before = ' if (result == 0) result = add_path(ruleset, "/", LANDLOCK_ACCESS_FS_REFER);' assert text.count(before) == 1 header.write_text(text.replace(before, " /* Missing compatibility grant: REFER remains denied. */")) + if mode == "broker-private-stream-wrong-cwd": + header = target / "socket_private_unix.h" + text = header.read_text() + before = ' snprintf(proc, sizeof(proc), "/proc/%u/cwd", tid);' + assert text.count(before) == 1 + header.write_text(text.replace(before, ' tid = (unsigned int)getpid(); /* Wrong-context control. */\n' + before)) + if mode == "broker-private-stream-no-beneath": + header = target / "socket_private_unix.h" + text = header.read_text() + before = ''' struct open_how how = { .flags = O_PATH | O_CLOEXEC, + .resolve = RESOLVE_BENEATH | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS };''' + assert text.count(before) == 1 + header.write_text(text.replace(before, before.replace('RESOLVE_BENEATH | ', ''))) if mode == "broker-audit-wrong-cap": broker = target / "socket_broker.h" text = broker.read_text() diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/arm64/linux-ipc-broker-private-stream-mutation.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/arm64/linux-ipc-broker-private-stream-mutation.json new file mode 100644 index 000000000..ab639bbe7 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/arm64/linux-ipc-broker-private-stream-mutation.json @@ -0,0 +1,921 @@ +{ + "platform": "linux", + "architecture": "aarch64", + "checkout": "0aed910c2e00671ecf2dd3d88fb98b028fdba546", + "run_id": "41076338785", + "candidate": true, + "landlock9": false, + "socket_broker": true, + "private_stream_probe": true, + "unix_mutation_probe": true, + "cancellation_probe": false, + "mutation_probe": false, + "escape_probe": null, + "saturation_probe": false, + "sources": [ + "crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", + "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", + "crates/cyber-sandbox/src/plugin_policy.rs", + "crates/cyber-sandbox/src/plugin_policy/linux.rs", + "crates/cyber-sandbox/native/linux_plugin_exec.c", + "crates/cyber-sandbox/native/linux_filter.h", + "crates/cyber-sandbox/native/linux_initial_exec.h", + "crates/cyber-sandbox/src/native_exec.rs", + "crates/cyber-sandbox/src/bin/cyber-sandbox-exec.rs", + "crates/cyber-sandbox/build.rs", + "crates/cyber-sandbox/Cargo.toml", + "Cargo.lock", + ".github/workflows/plugin-linux-ipc.yml", + "scripts/probes/plugin-native-entry/linux_socket_candidate.h", + "scripts/probes/plugin-native-entry/linux_socket_broker.h", + "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", + "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", + "scripts/probes/plugin-native-entry/linux_unix9_policy.h", + "scripts/probes/plugin-native-entry/build_socket_candidate.py" + ], + "source_sha256": "a59ac3e0c8fed62905517f9ce468b13810f8f6d79955de4b902ee4f04db7b643", + "helper_sha256": "caad0757d3e2c57f457c483d440ded657a81f99495982a2a4f923c4d0a2c7116", + "rows": [ + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "mode": "unix-mutation", + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "observed": { + "ready": { + "phase": "mutation-ready", + "request_tid": 4 + }, + "finished": { + "phase": "mutation-finished", + "fd_replaced": true, + "address_changed": true, + "path_replaced": true, + "original_unlinked": true, + "result_ok": true, + "sent": true, + "private_roundtrip": true + }, + "cancelled_pid": null, + "pinned_tid": 4, + "started": [ + 5 + ], + "reaped": [ + 5 + ], + "audit": [ + "BPIN 4", + "BSTART 5", + "BREAP 5" + ], + "stdout_closed_before_cleanup": null, + "owner_exited_before_cleanup": null, + "pressure": null, + "pressure_cancelled": null, + "cancelled_workers": [], + "host_received_fixture": false + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "mode": "unix-mutation", + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "observed": { + "ready": { + "phase": "mutation-ready", + "request_tid": 4 + }, + "finished": { + "phase": "mutation-finished", + "fd_replaced": true, + "address_changed": true, + "path_replaced": true, + "original_unlinked": true, + "result_ok": true, + "sent": true, + "private_roundtrip": true + }, + "cancelled_pid": null, + "pinned_tid": 4, + "started": [ + 5 + ], + "reaped": [ + 5 + ], + "audit": [ + "BPIN 4", + "BSTART 5", + "BREAP 5" + ], + "stdout_closed_before_cleanup": null, + "owner_exited_before_cleanup": null, + "pressure": null, + "pressure_cancelled": null, + "cancelled_workers": [], + "host_received_fixture": false + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "mode": "unix-mutation", + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "observed": { + "ready": { + "phase": "mutation-ready", + "request_tid": 4 + }, + "finished": { + "phase": "mutation-finished", + "fd_replaced": true, + "address_changed": true, + "path_replaced": true, + "original_unlinked": true, + "result_ok": true, + "sent": true, + "private_roundtrip": true + }, + "cancelled_pid": null, + "pinned_tid": 4, + "started": [ + 5 + ], + "reaped": [ + 5 + ], + "audit": [ + "BPIN 4", + "BSTART 5", + "BREAP 5" + ], + "stdout_closed_before_cleanup": null, + "owner_exited_before_cleanup": null, + "pressure": null, + "pressure_cancelled": null, + "cancelled_workers": [], + "host_received_fixture": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "mode": "unix-mutation", + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "observed": { + "ready": { + "phase": "mutation-ready", + "request_tid": 4 + }, + "finished": { + "phase": "mutation-finished", + "fd_replaced": true, + "address_changed": true, + "path_replaced": true, + "original_unlinked": true, + "result_ok": true, + "sent": true, + "private_roundtrip": true + }, + "cancelled_pid": null, + "pinned_tid": 4, + "started": [ + 5 + ], + "reaped": [ + 5 + ], + "audit": [ + "BPIN 4", + "BSTART 5", + "BREAP 5" + ], + "stdout_closed_before_cleanup": null, + "owner_exited_before_cleanup": null, + "pressure": null, + "pressure_cancelled": null, + "cancelled_workers": [], + "host_received_fixture": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + } + ], + "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/arm64/private-stream-no-endpoint.log b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/arm64/private-stream-no-endpoint.log new file mode 100644 index 000000000..804fb4815 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/arm64/private-stream-no-endpoint.log @@ -0,0 +1,4 @@ + +thread 'main' (8423) panicked at crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs:286:9: +private UNIX mutation escaped the pinned endpoint: {"ready":{"phase":"mutation-ready","request_tid":4},"finished":{"phase":"mutation-finished","fd_replaced":true,"address_changed":true,"path_replaced":true,"original_unlinked":true,"result_ok":true,"sent":true,"private_roundtrip":false},"cancelled_pid":null,"pinned_tid":4,"started":[5],"reaped":[5],"audit":["BPIN 4","BSTART 5","BREAP 5"],"stdout_closed_before_cleanup":null,"owner_exited_before_cleanup":null,"pressure":null,"pressure_cancelled":null,"cancelled_workers":[],"host_received_fixture":true} +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/x64/linux-ipc-broker-private-stream-mutation.json b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/x64/linux-ipc-broker-private-stream-mutation.json new file mode 100644 index 000000000..79412d4db --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/x64/linux-ipc-broker-private-stream-mutation.json @@ -0,0 +1,921 @@ +{ + "platform": "linux", + "architecture": "x86_64", + "checkout": "0aed910c2e00671ecf2dd3d88fb98b028fdba546", + "run_id": "41076338785", + "candidate": true, + "landlock9": false, + "socket_broker": true, + "private_stream_probe": true, + "unix_mutation_probe": true, + "cancellation_probe": false, + "mutation_probe": false, + "escape_probe": null, + "saturation_probe": false, + "sources": [ + "crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", + "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", + "crates/cyber-sandbox/src/plugin_policy.rs", + "crates/cyber-sandbox/src/plugin_policy/linux.rs", + "crates/cyber-sandbox/native/linux_plugin_exec.c", + "crates/cyber-sandbox/native/linux_filter.h", + "crates/cyber-sandbox/native/linux_initial_exec.h", + "crates/cyber-sandbox/src/native_exec.rs", + "crates/cyber-sandbox/src/bin/cyber-sandbox-exec.rs", + "crates/cyber-sandbox/build.rs", + "crates/cyber-sandbox/Cargo.toml", + "Cargo.lock", + ".github/workflows/plugin-linux-ipc.yml", + "scripts/probes/plugin-native-entry/linux_socket_candidate.h", + "scripts/probes/plugin-native-entry/linux_socket_broker.h", + "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", + "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", + "scripts/probes/plugin-native-entry/linux_unix9_policy.h", + "scripts/probes/plugin-native-entry/build_socket_candidate.py" + ], + "source_sha256": "a59ac3e0c8fed62905517f9ce468b13810f8f6d79955de4b902ee4f04db7b643", + "helper_sha256": "b2bfe623e0dca611d09382997b1ddb819e6c4ffb8f81e714c9f540283db5c5d9", + "rows": [ + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "mode": "unix-mutation", + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "observed": { + "ready": { + "phase": "mutation-ready", + "request_tid": 4 + }, + "finished": { + "phase": "mutation-finished", + "fd_replaced": true, + "address_changed": true, + "path_replaced": true, + "original_unlinked": true, + "result_ok": true, + "sent": true, + "private_roundtrip": true + }, + "cancelled_pid": null, + "pinned_tid": 4, + "started": [ + 5 + ], + "reaped": [ + 5 + ], + "audit": [ + "BPIN 4", + "BSTART 5", + "BREAP 5" + ], + "stdout_closed_before_cleanup": null, + "owner_exited_before_cleanup": null, + "pressure": null, + "pressure_cancelled": null, + "cancelled_workers": [], + "host_received_fixture": false + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "mode": "unix-mutation", + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "observed": { + "ready": { + "phase": "mutation-ready", + "request_tid": 4 + }, + "finished": { + "phase": "mutation-finished", + "fd_replaced": true, + "address_changed": true, + "path_replaced": true, + "original_unlinked": true, + "result_ok": true, + "sent": true, + "private_roundtrip": true + }, + "cancelled_pid": null, + "pinned_tid": 4, + "started": [ + 5 + ], + "reaped": [ + 5 + ], + "audit": [ + "BPIN 4", + "BSTART 5", + "BREAP 5" + ], + "stdout_closed_before_cleanup": null, + "owner_exited_before_cleanup": null, + "pressure": null, + "pressure_cancelled": null, + "cancelled_workers": [], + "host_received_fixture": false + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "mode": "unix-mutation", + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "observed": { + "ready": { + "phase": "mutation-ready", + "request_tid": 4 + }, + "finished": { + "phase": "mutation-finished", + "fd_replaced": true, + "address_changed": true, + "path_replaced": true, + "original_unlinked": true, + "result_ok": true, + "sent": true, + "private_roundtrip": true + }, + "cancelled_pid": null, + "pinned_tid": 4, + "started": [ + 5 + ], + "reaped": [ + 5 + ], + "audit": [ + "BPIN 4", + "BSTART 5", + "BREAP 5" + ], + "stdout_closed_before_cleanup": null, + "owner_exited_before_cleanup": null, + "pressure": null, + "pressure_cancelled": null, + "cancelled_workers": [], + "host_received_fixture": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "mode": "unix-mutation", + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "observed": { + "ready": { + "phase": "mutation-ready", + "request_tid": 4 + }, + "finished": { + "phase": "mutation-finished", + "fd_replaced": true, + "address_changed": true, + "path_replaced": true, + "original_unlinked": true, + "result_ok": true, + "sent": true, + "private_roundtrip": true + }, + "cancelled_pid": null, + "pinned_tid": 4, + "started": [ + 5 + ], + "reaped": [ + 5 + ], + "audit": [ + "BPIN 4", + "BSTART 5", + "BREAP 5" + ], + "stdout_closed_before_cleanup": null, + "owner_exited_before_cleanup": null, + "pressure": null, + "pressure_cancelled": null, + "cancelled_workers": [], + "host_received_fixture": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18 + } + } + ], + "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/x64/private-stream-no-endpoint.log b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/x64/private-stream-no-endpoint.log new file mode 100644 index 000000000..902fafb3e --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-stream-mutation-9bb0fb60/x64/private-stream-no-endpoint.log @@ -0,0 +1,4 @@ + +thread 'main' (8482) panicked at crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs:286:9: +private UNIX mutation escaped the pinned endpoint: {"ready":{"phase":"mutation-ready","request_tid":4},"finished":{"phase":"mutation-finished","fd_replaced":true,"address_changed":true,"path_replaced":true,"original_unlinked":true,"result_ok":true,"sent":true,"private_roundtrip":false},"cancelled_pid":null,"pinned_tid":4,"started":[5],"reaped":[5],"audit":["BPIN 4","BSTART 5","BREAP 5"],"stdout_closed_before_cleanup":null,"owner_exited_before_cleanup":null,"pressure":null,"pressure_cancelled":null,"cancelled_workers":[],"host_received_fixture":true} +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/linux_socket_broker.h b/scripts/probes/plugin-native-entry/linux_socket_broker.h index 80dbeadc4..29dff69ce 100644 --- a/scripts/probes/plugin-native-entry/linux_socket_broker.h +++ b/scripts/probes/plugin-native-entry/linux_socket_broker.h @@ -89,7 +89,7 @@ static int broker_copy(int listener, const struct seccomp_notif *request, error = EPERM; #ifdef CYBER_PRIVATE_UNIX_STREAM if (domain == AF_UNIX) { - error = private_endpoint(&call->address, call->length, &call->endpoint); + error = private_endpoint(&call->address, call->length, request->pid, &call->endpoint); if (error != 0) goto failed; } else #endif diff --git a/scripts/probes/plugin-native-entry/linux_socket_private_unix.h b/scripts/probes/plugin-native-entry/linux_socket_private_unix.h index d90fff1ed..1019f6ce1 100644 --- a/scripts/probes/plugin-native-entry/linux_socket_private_unix.h +++ b/scripts/probes/plugin-native-entry/linux_socket_private_unix.h @@ -81,9 +81,52 @@ static int private_make_sock(void) { return result; } +static int private_same_directory(int first, int second) { + struct statx a, b; + unsigned int mask = STATX_INO | STATX_MNT_ID | STATX_TYPE; + if (syscall(SYS_statx, first, "", AT_EMPTY_PATH, mask, &a) != 0 || + syscall(SYS_statx, second, "", AT_EMPTY_PATH, mask, &b) != 0) return 0; + return (a.stx_mask & mask) == mask && (b.stx_mask & mask) == mask && + S_ISDIR(a.stx_mode) && S_ISDIR(b.stx_mode) && a.stx_ino == b.stx_ino && + a.stx_dev_major == b.stx_dev_major && a.stx_dev_minor == b.stx_dev_minor && + a.stx_mnt_id == b.stx_mnt_id; +} + +/* Bind a relative name to the actual notifying thread's CWD. Only an attested + * directory inside the protected scratch mount may supply this context. */ +static int private_relative(unsigned int tid, const char *path, char *relative, size_t capacity) { + char proc[64], cwd_path[4097]; + snprintf(proc, sizeof(proc), "/proc/%u/cwd", tid); + int cwd = open(proc, O_PATH | O_DIRECTORY | O_CLOEXEC); + if (cwd < 0) return errno; + snprintf(proc, sizeof(proc), "/proc/self/fd/%d", cwd); + ssize_t count = readlink(proc, cwd_path, sizeof(cwd_path) - 1); + int error = count < 0 ? errno : ENAMETOOLONG; + if (count < 0 || (size_t)count >= sizeof(cwd_path) - 1) goto done; + cwd_path[count] = '\0'; + size_t prefix = strlen(private_path); + const char *within; + if (strcmp(cwd_path, private_path) == 0) within = "."; + else if (prefix < (size_t)count && strncmp(cwd_path, private_path, prefix) == 0 && + cwd_path[prefix] == '/') within = cwd_path + prefix + 1; + else { error = EPERM; goto done; } + struct open_how how = { .flags = O_PATH | O_DIRECTORY | O_CLOEXEC, + .resolve = RESOLVE_BENEATH | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS }; + int matched = syscall(SYS_openat2, private_root, within, &how, sizeof(how)); + if (matched < 0) { error = errno; goto done; } + int same = private_same_directory(cwd, matched); + close(matched); + if (!same) { error = EPERM; goto done; } + int size = snprintf(relative, capacity, "%s/%s", within, path); + error = size <= 0 || (size_t)size >= capacity ? ENAMETOOLONG : 0; +done: + close(cwd); + return error; +} + /* The real socket descriptor was already pinned for the exact notifying thread. * Return a pinned pathname endpoint, or -1 for a private abstract/UNSPEC address. */ -static int private_endpoint(struct sockaddr_storage *storage, socklen_t length, int *endpoint) { +static int private_endpoint(struct sockaddr_storage *storage, socklen_t length, unsigned int tid, int *endpoint) { *endpoint = -1; if (storage->ss_family == AF_UNSPEC) return 0; if (length <= offsetof(struct sockaddr_un, sun_path) || @@ -94,12 +137,20 @@ static int private_endpoint(struct sockaddr_storage *storage, socklen_t length, size_t count = length - offsetof(struct sockaddr_un, sun_path); memcpy(path, address->sun_path, count); path[count] = '\0'; - size_t prefix = strlen(private_path); - if (prefix >= strlen(path) || strncmp(path, private_path, prefix) != 0 || - path[prefix] != '/') return EPERM; + char relative[4096]; + const char *selected = relative; + if (path[0] == '/') { + size_t prefix = strlen(private_path); + if (prefix >= strlen(path) || strncmp(path, private_path, prefix) != 0 || + path[prefix] != '/') return EPERM; + selected = path + prefix + 1; + } else { + int error = private_relative(tid, path, relative, sizeof(relative)); + if (error != 0) return error; + } struct open_how how = { .flags = O_PATH | O_CLOEXEC, .resolve = RESOLVE_BENEATH | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS }; - int fd = syscall(SYS_openat2, private_root, path + prefix + 1, &how, sizeof(how)); + int fd = syscall(SYS_openat2, private_root, selected, &how, sizeof(how)); if (fd < 0) return errno; struct stat info; if (fstat(fd, &info) != 0 || !S_ISSOCK(info.st_mode)) { From 077fb62e04ac6bbdeaa66cbdf465dab12a7647cc Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 12:25:37 -0400 Subject: [PATCH 09/21] test(plugins): exercise runtime private UNIX streams --- .github/workflows/plugin-linux-ipc.yml | 19 +- .../linux-private-relative-paths.md | 23 +- .../linux-private-runtime-ipc.md | 38 + .../linux-private-stream-integration.md | 5 +- .../native-host-integration.md | 5 +- scripts/probes/plugin-confinement/fixture.cjs | 1 + scripts/probes/plugin-confinement/fixture.py | 40 + .../plugin-confinement/fixture_native.c | 51 ++ .../plugin-confinement/private_unix.cjs | 60 ++ scripts/probes/plugin-confinement/run.mts | 17 +- .../build_socket_candidate.py | 7 + .../linux-ipc-broker-private-stream.json | 818 ++++++++++++++++++ .../arm64/private-stream-no-beneath.log | 4 + .../arm64/private-stream-wrong-cwd.log | 6 + .../x64/linux-ipc-broker-private-stream.json | 818 ++++++++++++++++++ .../x64/private-stream-no-beneath.log | 4 + .../x64/private-stream-wrong-cwd.log | 6 + 17 files changed, 1912 insertions(+), 10 deletions(-) create mode 100644 openspec/changes/complete-plugin-hook-runtime/linux-private-runtime-ipc.md create mode 100644 scripts/probes/plugin-confinement/private_unix.cjs create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/arm64/linux-ipc-broker-private-stream.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/arm64/private-stream-no-beneath.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/arm64/private-stream-wrong-cwd.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/x64/linux-ipc-broker-private-stream.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/x64/private-stream-no-beneath.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/x64/private-stream-wrong-cwd.log diff --git a/.github/workflows/plugin-linux-ipc.yml b/.github/workflows/plugin-linux-ipc.yml index cc8adc751..243e89a2c 100644 --- a/.github/workflows/plugin-linux-ipc.yml +++ b/.github/workflows/plugin-linux-ipc.yml @@ -112,7 +112,7 @@ jobs: for variant in broker-private-stream broker-private-stream-no-makesock broker-private-stream-no-refer broker-private-stream-mutation broker-private-stream-mutation-no-endpoint; do python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/$variant" "$variant" done - for variant in wrong-cwd no-beneath; do + for variant in wrong-cwd no-beneath no-unix-create; do python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/broker-private-stream-$variant" "broker-private-stream-$variant" done for mode in mutation mutation-no-pin mutation-no-copy mutation-continue; do @@ -402,6 +402,22 @@ jobs: done done exit "$status" + - name: Reject missing runtime private pathname socket support + if: ${{ !cancelled() && steps.build.outcome == 'success' }} + shell: bash + run: | + set -euo pipefail + log="$RUNNER_TEMP/private-runtime-no-create.log" + if node --experimental-strip-types scripts/probes/plugin-confinement/run.mts --runtime python --python "$(command -v python3)" --initial-exec --packaged-helper "$RUNNER_TEMP/broker-private-stream-no-unix-create" --socket-broker --broker-private-stream --report "$RUNNER_TEMP/private-runtime-no-create.json" > "$log" 2>&1; then + echo 'Missing private socket creation unexpectedly passed runtime acceptance' >&2 + exit 1 + fi + python3 - "$log" <<'PY' + from pathlib import Path + import sys + text = Path(sys.argv[1]).read_text() + assert 'no-capabilities: private UNIX runtime exchange failed: [false,false]' in text, text + PY - name: Retain diagnostic observations if: always() uses: actions/upload-artifact@v4 @@ -418,6 +434,7 @@ jobs: ${{ runner.temp }}/private-stream-no-endpoint.log ${{ runner.temp }}/private-stream-wrong-cwd.log ${{ runner.temp }}/private-stream-no-beneath.log + ${{ runner.temp }}/private-runtime-no-create.log ${{ runner.temp }}/broker-no-thread.log ${{ runner.temp }}/broker-no-cancel.log ${{ runner.temp }}/broker-mutation-*.log diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-relative-paths.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-relative-paths.md index 3c8724f81..769884ab9 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-relative-paths.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-relative-paths.md @@ -43,7 +43,28 @@ so the project-native Clippy gate supplies the Rust measurement. Local checks cover Rust example Clippy, portable C fixture syntax excluding Linux branches, Python/workflow syntax, 20 compiler-intercepted builder transformations and formatting/diff. Actual Linux C compilation, mount/CWD semantics and both -controls require hosted x64/arm64 execution; no new native result is claimed yet. +controls require hosted x64/arm64 execution. The result below supplies that +evidence for the exact tested source. + +## Native result for b227c833 + +[Run 41084231069](https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41084231069) +passed on Linux x64 and arm64. Each architecture retains 32 cases: 16 host +endpoint denials and 16 pair cases. Each pair exchanges a token and acknowledgement +using both scratch-root relative and nested parent-relative names. Escape +attempts neither connect nor send; the fixture-owned host listener receives no +token. Independent read/write expectations remain enforced. + +The wrong-CWD control fails the named relative-root exchange while absolute +scratch exchange succeeds. The missing-beneath control actually delivers to the +owned host listener before failing the named escape assertion. Original reports +and both logs are retained under +`scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/{x64,arm64}`. +They bind tested merge `b719d619418f36f66f553c1582b09a99195c7ce5`, whose tree +equals head `b227c83329acf58b50a1239b937e25fc68475a5f`, and source manifest SHA-256 +`f53cfe901242e30b8fdcd3bab1a90ac62ff2f451722339f95052d7b378239cad`. +The manifest and tree equality were independently verified. These reports do +not cover the subsequent runtime API exchange extension. Relative names beginning from outside scratch, supported symlink/alias forms, datagram/seqpacket and destination-bearing sends, ancillary/peer-credential diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-runtime-ipc.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-runtime-ipc.md new file mode 100644 index 000000000..48964b044 --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-runtime-ipc.md @@ -0,0 +1,38 @@ +# Runtime private pathname IPC acceptance + +The private-stream candidate's startup matrix previously checked file, thread +and execution behavior without using each runtime's own pathname socket API. +This extension requires real token/acknowledgement exchanges over both absolute +and caller-CWD-relative scratch sockets. It implements part of task N2 under the +approved [native host direction](native-host-integration.md). + +Node, Bun and Deno use the existing untrusted CommonJS bootstrap and a shared +`node:net` fixture. Python uses its socket API; the native fixture uses direct +socket calls. Each binds a listener, connects a separate client, sends `T` and +requires `A` in response. The relative case changes and restores the runtime's +CWD, independently of the broker's CWD. Sockets are closed and owned pathname +listeners removed before restoring that context. Operations have time limits; +the outer harness retains its process deadline. + +Only `--broker-private-stream` enables these expectations. All nine rows per +runtime, including the first unconfined control and all eight read/write/shell +combinations, require `private_unix: [true, true]`. Original capability +assertions remain. The source manifest includes the new shared fixture. + +A temporary missing-support helper denies new UNIX socket creation while +retaining stream socketpairs and the rest of the candidate policy. The Python +matrix must pass its unconfined row, then fail specifically at +`no-capabilities: private UNIX runtime exchange failed: [false,false]`. +Startup refusal or an unrelated assertion cannot satisfy this control. + +Local unconfined component checks pass for Node, Python and the native exchange +functions, including CWD restoration and pathname cleanup. Portable C syntax, +TypeScript/JavaScript/Python syntax and workflow checks are available on macOS. +Bun and Deno are unavailable locally. Real Linux confinement and all five +runtime families require the hosted x64/arm64 workflow; those results remain +pending. No production launch path changes in this extension. + +Outside-root relative contexts, supported aliases, datagram/seqpacket, +destination-bearing sends, ancillary and peer identity behavior, proxy/network +intersections and production ownership remain required. N2–N7 and the full +goal stay open. diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md index 309bb7b71..2cf6bcc1f 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md @@ -89,7 +89,10 @@ original receipts are not relabeled as execution of the rebased head. The [real broker pathname replacement case](linux-private-stream-mutation.md) has source-bound passing x64/arm64 evidence. The [caller-bound relative-path extension](linux-private-relative-paths.md) now adds -scratch-relative handling; its native evidence remains pending. +scratch-relative handling with retained x64/arm64 evidence. The +[runtime API exchange extension](linux-private-runtime-ipc.md) adds acceptance +for each runtime's own private pathname socket operations; hosted results for +that extension remain pending. Still required before complete IPC/production acceptance: verified post-pin replacement, relative/alias forms, datagram/seqpacket and diff --git a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md index b73d57161..85d01b292 100644 --- a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md @@ -110,7 +110,10 @@ App's legacy launch path does not implement this sequence today. runtime controls and denied ambient access, not only refusal cases. The [endpoint identity prerequisite](linux-unix-endpoint-identity.md) tests the first pathname-object binding step; the [private stream candidate integration](linux-private-stream-integration.md) - applies that primitive in real connect notifications. Neither completes this task. + applies that primitive in real connect notifications. The + [runtime API exchange extension](linux-private-runtime-ipc.md) requires real + private pathname exchanges from each supported runtime. These increments do + not complete this task. - [ ] N3 Implement registry-owned generation admission and immutable resource binding with actual production startup, revocation and quarantine tests. - [ ] N4 Integrate the native launch owner and independently intersect all diff --git a/scripts/probes/plugin-confinement/fixture.cjs b/scripts/probes/plugin-confinement/fixture.cjs index 909766b24..872bde60a 100644 --- a/scripts/probes/plugin-confinement/fixture.cjs +++ b/scripts/probes/plugin-confinement/fixture.cjs @@ -135,6 +135,7 @@ async function inspect() { written_project_read: native.read(c.project_write), }; observations.project_rename = renameProject(); + if (c.private_stream) observations.private_unix = await require("./private_unix.cjs")(c.scratch); if (c.initial_exec) observations.filter_replacement_denied = native.replacementDenied(); if (c.platform === "linux" && c.kind === "bun") { observations.proc_root_reads = [native.read("/proc/self/root" + c.project_file), native.read("/proc/self/root" + c.private_file)]; diff --git a/scripts/probes/plugin-confinement/fixture.py b/scripts/probes/plugin-confinement/fixture.py index 768c40904..c2af2af1b 100644 --- a/scripts/probes/plugin-confinement/fixture.py +++ b/scripts/probes/plugin-confinement/fixture.py @@ -210,11 +210,51 @@ def inspect(): } observations["written_project_read"] = native_read(case["project_write"]) observations["project_rename"] = rename_project() + if case.get("private_stream"): + observations["private_unix"] = private_unix() if case["initial_exec"]: observations["filter_replacement_denied"] = filter_replacement_denied() print(json.dumps({"jsonrpc": "2.0", "id": request["id"], "result": observations}, sort_keys=True)) +def private_unix(): + import socket + + def exchange(endpoint): + bound = False + try: + with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as server: + server.settimeout(2) + server.bind(endpoint) + bound = True + server.listen(1) + with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client: + client.settimeout(2) + client.connect(endpoint) + peer, _ = server.accept() + with peer: + peer.settimeout(2) + client.sendall(b"T") + if peer.recv(1) != b"T": + return False + peer.sendall(b"A") + return client.recv(1) == b"A" + except OSError: + return False + finally: + if bound: + os.unlink(endpoint) + + absolute = exchange(os.path.join(case["scratch"], "a.sock")) + previous = os.open(".", os.O_RDONLY | os.O_DIRECTORY) + try: + os.chdir(case["scratch"]) + return [absolute, exchange("r.sock")] + finally: + os.fchdir(previous) + os.close(previous) + + if case["mode"] == "exec": self_exec() else: diff --git a/scripts/probes/plugin-confinement/fixture_native.c b/scripts/probes/plugin-confinement/fixture_native.c index 2563375fb..9c4e5e432 100644 --- a/scripts/probes/plugin-confinement/fixture_native.c +++ b/scripts/probes/plugin-confinement/fixture_native.c @@ -11,6 +11,9 @@ #include #include #include +#include +#include +#include #include #include #include "process_policy.h" @@ -78,6 +81,49 @@ static int joined(char *out, const char *directory, const char *name) { return size > 0 && size < PATH_MAX; } +static int private_stream_exchange(const char *path) { + struct sockaddr_un address = { .sun_family = AF_UNIX }; + if (strlen(path) >= sizeof(address.sun_path)) return 0; + strcpy(address.sun_path, path); + int server = socket(AF_UNIX, SOCK_STREAM, 0), client = -1, peer = -1; + int bound = 0, result = 0; + struct timeval timeout = { .tv_sec = 2 }; + if (server < 0 || setsockopt(server, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) != 0 || + bind(server, (struct sockaddr *)&address, sizeof(address)) != 0) goto done; + bound = 1; + if (listen(server, 1) != 0) goto done; + client = socket(AF_UNIX, SOCK_STREAM, 0); + if (client < 0 || setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) != 0 || + setsockopt(client, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) != 0 || + connect(client, (struct sockaddr *)&address, sizeof(address)) != 0) goto done; + peer = accept(server, NULL, NULL); + if (peer < 0 || setsockopt(peer, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) != 0) goto done; + char token = 0, ack = 0; + result = send(client, "T", 1, 0) == 1 && recv(peer, &token, 1, 0) == 1 && token == 'T' && + send(peer, "A", 1, 0) == 1 && recv(client, &ack, 1, 0) == 1 && ack == 'A'; +done: + if (peer >= 0) close(peer); + if (client >= 0) close(client); + if (server >= 0) close(server); + if (bound) unlink(path); + return result; +} + +static int private_stream_probe(const char *scratch, int result[2]) { + char absolute[PATH_MAX]; + if (!joined(absolute, scratch, "a.sock")) return 0; + result[0] = private_stream_exchange(absolute); + int previous = open(".", O_RDONLY | O_DIRECTORY); + if (previous < 0) return 0; + int restored = 1; + if (chdir(scratch) == 0) { + result[1] = private_stream_exchange("r.sock"); + restored = fchdir(previous) == 0; + } + close(previous); + return restored; +} + /* No untrusted shell strings: only fixed commands and separate fixture paths. */ static int child(char *const args[], char *output, size_t size) { int channel[2]; @@ -229,6 +275,10 @@ int main(int argc, char **argv) { snprintf(native_children, sizeof(native_children), "[%s,%s]", truth(cat_read == 0), truth(cat_secret == 0)); } int confined = strcmp(argv[13], "1") == 0; + const char *private_stream = getenv("CYBER_PROOF_PRIVATE_STREAM"); + int probe_ipc = private_stream != NULL && strcmp(private_stream, "1") == 0; + int ipc[2] = {0}; + if (probe_ipc && !private_stream_probe(scratch_dir, ipc)) return 2; printf("{\"jsonrpc\":\"2.0\",\"id\":\"native-proof\",\"result\":{\"stdio_tool\":true,\"package_read\":%s,\"scratch_write\":%s,\"scratch_read\":%s,", truth(native_read(package)), truth(scratch_write), truth(native_read(scratch))); printf("\"project_read\":%s,\"project_list\":%s,\"project_write\":%s,\"written_project_read\":%s,", @@ -254,6 +304,7 @@ int main(int argc, char **argv) { #ifdef __linux__ printf(",\"filter_replacement_denied\":%s", truth(proof_replacement_denied())); #endif + if (probe_ipc) printf(",\"private_unix\":[%s,%s]", truth(ipc[0]), truth(ipc[1])); puts("}}"); return 0; } diff --git a/scripts/probes/plugin-confinement/private_unix.cjs b/scripts/probes/plugin-confinement/private_unix.cjs new file mode 100644 index 000000000..173bdf2d8 --- /dev/null +++ b/scripts/probes/plugin-confinement/private_unix.cjs @@ -0,0 +1,60 @@ +// CJS is required by the same untrusted Node/Bun/Deno bootstrap fixture. +const net = require("node:net"); +const path = require("node:path"); + +function listen(server, endpoint) { + return new Promise((resolve, reject) => { + server.once("error", reject); + server.listen(endpoint, resolve); + }); +} + +function acknowledgement(socket) { + return new Promise((resolve, reject) => { + socket.once("error", reject); + socket.once("data", data => resolve(data.length === 1 && data[0] === 65)); + socket.once("connect", () => socket.write("T")); + }); +} + +async function exchange(endpoint) { + const peers = new Set(); + const server = net.createServer(peer => { + peers.add(peer); + peer.on("error", () => {}); + peer.once("data", data => { + if (data.length === 1 && data[0] === 84) peer.end("A"); + else peer.destroy(); + }); + }); + server.on("error", () => {}); + let client, timer; + const deadline = new Promise((_, reject) => { + timer = setTimeout(() => reject(new Error("private stream exchange timed out")), 3000); + }); + try { + await Promise.race([listen(server, endpoint), deadline]); + client = new net.Socket(); + const response = acknowledgement(client); + client.connect(endpoint); + return await Promise.race([response, deadline]); + } catch { + return false; + } finally { + clearTimeout(timer); + client?.destroy(); + for (const peer of peers) peer.destroy(); + await new Promise(resolve => server.close(() => resolve())); + } +} + +module.exports = async function privateUnix(scratch) { + const absolute = await exchange(path.join(scratch, "a.sock")); + const previous = process.cwd(); + try { + process.chdir(scratch); + return [absolute, await exchange("r.sock")]; + } finally { + process.chdir(previous); + } +}; diff --git a/scripts/probes/plugin-confinement/run.mts b/scripts/probes/plugin-confinement/run.mts index 22856c631..00ba80973 100644 --- a/scripts/probes/plugin-confinement/run.mts +++ b/scripts/probes/plugin-confinement/run.mts @@ -12,7 +12,7 @@ import { fileURLToPath } from "node:url"; import { parseArgs } from "node:util"; type Runtime = { kind: "python" | "node" | "bun" | "deno" | "native"; executable: string; prefix: string; include: string; libdir: string; library?: string; version: string }; -type Artifacts = { executable: string; addon?: string; landlock?: string; initialExec: boolean; stagedPlatform?: boolean; signingIdentifier?: string; trace?: string; packaged?: boolean; unixScratch?: boolean }; +type Artifacts = { executable: string; addon?: string; landlock?: string; initialExec: boolean; stagedPlatform?: boolean; signingIdentifier?: string; trace?: string; packaged?: boolean; unixScratch?: boolean; privateStream?: boolean }; type Flags = { read: boolean; write: boolean; shell: boolean; unrestricted?: boolean }; type Observation = Record; const source = dirname(fileURLToPath(import.meta.url)); @@ -170,7 +170,7 @@ function fixture(root: string): Record { // Runtime module loaders may open the entrypoint's directory as well as // the file. Stage the trusted bootstrap in the already admitted read-only // package instead of granting access to the repository containing it. - for (const file of ["fixture.py", "fixture.cjs", "node_bootstrap.cjs"]) copyFileSync(join(source, file), join(paths.package, file)); + for (const file of ["fixture.py", "fixture.cjs", "private_unix.cjs", "node_bootstrap.cjs"]) copyFileSync(join(source, file), join(paths.package, file)); for (const path of [join(paths.package, "data"), join(paths.project, "data"), join(paths.private, "data")]) { writeFileSync(path, "owned temporary fixture", { mode: 0o600 }); } @@ -229,7 +229,7 @@ function observe(artifacts: Artifacts, runtime: Runtime, paths: Record !unsupported_cases.some(item => item.name === name)) .map(([name, flags]) => check(root, artifacts, runtime, name, flags)); const digest = createHash("sha256"); - const sources = ["run.mts", "macos_python.c", "macos_node.c", "native_exec.c", "node_bootstrap.cjs", "fixture.py", "fixture.cjs", "process_policy.h", "linux_filter.h", "linux_exec.c", "linux_initial_exec.h", "fixture_native.c", "macos_exec.c", "macos_stage.mts"]; + const sources = ["run.mts", "macos_python.c", "macos_node.c", "native_exec.c", "node_bootstrap.cjs", "fixture.py", "fixture.cjs", "private_unix.cjs", "process_policy.h", "linux_filter.h", "linux_exec.c", "linux_initial_exec.h", "fixture_native.c", "macos_exec.c", "macos_stage.mts"]; for (const file of sources) { digest.update(file + "\0").update(readFileSync(join(source, file))); } diff --git a/scripts/probes/plugin-native-entry/build_socket_candidate.py b/scripts/probes/plugin-native-entry/build_socket_candidate.py index 572bb6120..395df7e27 100644 --- a/scripts/probes/plugin-native-entry/build_socket_candidate.py +++ b/scripts/probes/plugin-native-entry/build_socket_candidate.py @@ -13,6 +13,7 @@ "broker-private-stream", "broker-private-stream-no-makesock", "broker-private-stream-no-refer", "broker-private-stream-mutation", "broker-private-stream-mutation-no-endpoint", "broker-private-stream-wrong-cwd", "broker-private-stream-no-beneath", + "broker-private-stream-no-unix-create", "landlock9", "landlock9-no-resolve"} unix9 = mode.startswith("landlock9") private_stream = mode.startswith("broker-private-stream") @@ -24,6 +25,12 @@ family = "linux_socket_landlock9.h" if unix9 else ( "linux_socket_private_stream.h" if private_stream else "linux_socket_candidate.h") shutil.copyfile(Path(__file__).with_name(family), target / "socket_candidate.h") + if mode == "broker-private-stream-no-unix-create": + header = target / "socket_candidate.h" + text = header.read_text() + before = "BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AF_UNIX, 1, 0)" + assert text.count(before) == 2 + header.write_text(text.replace(before, before.replace('AF_UNIX, 1, 0', 'AF_UNIX, 0, 0'), 1)) if mode.startswith("broker"): shutil.copyfile(Path(__file__).with_name("linux_socket_broker.h"), target / "socket_broker.h") if private_stream: diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/arm64/linux-ipc-broker-private-stream.json b/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/arm64/linux-ipc-broker-private-stream.json new file mode 100644 index 000000000..74969212e --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/arm64/linux-ipc-broker-private-stream.json @@ -0,0 +1,818 @@ +{ + "platform": "linux", + "architecture": "aarch64", + "checkout": "b719d619418f36f66f553c1582b09a99195c7ce5", + "run_id": "41084231069", + "candidate": true, + "landlock9": false, + "socket_broker": true, + "private_stream_probe": true, + "unix_mutation_probe": false, + "cancellation_probe": false, + "mutation_probe": false, + "escape_probe": null, + "saturation_probe": false, + "sources": [ + "crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h", + "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", + "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", + "crates/cyber-sandbox/src/plugin_policy.rs", + "crates/cyber-sandbox/src/plugin_policy/linux.rs", + "crates/cyber-sandbox/native/linux_plugin_exec.c", + "crates/cyber-sandbox/native/linux_filter.h", + "crates/cyber-sandbox/native/linux_initial_exec.h", + "crates/cyber-sandbox/src/native_exec.rs", + "crates/cyber-sandbox/src/bin/cyber-sandbox-exec.rs", + "crates/cyber-sandbox/build.rs", + "crates/cyber-sandbox/Cargo.toml", + "Cargo.lock", + ".github/workflows/plugin-linux-ipc.yml", + "scripts/probes/plugin-native-entry/linux_socket_candidate.h", + "scripts/probes/plugin-native-entry/linux_socket_broker.h", + "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", + "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", + "scripts/probes/plugin-native-entry/linux_unix9_policy.h", + "scripts/probes/plugin-native-entry/build_socket_candidate.py" + ], + "source_sha256": "f53cfe901242e30b8fdcd3bab1a90ac62ff2f451722339f95052d7b378239cad", + "helper_sha256": "e1cd32b8483cf2aa67856e7e7ddecbcd54ca37253552152919ec9c4061e53e18", + "rows": [ + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + } + ], + "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/arm64/private-stream-no-beneath.log b/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/arm64/private-stream-no-beneath.log new file mode 100644 index 000000000..4e4cf5f78 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/arm64/private-stream-no-beneath.log @@ -0,0 +1,4 @@ + +thread 'main' (8522) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:191:9: +private relative path escaped scratch: {"host_received_fixture":true,"observed":{"started":true,"connected":false,"sent":false,"project_read":false,"pair_roundtrip":true,"pair_disconnect":false,"pair_reconnect":false,"pair_bind":false,"pair_listen":false,"pair_sendto":false,"pair_sendmsg":false,"datagram_pair":false,"seqpacket_pair":false,"landlock_abi":8,"tcp_roundtrip":true,"thread_tcp_roundtrip":true,"scratch_unix_roundtrip":true,"regular_reparent":false,"cross_mount_alias_errno":18,"relative_root_roundtrip":true,"relative_parent_roundtrip":true,"relative_escape_connected":true,"relative_escape_sent":true}} +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/arm64/private-stream-wrong-cwd.log b/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/arm64/private-stream-wrong-cwd.log new file mode 100644 index 000000000..d4dc9b31c --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/arm64/private-stream-wrong-cwd.log @@ -0,0 +1,6 @@ + +thread 'main' (8501) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:197:13: +assertion `left == right` failed: private relative stream exchange: relative_root_roundtrip: {"started":true,"connected":false,"sent":false,"project_read":false,"pair_roundtrip":true,"pair_disconnect":false,"pair_reconnect":false,"pair_bind":false,"pair_listen":false,"pair_sendto":false,"pair_sendmsg":false,"datagram_pair":false,"seqpacket_pair":false,"landlock_abi":8,"tcp_roundtrip":true,"thread_tcp_roundtrip":true,"scratch_unix_roundtrip":true,"regular_reparent":false,"cross_mount_alias_errno":18,"relative_root_roundtrip":false,"relative_parent_roundtrip":false,"relative_escape_connected":false,"relative_escape_sent":false} + left: Bool(false) + right: true +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/x64/linux-ipc-broker-private-stream.json b/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/x64/linux-ipc-broker-private-stream.json new file mode 100644 index 000000000..86448fb05 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/x64/linux-ipc-broker-private-stream.json @@ -0,0 +1,818 @@ +{ + "platform": "linux", + "architecture": "x86_64", + "checkout": "b719d619418f36f66f553c1582b09a99195c7ce5", + "run_id": "41084231069", + "candidate": true, + "landlock9": false, + "socket_broker": true, + "private_stream_probe": true, + "unix_mutation_probe": false, + "cancellation_probe": false, + "mutation_probe": false, + "escape_probe": null, + "saturation_probe": false, + "sources": [ + "crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h", + "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", + "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", + "crates/cyber-sandbox/src/plugin_policy.rs", + "crates/cyber-sandbox/src/plugin_policy/linux.rs", + "crates/cyber-sandbox/native/linux_plugin_exec.c", + "crates/cyber-sandbox/native/linux_filter.h", + "crates/cyber-sandbox/native/linux_initial_exec.h", + "crates/cyber-sandbox/src/native_exec.rs", + "crates/cyber-sandbox/src/bin/cyber-sandbox-exec.rs", + "crates/cyber-sandbox/build.rs", + "crates/cyber-sandbox/Cargo.toml", + "Cargo.lock", + ".github/workflows/plugin-linux-ipc.yml", + "scripts/probes/plugin-native-entry/linux_socket_candidate.h", + "scripts/probes/plugin-native-entry/linux_socket_broker.h", + "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", + "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", + "scripts/probes/plugin-native-entry/linux_unix9_policy.h", + "scripts/probes/plugin-native-entry/build_socket_candidate.py" + ], + "source_sha256": "f53cfe901242e30b8fdcd3bab1a90ac62ff2f451722339f95052d7b378239cad", + "helper_sha256": "73acbf7c4dc288a0aa02d6cd3074a3c45b471bd12833a659f1f391faf105cff6", + "rows": [ + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + } + ], + "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/x64/private-stream-no-beneath.log b/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/x64/private-stream-no-beneath.log new file mode 100644 index 000000000..990496d0a --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/x64/private-stream-no-beneath.log @@ -0,0 +1,4 @@ + +thread 'main' (8898) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:191:9: +private relative path escaped scratch: {"host_received_fixture":true,"observed":{"started":true,"connected":false,"sent":false,"project_read":false,"pair_roundtrip":true,"pair_disconnect":false,"pair_reconnect":false,"pair_bind":false,"pair_listen":false,"pair_sendto":false,"pair_sendmsg":false,"datagram_pair":false,"seqpacket_pair":false,"landlock_abi":8,"tcp_roundtrip":true,"thread_tcp_roundtrip":true,"scratch_unix_roundtrip":true,"regular_reparent":false,"cross_mount_alias_errno":18,"relative_root_roundtrip":true,"relative_parent_roundtrip":true,"relative_escape_connected":true,"relative_escape_sent":true}} +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/x64/private-stream-wrong-cwd.log b/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/x64/private-stream-wrong-cwd.log new file mode 100644 index 000000000..1db86d5ab --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-relative-b227c833/x64/private-stream-wrong-cwd.log @@ -0,0 +1,6 @@ + +thread 'main' (8877) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:197:13: +assertion `left == right` failed: private relative stream exchange: relative_root_roundtrip: {"started":true,"connected":false,"sent":false,"project_read":false,"pair_roundtrip":true,"pair_disconnect":false,"pair_reconnect":false,"pair_bind":false,"pair_listen":false,"pair_sendto":false,"pair_sendmsg":false,"datagram_pair":false,"seqpacket_pair":false,"landlock_abi":8,"tcp_roundtrip":true,"thread_tcp_roundtrip":true,"scratch_unix_roundtrip":true,"regular_reparent":false,"cross_mount_alias_errno":18,"relative_root_roundtrip":false,"relative_parent_roundtrip":false,"relative_escape_connected":false,"relative_escape_sent":false} + left: Bool(false) + right: true +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace From 2f1fee99b730db5d3d37876b603e5c059399088d Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 12:33:50 -0400 Subject: [PATCH 10/21] feat(plugins): admit scratch socket aliases by mount identity --- .github/workflows/plugin-linux-ipc.yml | 18 +- .../examples/plugin_unix_socket_probe.rs | 30 +- .../tests/fixtures/plugin_unix_relative.h | 66 +- .../tests/fixtures/plugin_unix_socket.c | 21 +- .../linux-private-aliases.md | 57 ++ .../linux-private-relative-paths.md | 8 +- .../linux-private-runtime-ipc.md | 26 +- .../linux-private-stream-integration.md | 12 +- .../native-host-integration.md | 3 +- .../build_socket_candidate.py | 17 +- .../arm64/bun.json | 524 +++++++++++ .../arm64/deno.json | 475 ++++++++++ .../linux-ipc-broker-private-stream.json | 818 ++++++++++++++++++ .../arm64/native.json | 511 +++++++++++ .../arm64/node.json | 475 ++++++++++ .../arm64/private-runtime-no-create.log | 31 + .../arm64/python.json | 466 ++++++++++ .../x64/bun.json | 524 +++++++++++ .../x64/deno.json | 475 ++++++++++ .../x64/linux-ipc-broker-private-stream.json | 818 ++++++++++++++++++ .../x64/native.json | 511 +++++++++++ .../x64/node.json | 475 ++++++++++ .../x64/private-runtime-no-create.log | 31 + .../x64/python.json | 466 ++++++++++ .../linux_socket_private_unix.h | 85 +- 25 files changed, 6849 insertions(+), 94 deletions(-) create mode 100644 openspec/changes/complete-plugin-hook-runtime/linux-private-aliases.md create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/bun.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/deno.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/linux-ipc-broker-private-stream.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/native.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/node.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/private-runtime-no-create.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/python.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/bun.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/deno.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/linux-ipc-broker-private-stream.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/native.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/node.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/private-runtime-no-create.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/python.json diff --git a/.github/workflows/plugin-linux-ipc.yml b/.github/workflows/plugin-linux-ipc.yml index 243e89a2c..1deb0bfa9 100644 --- a/.github/workflows/plugin-linux-ipc.yml +++ b/.github/workflows/plugin-linux-ipc.yml @@ -112,7 +112,7 @@ jobs: for variant in broker-private-stream broker-private-stream-no-makesock broker-private-stream-no-refer broker-private-stream-mutation broker-private-stream-mutation-no-endpoint; do python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/$variant" "$variant" done - for variant in wrong-cwd no-beneath no-unix-create; do + for variant in wrong-cwd no-mount no-unix-create no-alias; do python3 scripts/probes/plugin-native-entry/build_socket_candidate.py "$RUNNER_TEMP/broker-private-stream-$variant" "broker-private-stream-$variant" done for mode in mutation mutation-no-pin mutation-no-copy mutation-continue; do @@ -153,11 +153,11 @@ jobs: '"private_roundtrip":false', '"host_received_fixture":true', 'BPIN ']: assert token in text, text PY - - name: Reject wrong relative context and missing scratch traversal boundary + - name: Reject wrong relative context and missing endpoint mount boundary shell: bash run: | set -euo pipefail - for control in wrong-cwd no-beneath; do + for control in wrong-cwd no-mount no-alias; do log="$RUNNER_TEMP/private-stream-$control.log" if target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/broker-private-stream-$control" "$RUNNER_TEMP/linux-ipc-private-$control.json" --broker-private-stream > "$log" 2>&1; then echo "Private relative-path control unexpectedly passed: $control" >&2 @@ -170,9 +170,14 @@ jobs: if sys.argv[2] == 'wrong-cwd': assert 'private relative stream exchange: relative_root_roundtrip' in text, text assert '"scratch_unix_roundtrip":true' in text and '"relative_root_roundtrip":false' in text, text + elif sys.argv[2] == 'no-mount': + assert 'socket denial: outside:' in text, text + for token in ['"host_received_fixture":true', '"connected":true', '"sent":true']: + assert token in text, text else: - assert 'private relative path escaped scratch:' in text, text - for token in ['"host_received_fixture":true', '"relative_escape_connected":true', '"relative_escape_sent":true']: + assert 'private relative stream exchange: alias_relative_roundtrip' in text, text + for token in ['"scratch_unix_roundtrip":true', '"relative_root_roundtrip":true', + '"outside_cwd_roundtrip":true', '"alias_relative_roundtrip":false']: assert token in text, text PY done @@ -433,7 +438,8 @@ jobs: ${{ runner.temp }}/broker-private-stream-no-refer.log ${{ runner.temp }}/private-stream-no-endpoint.log ${{ runner.temp }}/private-stream-wrong-cwd.log - ${{ runner.temp }}/private-stream-no-beneath.log + ${{ runner.temp }}/private-stream-no-mount.log + ${{ runner.temp }}/private-stream-no-alias.log ${{ runner.temp }}/private-runtime-no-create.log ${{ runner.temp }}/broker-no-thread.log ${{ runner.temp }}/broker-no-cancel.log diff --git a/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs b/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs index c0925efec..d97ee00f3 100644 --- a/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs +++ b/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs @@ -41,9 +41,16 @@ mod probe { fn receipt(listener: &UnixListener, observed: &Value) -> bool { assert_eq!(observed["started"], true); - let connected = - observed["connected"] == true || observed["relative_escape_connected"] == true; - let sent = observed["sent"] == true || observed["relative_escape_sent"] == true; + let connected = [ + "connected", + "relative_escape_connected", + "alias_escape_connected", + ] + .iter() + .any(|key| observed[*key] == true); + let sent = ["sent", "relative_escape_sent", "alias_escape_sent"] + .iter() + .any(|key| observed[*key] == true); match listener.accept() { Ok((mut stream, _)) => { assert!(connected); @@ -193,7 +200,14 @@ mod probe { "private relative path escaped scratch: {}", json!({"host_received_fixture":delivered,"observed":observed}) ); - for key in ["relative_root_roundtrip", "relative_parent_roundtrip"] { + for key in [ + "relative_root_roundtrip", + "relative_parent_roundtrip", + "outside_cwd_roundtrip", + "alias_relative_roundtrip", + "alias_absolute_roundtrip", + "alias_directory_roundtrip", + ] { assert_eq!( observed[key], true, "private relative stream exchange: {key}: {observed}" @@ -201,6 +215,8 @@ mod probe { } assert_eq!(observed["relative_escape_connected"], false); assert_eq!(observed["relative_escape_sent"], false); + assert_eq!(observed["alias_escape_connected"], false); + assert_eq!(observed["alias_escape_sent"], false); assert_eq!( observed["regular_reparent"], policy.fs_write, "private IPC layer changed ordinary file moves: {label} read={} write={}: {observed}", @@ -406,7 +422,11 @@ mod probe { assert_eq!(observed["project_read"], read, "native read control"); let delivered = receipt(&listeners[index], &observed); if candidate || label == "private-mask" { - assert!(!delivered, "socket denial: {label}: {observed}"); + assert!( + !delivered, + "socket denial: {label}: {}", + json!({"host_received_fixture":delivered,"observed":observed}) + ); } rows.push(json!({"socket": label, "fs_read": read, "fs_write": write, "shell": false, "host_received_fixture": delivered, "observed": observed})); diff --git a/crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h b/crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h index cd3633a0f..c90fbba6c 100644 --- a/crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h +++ b/crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h @@ -1,6 +1,60 @@ /* Relative names must resolve from the guest's CWD, never the broker's. */ -struct relative_result { int root, parent, escape_connected, escape_sent; }; +struct relative_result { + int root, parent, outside_cwd, alias_relative, alias_absolute, alias_directory; + int escape_connected, escape_sent, alias_escape_connected, alias_escape_sent; +}; #ifdef __linux__ +static int relative_connect_token(const char *path, int *sent) { + struct sockaddr_un address = { .sun_family = AF_UNIX }; + if (strlen(path) >= sizeof(address.sun_path)) return 0; + strcpy(address.sun_path, path); + int socket_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + int connected = socket_fd >= 0 && connect(socket_fd, (struct sockaddr *)&address, + (socklen_t)(offsetof(struct sockaddr_un, sun_path) + strlen(path) + 1)) == 0; + *sent = connected && send(socket_fd, "fixture-only", 12, MSG_NOSIGNAL) == 12; + if (socket_fd >= 0) close(socket_fd); + return connected; +} + +static int relative_alias_exchange(const char *scratch, const char *name, + const char *value, const char *tail) { + char target[544], alias[544], destination[576]; + snprintf(target, sizeof(target), "%s/alias-target.sock", scratch); + snprintf(alias, sizeof(alias), "%s/%s", scratch, name); + snprintf(destination, sizeof(destination), "%s%s", alias, tail); + if (symlink(value == NULL ? target : value, alias) != 0) return 0; + int result = local_exchange_to(AF_UNIX, target, -1, destination); + unlink(alias); + return result; +} + +static int relative_outside_exchange(const char *scratch, int root) { + const char *name = strrchr(scratch, '/'); + if (name == NULL) return 0; + char target[544], destination[544]; + snprintf(target, sizeof(target), "%s/outside-cwd.sock", scratch); + snprintf(destination, sizeof(destination), "%s/outside-cwd.sock", name + 1); + int parent = openat(root, "..", O_PATH | O_DIRECTORY | O_CLOEXEC); + if (parent < 0) return 0; + int result = fchdir(parent) == 0 && local_exchange_to(AF_UNIX, target, -1, destination); + if (fchdir(root) != 0) _exit(3); + close(parent); + return result; +} + +static void relative_aliases(const char *scratch, int root, struct relative_result *result) { + result->alias_relative = relative_alias_exchange(scratch, "relative-link.sock", "alias-target.sock", ""); + result->alias_absolute = relative_alias_exchange(scratch, "absolute-link.sock", NULL, ""); + result->alias_directory = relative_alias_exchange(scratch, "directory-link", ".", "/alias-target.sock"); + result->outside_cwd = relative_outside_exchange(scratch, root); + char alias[544]; + snprintf(alias, sizeof(alias), "%s/escape-link.sock", scratch); + if (symlink("../host.sock", alias) == 0) { + result->alias_escape_connected = relative_connect_token(alias, &result->alias_escape_sent); + unlink(alias); + } +} + static struct relative_result relative_probe(const char *scratch_socket) { struct relative_result result = {0}; if (scratch_socket == NULL || strlen(scratch_socket) >= 512) return result; @@ -11,20 +65,14 @@ static struct relative_result relative_probe(const char *scratch_socket) { *last = '\0'; int previous = open(".", O_PATH | O_DIRECTORY | O_CLOEXEC); int root = open(scratch, O_PATH | O_DIRECTORY | O_CLOEXEC); - int outside = -1; if (previous < 0 || root < 0 || fchdir(root) != 0) goto done; result.root = local_exchange(AF_UNIX, "relative.sock", -1); if (mkdir("relative-dir", 0700) != 0 || chdir("relative-dir") != 0) goto done; result.parent = local_exchange(AF_UNIX, "../parent.sock", -1); if (fchdir(root) != 0) _exit(3); - struct sockaddr_un address = { .sun_family = AF_UNIX }; - strcpy(address.sun_path, "../host.sock"); - outside = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); - result.escape_connected = outside >= 0 && connect(outside, (struct sockaddr *)&address, - (socklen_t)(offsetof(struct sockaddr_un, sun_path) + strlen(address.sun_path) + 1)) == 0; - result.escape_sent = result.escape_connected && send(outside, "fixture-only", 12, MSG_NOSIGNAL) == 12; + result.escape_connected = relative_connect_token("../host.sock", &result.escape_sent); + relative_aliases(scratch, root, &result); done: - if (outside >= 0) close(outside); if (root >= 0) { unlinkat(root, "relative-dir", AT_REMOVEDIR); close(root); } if (previous >= 0) { if (fchdir(previous) != 0) _exit(3); diff --git a/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c b/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c index f84949045..22d44634d 100644 --- a/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c +++ b/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c @@ -26,7 +26,7 @@ static int abi(void) { #endif } -static int local_exchange(int family, const char *path, int server) { +static int local_exchange_to(int family, const char *path, int server, const char *destination) { int client = -1, peer = -1, ok = 0; struct sockaddr_storage storage = {0}; socklen_t length; @@ -45,6 +45,12 @@ static int local_exchange(int family, const char *path, int server) { if (server < 0) server = socket(family, SOCK_STREAM, 0); if (server < 0 || bind(server, (struct sockaddr *)&storage, length) != 0 || listen(server, 1) != 0 || getsockname(server, (struct sockaddr *)&storage, &length) != 0) goto done; + if (destination != NULL) { + struct sockaddr_un *address = (struct sockaddr_un *)&storage; + if (family != AF_UNIX || strlen(destination) >= sizeof(address->sun_path)) goto done; + strcpy(address->sun_path, destination); + length = (socklen_t)(offsetof(struct sockaddr_un, sun_path) + strlen(destination) + 1); + } client = socket(family, SOCK_STREAM, 0); if (client < 0 || connect(client, (struct sockaddr *)&storage, length) != 0) goto done; peer = accept(server, NULL, NULL); @@ -60,6 +66,10 @@ static int local_exchange(int family, const char *path, int server) { return ok; } +static int local_exchange(int family, const char *path, int server) { + return local_exchange_to(family, path, server, NULL); +} + #include "plugin_unix_relative.h" #ifdef __linux__ @@ -176,7 +186,9 @@ static int pair_probe(const struct sockaddr_un *address, socklen_t length, "\"datagram_pair\":%s,\"seqpacket_pair\":%s,\"landlock_abi\":%d," "\"tcp_roundtrip\":%s,\"thread_tcp_roundtrip\":%s,\"scratch_unix_roundtrip\":%s,\"regular_reparent\":%s," "\"cross_mount_alias_errno\":%d,\"relative_root_roundtrip\":%s,\"relative_parent_roundtrip\":%s," - "\"relative_escape_connected\":%s,\"relative_escape_sent\":%s}\n", + "\"relative_escape_connected\":%s,\"relative_escape_sent\":%s," + "\"outside_cwd_roundtrip\":%s,\"alias_relative_roundtrip\":%s,\"alias_absolute_roundtrip\":%s," + "\"alias_directory_roundtrip\":%s,\"alias_escape_connected\":%s,\"alias_escape_sent\":%s}\n", (connected || reconnected) ? "true" : "false", sent ? "true" : "false", readable ? "true" : "false", roundtrip ? "true" : "false", disconnected ? "true" : "false", reconnected ? "true" : "false", @@ -186,7 +198,10 @@ static int pair_probe(const struct sockaddr_un *address, socklen_t length, tcp ? "true" : "false", thread_tcp ? "true" : "false", scratch_ipc ? "true" : "false", moved ? "true" : "false", alias_error, relative.root ? "true" : "false", relative.parent ? "true" : "false", - relative.escape_connected ? "true" : "false", relative.escape_sent ? "true" : "false"); + relative.escape_connected ? "true" : "false", relative.escape_sent ? "true" : "false", + relative.outside_cwd ? "true" : "false", relative.alias_relative ? "true" : "false", + relative.alias_absolute ? "true" : "false", relative.alias_directory ? "true" : "false", + relative.alias_escape_connected ? "true" : "false", relative.alias_escape_sent ? "true" : "false"); return 0; } diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-aliases.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-aliases.md new file mode 100644 index 000000000..b0810792e --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-aliases.md @@ -0,0 +1,57 @@ +# Private UNIX aliases and outside-scratch caller contexts + +This extends the approved broker's private-stream candidate under task N2. The +earlier [relative-path proof](linux-private-relative-paths.md) accepted only a +CWD already inside scratch and rejected symlinks. The current candidate instead +pins the resulting socket and checks its mount identity against the pinned, +separately mounted scratch root. It still requires protected scratch provenance +and does not activate production native hosts. + +For a relative name, open `/proc//cwd` as a directory handle +and use that exact object for lookup. The broker's CWD and a reconstructed string +cannot supply context. Absolute names resolve in the shared protected mount +namespace. `openat2` uses O_PATH and RESOLVE_NO_MAGICLINKS. Ordinary symlinks may +resolve, including absolute links and directory components; no content is read. +The final handle must describe a socket on the exact scratch mount, with matching +device identity and returned statx mount/type fields. Both mount-bearing handles +stay pinned through validation; the endpoint remains owned through worker connect. + +This uses the kernel's [handle-based statx mount identity](https://man7.org/linux/man-pages/man2/statx.2.html) +and [openat2 resolution controls](https://man7.org/linux/man-pages/man2/openat2.2.html). +The candidate no longer treats lexical beneath-root lookup as the authorization +boundary. Endpoint mount membership is the boundary, including when a path +temporarily traverses outside scratch. Missing metadata, a different mount, +non-socket endpoints and magic links are refused. Final notification validity +and the pinned socket/endpoint worker operation are unchanged. + +The owner must establish a fresh scratch tree, bind it separately, protect its +source and all writable aliases from other hosts, exclude foreign sockets at +startup and prevent guest mount manipulation. A mount ID is not an ownership +proof without those preconditions. Cross-root hard links still fail EXDEV; +descendant mounts do not inherit scratch endpoint authority. + +Each native private-stream pair case now requires token/acknowledgement exchange +from scratch root, from a nested parent-relative name, from a CWD outside scratch, +through relative and absolute socket symlinks, and through a directory symlink. +Direct parent escape and a scratch symlink to the owned host listener must both +fail. The owner checks actual host delivery in addition to target observations. + +Three temporary controls isolate context, security and compatibility. Wrong-CWD +lookup must fail the named root-relative exchange after absolute exchange works. +Omitting only the endpoint mount guard must actually deliver to the owned host +listener and fail `socket denial: outside`. Adding NO_SYMLINKS must preserve root, +outside-CWD and absolute scratch exchanges, then fail the named relative-alias +exchange. Generic startup failures do not satisfy these controls. The prior +missing-beneath proof is retained as evidence of the earlier algorithm, while +the current workflow uses the missing-mount control. + +Local checks cover portable C syntax, Rust example Clippy, intercepted candidate +transformations, Python/workflow syntax and spec validation. An unconfined macOS +component check exercises all six positive fixture exchanges and both reachable +owned host controls, adapting O_PATH/CLOEXEC flags for that platform. It does not +test Linux flags, mount identity or confinement. Hosted Linux x64/arm64 results +for this extension remain pending. + +Datagram/seqpacket, destination-bearing sends, ancillary and peer identity, +proxy/network intersections and production admission/settlement remain required. +N2–N7 and the parent tasks remain open. diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-relative-paths.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-relative-paths.md index 769884ab9..89fa8964e 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-relative-paths.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-relative-paths.md @@ -1,8 +1,10 @@ # Caller-bound relative private UNIX paths -The private-stream candidate now resolves relative names using the actual -notifying thread's working directory. This extends the approved broker scope; -it is not production admission or complete pathname/IPC acceptance. +This records the b227c833 private-stream prerequisite and its native receipts. +It resolves relative names using the actual notifying thread's working directory. +The subsequent [alias and outside-CWD extension](linux-private-aliases.md) +replaces the beneath-root authorization algorithm described here with pinned +endpoint mount membership. Neither is production admission or complete IPC. The broker opens the thread's procfs CWD as an owned directory handle, reads that handle's kernel pathname and matches it to a beneath-root directory open in the diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-runtime-ipc.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-runtime-ipc.md index 48964b044..69d7f1a39 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-runtime-ipc.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-runtime-ipc.md @@ -29,8 +29,30 @@ Local unconfined component checks pass for Node, Python and the native exchange functions, including CWD restoration and pathname cleanup. Portable C syntax, TypeScript/JavaScript/Python syntax and workflow checks are available on macOS. Bun and Deno are unavailable locally. Real Linux confinement and all five -runtime families require the hosted x64/arm64 workflow; those results remain -pending. No production launch path changes in this extension. +runtime families require the hosted x64/arm64 workflow. No production launch +path changes in this extension. + +## Native result for 077fb62e + +[Run 41089801122](https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41089801122) +passes both Linux jobs. Each architecture's Node, Python, Bun, Deno and native +reports contains all nine rows with `private_unix: [true, true]` and no unsupported +rows: 45 runtime cases per architecture. The missing-create control passes the +unconfined row and fails at the exact named no-capabilities assertion with both +exchange results false. + +Original runtime reports, the socket report binding their helper digest, and the +control log are retained under +`scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/{x64,arm64}`. +They bind tested merge `e161ed17510ed29120fad191610d9fc5e900edee`, whose tree equals +source head `077fb62e04ac6bbdeaa66cbdf465dab12a7647cc`, kernel +`7.0.0-1017-azure`, runtime manifest SHA-256 +`8a8fa6f23f4e209611af317fd7bb2babdbe4f0ffde7b26e4c95822fef0679288` +and socket manifest SHA-256 +`7fc859f57cf92e4a0c072b9a3d6d814360fa5e774a226f8c1743f544de6ce35a`. +Both manifests and tree equality were independently verified. Every runtime's +input and executed helper digest matches its architecture's socket report. +These receipts do not cover the subsequent alias/mount-identity extension. Outside-root relative contexts, supported aliases, datagram/seqpacket, destination-bearing sends, ancillary and peer identity behavior, proxy/network diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md index 2cf6bcc1f..ae5235ee8 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md @@ -27,9 +27,11 @@ mount, so writable project sockets cannot be hard-linked into it; this origin precondition is essential, including after a source pathname is unlinked. Connect notifications still pin the exact requesting thread's socket. For an -absolute scratch pathname the broker uses beneath/no-symlink/no-magic-link -resolution and checks the actual endpoint inode, retaining its O_PATH descriptor -through the worker operation. The worker keeps only socket, result pipe and +absolute scratch pathname the initial implementation used beneath/no-symlink/ +no-magic-link resolution. The [alias extension](linux-private-aliases.md) now +checks pinned endpoint mount membership and permits safe symlinks and callers +outside scratch. Both retain the endpoint's O_PATH descriptor through the worker +operation. The worker keeps only socket, result pipe and endpoint handles at fixed slots, then connects through its own procfs reference. It never continues a mutable inspected pathname or re-resolves a guest descriptor. Private abstract stream destinations rely on the mandatory private net namespace. @@ -91,8 +93,8 @@ has source-bound passing x64/arm64 evidence. The [caller-bound relative-path extension](linux-private-relative-paths.md) now adds scratch-relative handling with retained x64/arm64 evidence. The [runtime API exchange extension](linux-private-runtime-ipc.md) adds acceptance -for each runtime's own private pathname socket operations; hosted results for -that extension remain pending. +for each runtime's own private pathname socket operations with retained passing +x64/arm64 results. The alias extension's native results remain pending. Still required before complete IPC/production acceptance: verified post-pin replacement, relative/alias forms, datagram/seqpacket and diff --git a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md index 85d01b292..7ede07e7b 100644 --- a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md @@ -113,7 +113,8 @@ App's legacy launch path does not implement this sequence today. applies that primitive in real connect notifications. The [runtime API exchange extension](linux-private-runtime-ipc.md) requires real private pathname exchanges from each supported runtime. These increments do - not complete this task. + not complete this task. The [alias extension](linux-private-aliases.md) covers + safe symlinks and outside-scratch caller contexts through pinned mount identity. - [ ] N3 Implement registry-owned generation admission and immutable resource binding with actual production startup, revocation and quarantine tests. - [ ] N4 Integrate the native launch owner and independently intersect all diff --git a/scripts/probes/plugin-native-entry/build_socket_candidate.py b/scripts/probes/plugin-native-entry/build_socket_candidate.py index 395df7e27..2b3353e0c 100644 --- a/scripts/probes/plugin-native-entry/build_socket_candidate.py +++ b/scripts/probes/plugin-native-entry/build_socket_candidate.py @@ -12,8 +12,8 @@ "broker-mutation", "broker-mutation-no-pin", "broker-mutation-no-copy", "broker-mutation-continue", "broker-private-stream", "broker-private-stream-no-makesock", "broker-private-stream-no-refer", "broker-private-stream-mutation", "broker-private-stream-mutation-no-endpoint", - "broker-private-stream-wrong-cwd", "broker-private-stream-no-beneath", - "broker-private-stream-no-unix-create", + "broker-private-stream-wrong-cwd", "broker-private-stream-no-mount", + "broker-private-stream-no-unix-create", "broker-private-stream-no-alias", "landlock9", "landlock9-no-resolve"} unix9 = mode.startswith("landlock9") private_stream = mode.startswith("broker-private-stream") @@ -53,13 +53,18 @@ before = ' snprintf(proc, sizeof(proc), "/proc/%u/cwd", tid);' assert text.count(before) == 1 header.write_text(text.replace(before, ' tid = (unsigned int)getpid(); /* Wrong-context control. */\n' + before)) - if mode == "broker-private-stream-no-beneath": + if mode == "broker-private-stream-no-mount": header = target / "socket_private_unix.h" text = header.read_text() - before = ''' struct open_how how = { .flags = O_PATH | O_CLOEXEC, - .resolve = RESOLVE_BENEATH | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS };''' + before = ' if (!private_socket_mount(fd)) {' assert text.count(before) == 1 - header.write_text(text.replace(before, before.replace('RESOLVE_BENEATH | ', ''))) + header.write_text(text.replace(before, ' if (!private_socket_mount(fd) && 0) { /* Missing endpoint mount guard. */')) + if mode == "broker-private-stream-no-alias": + header = target / "socket_private_unix.h" + text = header.read_text() + before = ' .resolve = RESOLVE_NO_MAGICLINKS };' + assert text.count(before) == 1 + header.write_text(text.replace(before, before.replace('RESOLVE_NO_MAGICLINKS', 'RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS'))) if mode == "broker-audit-wrong-cap": broker = target / "socket_broker.h" text = broker.read_text() diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/bun.json b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/bun.json new file mode 100644 index 000000000..cc7a13593 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/bun.json @@ -0,0 +1,524 @@ +{ + "recorded_at": "2026-10-30T16:29:20.896Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "8a8fa6f23f4e209611af317fd7bb2babdbe4f0ffde7b26e4c95822fef0679288", + "platform": "linux", + "architecture": "arm64", + "runtime": "bun", + "version": "1.4.4", + "startup_control": { + "preload": true, + "dotenv": true + }, + "packaged_helper": { + "input_sha256": "e1cd32b8483cf2aa67856e7e7ddecbcd54ca37253552152919ec9c4061e53e18", + "executed_sha256": "e1cd32b8483cf2aa67856e7e7ddecbcd54ca37253552152919ec9c4061e53e18", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": false, + "proc_root_reads": [ + true, + true + ], + "proc_init_list": true + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/deno.json b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/deno.json new file mode 100644 index 000000000..83547402f --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/deno.json @@ -0,0 +1,475 @@ +{ + "recorded_at": "2026-10-30T16:29:23.497Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "8a8fa6f23f4e209611af317fd7bb2babdbe4f0ffde7b26e4c95822fef0679288", + "platform": "linux", + "architecture": "arm64", + "runtime": "deno", + "version": "2.9.8", + "packaged_helper": { + "input_sha256": "e1cd32b8483cf2aa67856e7e7ddecbcd54ca37253552152919ec9c4061e53e18", + "executed_sha256": "e1cd32b8483cf2aa67856e7e7ddecbcd54ca37253552152919ec9c4061e53e18", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": false + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/linux-ipc-broker-private-stream.json b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/linux-ipc-broker-private-stream.json new file mode 100644 index 000000000..eb2992112 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/linux-ipc-broker-private-stream.json @@ -0,0 +1,818 @@ +{ + "platform": "linux", + "architecture": "aarch64", + "checkout": "e161ed17510ed29120fad191610d9fc5e900edee", + "run_id": "41089801122", + "candidate": true, + "landlock9": false, + "socket_broker": true, + "private_stream_probe": true, + "unix_mutation_probe": false, + "cancellation_probe": false, + "mutation_probe": false, + "escape_probe": null, + "saturation_probe": false, + "sources": [ + "crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h", + "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", + "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", + "crates/cyber-sandbox/src/plugin_policy.rs", + "crates/cyber-sandbox/src/plugin_policy/linux.rs", + "crates/cyber-sandbox/native/linux_plugin_exec.c", + "crates/cyber-sandbox/native/linux_filter.h", + "crates/cyber-sandbox/native/linux_initial_exec.h", + "crates/cyber-sandbox/src/native_exec.rs", + "crates/cyber-sandbox/src/bin/cyber-sandbox-exec.rs", + "crates/cyber-sandbox/build.rs", + "crates/cyber-sandbox/Cargo.toml", + "Cargo.lock", + ".github/workflows/plugin-linux-ipc.yml", + "scripts/probes/plugin-native-entry/linux_socket_candidate.h", + "scripts/probes/plugin-native-entry/linux_socket_broker.h", + "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", + "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", + "scripts/probes/plugin-native-entry/linux_unix9_policy.h", + "scripts/probes/plugin-native-entry/build_socket_candidate.py" + ], + "source_sha256": "7fc859f57cf92e4a0c072b9a3d6d814360fa5e774a226f8c1743f544de6ce35a", + "helper_sha256": "e1cd32b8483cf2aa67856e7e7ddecbcd54ca37253552152919ec9c4061e53e18", + "rows": [ + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + } + ], + "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/native.json b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/native.json new file mode 100644 index 000000000..c062af144 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/native.json @@ -0,0 +1,511 @@ +{ + "recorded_at": "2026-10-30T16:29:23.930Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "8a8fa6f23f4e209611af317fd7bb2babdbe4f0ffde7b26e4c95822fef0679288", + "platform": "linux", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "packaged_helper": { + "input_sha256": "e1cd32b8483cf2aa67856e7e7ddecbcd54ca37253552152919ec9c4061e53e18", + "executed_sha256": "e1cd32b8483cf2aa67856e7e7ddecbcd54ca37253552152919ec9c4061e53e18", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": true, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/node.json b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/node.json new file mode 100644 index 000000000..a2563add2 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/node.json @@ -0,0 +1,475 @@ +{ + "recorded_at": "2026-10-30T16:29:18.766Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "8a8fa6f23f4e209611af317fd7bb2babdbe4f0ffde7b26e4c95822fef0679288", + "platform": "linux", + "architecture": "arm64", + "runtime": "node", + "version": "22.23.4", + "packaged_helper": { + "input_sha256": "e1cd32b8483cf2aa67856e7e7ddecbcd54ca37253552152919ec9c4061e53e18", + "executed_sha256": "e1cd32b8483cf2aa67856e7e7ddecbcd54ca37253552152919ec9c4061e53e18", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": false + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/private-runtime-no-create.log b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/private-runtime-no-create.log new file mode 100644 index 000000000..9b25c8a6e --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/private-runtime-no-create.log @@ -0,0 +1,31 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: no-capabilities: private UNIX runtime exchange failed: [false,false] ++ actual - expected + + [ ++ false, ++ false +- true, +- true + ] + + at check (file:///home/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/run.mts:330:12) + at file:///home/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/run.mts:430:31 + at Array.map () + at main (file:///home/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/run.mts:430:8) + at file:///home/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/run.mts:452:1 + at ModuleJob.run (node:internal/modules/esm/module_job:343:25) + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:681:26) + at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: [ false, false ], + expected: [ true, true ], + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.23.4 diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/python.json b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/python.json new file mode 100644 index 000000000..a348c50e7 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/arm64/python.json @@ -0,0 +1,466 @@ +{ + "recorded_at": "2026-10-30T16:29:19.855Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "8a8fa6f23f4e209611af317fd7bb2babdbe4f0ffde7b26e4c95822fef0679288", + "platform": "linux", + "architecture": "arm64", + "runtime": "python", + "version": "3.13.17", + "packaged_helper": { + "input_sha256": "e1cd32b8483cf2aa67856e7e7ddecbcd54ca37253552152919ec9c4061e53e18", + "executed_sha256": "e1cd32b8483cf2aa67856e7e7ddecbcd54ca37253552152919ec9c4061e53e18", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "cannot_relax": null, + "child_reads": [ + true, + true + ], + "filter_replacement_denied": false, + "hardlink_private": true, + "inherited_descriptor": true, + "native_child_reads": [ + true, + true + ], + "native_fork": true, + "package_read": true, + "private_list": true, + "private_read": true, + "private_unix": [ + true, + true + ], + "private_write": true, + "project_list": true, + "project_read": true, + "project_rename": true, + "project_write": true, + "protected_read": true, + "protected_write": true, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/bun.json b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/bun.json new file mode 100644 index 000000000..7b6b89e36 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/bun.json @@ -0,0 +1,524 @@ +{ + "recorded_at": "2026-10-30T16:29:02.415Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "8a8fa6f23f4e209611af317fd7bb2babdbe4f0ffde7b26e4c95822fef0679288", + "platform": "linux", + "architecture": "x64", + "runtime": "bun", + "version": "1.4.4", + "startup_control": { + "preload": true, + "dotenv": true + }, + "packaged_helper": { + "input_sha256": "73acbf7c4dc288a0aa02d6cd3074a3c45b471bd12833a659f1f391faf105cff6", + "executed_sha256": "73acbf7c4dc288a0aa02d6cd3074a3c45b471bd12833a659f1f391faf105cff6", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": false, + "proc_root_reads": [ + true, + true + ], + "proc_init_list": true + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + false, + false + ], + "proc_init_list": false + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true, + "proc_root_reads": [ + true, + false + ], + "proc_init_list": false + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/deno.json b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/deno.json new file mode 100644 index 000000000..9af167e69 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/deno.json @@ -0,0 +1,475 @@ +{ + "recorded_at": "2026-10-30T16:29:05.202Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "8a8fa6f23f4e209611af317fd7bb2babdbe4f0ffde7b26e4c95822fef0679288", + "platform": "linux", + "architecture": "x64", + "runtime": "deno", + "version": "2.9.8", + "packaged_helper": { + "input_sha256": "73acbf7c4dc288a0aa02d6cd3074a3c45b471bd12833a659f1f391faf105cff6", + "executed_sha256": "73acbf7c4dc288a0aa02d6cd3074a3c45b471bd12833a659f1f391faf105cff6", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": false + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/linux-ipc-broker-private-stream.json b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/linux-ipc-broker-private-stream.json new file mode 100644 index 000000000..04524e317 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/linux-ipc-broker-private-stream.json @@ -0,0 +1,818 @@ +{ + "platform": "linux", + "architecture": "x86_64", + "checkout": "e161ed17510ed29120fad191610d9fc5e900edee", + "run_id": "41089801122", + "candidate": true, + "landlock9": false, + "socket_broker": true, + "private_stream_probe": true, + "unix_mutation_probe": false, + "cancellation_probe": false, + "mutation_probe": false, + "escape_probe": null, + "saturation_probe": false, + "sources": [ + "crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h", + "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", + "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", + "crates/cyber-sandbox/src/plugin_policy.rs", + "crates/cyber-sandbox/src/plugin_policy/linux.rs", + "crates/cyber-sandbox/native/linux_plugin_exec.c", + "crates/cyber-sandbox/native/linux_filter.h", + "crates/cyber-sandbox/native/linux_initial_exec.h", + "crates/cyber-sandbox/src/native_exec.rs", + "crates/cyber-sandbox/src/bin/cyber-sandbox-exec.rs", + "crates/cyber-sandbox/build.rs", + "crates/cyber-sandbox/Cargo.toml", + "Cargo.lock", + ".github/workflows/plugin-linux-ipc.yml", + "scripts/probes/plugin-native-entry/linux_socket_candidate.h", + "scripts/probes/plugin-native-entry/linux_socket_broker.h", + "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", + "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", + "scripts/probes/plugin-native-entry/linux_unix9_policy.h", + "scripts/probes/plugin-native-entry/build_socket_candidate.py" + ], + "source_sha256": "7fc859f57cf92e4a0c072b9a3d6d814360fa5e774a226f8c1743f544de6ce35a", + "helper_sha256": "73acbf7c4dc288a0aa02d6cd3074a3c45b471bd12833a659f1f391faf105cff6", + "rows": [ + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false + } + } + ], + "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/native.json b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/native.json new file mode 100644 index 000000000..fbcbfe33a --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/native.json @@ -0,0 +1,511 @@ +{ + "recorded_at": "2026-10-30T16:29:05.636Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "8a8fa6f23f4e209611af317fd7bb2babdbe4f0ffde7b26e4c95822fef0679288", + "platform": "linux", + "architecture": "x64", + "runtime": "native", + "version": "fixture-v2", + "packaged_helper": { + "input_sha256": "73acbf7c4dc288a0aa02d6cd3074a3c45b471bd12833a659f1f391faf105cff6", + "executed_sha256": "73acbf7c4dc288a0aa02d6cd3074a3c45b471bd12833a659f1f391faf105cff6", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": true, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "filter_replacement_denied": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/node.json b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/node.json new file mode 100644 index 000000000..5a9cd781a --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/node.json @@ -0,0 +1,475 @@ +{ + "recorded_at": "2026-10-30T16:29:00.209Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "8a8fa6f23f4e209611af317fd7bb2babdbe4f0ffde7b26e4c95822fef0679288", + "platform": "linux", + "architecture": "x64", + "runtime": "node", + "version": "22.23.4", + "packaged_helper": { + "input_sha256": "73acbf7c4dc288a0aa02d6cd3074a3c45b471bd12833a659f1f391faf105cff6", + "executed_sha256": "73acbf7c4dc288a0aa02d6cd3074a3c45b471bd12833a659f1f391faf105cff6", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": false + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ], + "filter_replacement_denied": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/private-runtime-no-create.log b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/private-runtime-no-create.log new file mode 100644 index 000000000..9b25c8a6e --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/private-runtime-no-create.log @@ -0,0 +1,31 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: no-capabilities: private UNIX runtime exchange failed: [false,false] ++ actual - expected + + [ ++ false, ++ false +- true, +- true + ] + + at check (file:///home/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/run.mts:330:12) + at file:///home/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/run.mts:430:31 + at Array.map () + at main (file:///home/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/run.mts:430:8) + at file:///home/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/run.mts:452:1 + at ModuleJob.run (node:internal/modules/esm/module_job:343:25) + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:681:26) + at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: [ false, false ], + expected: [ true, true ], + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.23.4 diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/python.json b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/python.json new file mode 100644 index 000000000..f0a3c8f39 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-runtime-077fb62e/x64/python.json @@ -0,0 +1,466 @@ +{ + "recorded_at": "2026-10-30T16:29:01.349Z", + "kernel_release": "7.0.0-1017-azure", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "8a8fa6f23f4e209611af317fd7bb2babdbe4f0ffde7b26e4c95822fef0679288", + "platform": "linux", + "architecture": "x64", + "runtime": "python", + "version": "3.13.17", + "packaged_helper": { + "input_sha256": "73acbf7c4dc288a0aa02d6cd3074a3c45b471bd12833a659f1f391faf105cff6", + "executed_sha256": "73acbf7c4dc288a0aa02d6cd3074a3c45b471bd12833a659f1f391faf105cff6", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": true, + "private_stream_candidate": true, + "mechanism": "experimental descriptor-pinned socket broker with one-use parent startup-exec budget; notification listener remains live for socket operations; immutable inherited filter", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "cannot_relax": null, + "child_reads": [ + true, + true + ], + "filter_replacement_denied": false, + "hardlink_private": true, + "inherited_descriptor": true, + "native_child_reads": [ + true, + true + ], + "native_fork": true, + "package_read": true, + "private_list": true, + "private_read": true, + "private_unix": [ + true, + true + ], + "private_write": true, + "project_list": true, + "project_read": true, + "project_rename": true, + "project_write": true, + "protected_read": true, + "protected_write": true, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "filter_replacement_denied": true, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-native-entry/linux_socket_private_unix.h b/scripts/probes/plugin-native-entry/linux_socket_private_unix.h index 1019f6ce1..95438cf0a 100644 --- a/scripts/probes/plugin-native-entry/linux_socket_private_unix.h +++ b/scripts/probes/plugin-native-entry/linux_socket_private_unix.h @@ -81,47 +81,27 @@ static int private_make_sock(void) { return result; } -static int private_same_directory(int first, int second) { - struct statx a, b; - unsigned int mask = STATX_INO | STATX_MNT_ID | STATX_TYPE; - if (syscall(SYS_statx, first, "", AT_EMPTY_PATH, mask, &a) != 0 || - syscall(SYS_statx, second, "", AT_EMPTY_PATH, mask, &b) != 0) return 0; - return (a.stx_mask & mask) == mask && (b.stx_mask & mask) == mask && - S_ISDIR(a.stx_mode) && S_ISDIR(b.stx_mode) && a.stx_ino == b.stx_ino && - a.stx_dev_major == b.stx_dev_major && a.stx_dev_minor == b.stx_dev_minor && - a.stx_mnt_id == b.stx_mnt_id; +/* A separate protected scratch bind mount supplies endpoint provenance even + * when a pathname traverses a symlink or begins from a caller CWD outside it. + * Both handles remain pinned: mount IDs cannot be recycled out from under them. + * The owner must prevent foreign links/submounts before admission. */ +static int private_socket_mount(int endpoint) { + struct statx root, socket; + unsigned int mask = STATX_MNT_ID | STATX_TYPE; + if (syscall(SYS_statx, private_root, "", AT_EMPTY_PATH, mask, &root) != 0 || + syscall(SYS_statx, endpoint, "", AT_EMPTY_PATH, mask, &socket) != 0) return 0; + return (root.stx_mask & mask) == mask && (socket.stx_mask & mask) == mask && + S_ISDIR(root.stx_mode) && S_ISSOCK(socket.stx_mode) && + root.stx_mnt_id == socket.stx_mnt_id && + root.stx_dev_major == socket.stx_dev_major && root.stx_dev_minor == socket.stx_dev_minor; } -/* Bind a relative name to the actual notifying thread's CWD. Only an attested - * directory inside the protected scratch mount may supply this context. */ -static int private_relative(unsigned int tid, const char *path, char *relative, size_t capacity) { - char proc[64], cwd_path[4097]; +/* Snapshot the notifying thread's actual directory object, not a guessed path + * or the broker's CWD. Notification validity is checked again after lookup. */ +static int private_context(unsigned int tid) { + char proc[64]; snprintf(proc, sizeof(proc), "/proc/%u/cwd", tid); - int cwd = open(proc, O_PATH | O_DIRECTORY | O_CLOEXEC); - if (cwd < 0) return errno; - snprintf(proc, sizeof(proc), "/proc/self/fd/%d", cwd); - ssize_t count = readlink(proc, cwd_path, sizeof(cwd_path) - 1); - int error = count < 0 ? errno : ENAMETOOLONG; - if (count < 0 || (size_t)count >= sizeof(cwd_path) - 1) goto done; - cwd_path[count] = '\0'; - size_t prefix = strlen(private_path); - const char *within; - if (strcmp(cwd_path, private_path) == 0) within = "."; - else if (prefix < (size_t)count && strncmp(cwd_path, private_path, prefix) == 0 && - cwd_path[prefix] == '/') within = cwd_path + prefix + 1; - else { error = EPERM; goto done; } - struct open_how how = { .flags = O_PATH | O_DIRECTORY | O_CLOEXEC, - .resolve = RESOLVE_BENEATH | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS }; - int matched = syscall(SYS_openat2, private_root, within, &how, sizeof(how)); - if (matched < 0) { error = errno; goto done; } - int same = private_same_directory(cwd, matched); - close(matched); - if (!same) { error = EPERM; goto done; } - int size = snprintf(relative, capacity, "%s/%s", within, path); - error = size <= 0 || (size_t)size >= capacity ? ENAMETOOLONG : 0; -done: - close(cwd); - return error; + return open(proc, O_PATH | O_DIRECTORY | O_CLOEXEC); } /* The real socket descriptor was already pinned for the exact notifying thread. @@ -137,25 +117,22 @@ static int private_endpoint(struct sockaddr_storage *storage, socklen_t length, size_t count = length - offsetof(struct sockaddr_un, sun_path); memcpy(path, address->sun_path, count); path[count] = '\0'; - char relative[4096]; - const char *selected = relative; - if (path[0] == '/') { - size_t prefix = strlen(private_path); - if (prefix >= strlen(path) || strncmp(path, private_path, prefix) != 0 || - path[prefix] != '/') return EPERM; - selected = path + prefix + 1; - } else { - int error = private_relative(tid, path, relative, sizeof(relative)); - if (error != 0) return error; + int cwd = -1; + if (path[0] != '/') { + cwd = private_context(tid); + if (cwd < 0) return errno; } + /* Ordinary symlinks may resolve to scratch. Magic links are not pathname + * authority; only the final pinned socket's protected mount grants access. */ struct open_how how = { .flags = O_PATH | O_CLOEXEC, - .resolve = RESOLVE_BENEATH | RESOLVE_NO_MAGICLINKS | RESOLVE_NO_SYMLINKS }; - int fd = syscall(SYS_openat2, private_root, selected, &how, sizeof(how)); - if (fd < 0) return errno; - struct stat info; - if (fstat(fd, &info) != 0 || !S_ISSOCK(info.st_mode)) { + .resolve = RESOLVE_NO_MAGICLINKS }; + int fd = syscall(SYS_openat2, cwd < 0 ? AT_FDCWD : cwd, path, &how, sizeof(how)); + int error = errno; + if (cwd >= 0) close(cwd); + if (fd < 0) return error; + if (!private_socket_mount(fd)) { close(fd); - return ENOTSOCK; + return EPERM; } *endpoint = fd; return 0; From 4d7b13ec7177680ccb6dcbf73d4bf06c94f25c11 Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 12:40:37 -0400 Subject: [PATCH 11/21] test(plugins): inspect accepted UNIX peer identity --- .github/workflows/plugin-linux-ipc.yml | 21 + .../examples/plugin_unix_socket_probe.rs | 52 + .../tests/fixtures/plugin_unix_socket.c | 34 + .../linux-private-aliases.md | 25 +- .../linux-private-peer-identity.md | 43 + .../linux-private-stream-integration.md | 4 +- .../native-host-integration.md | 3 + .../linux-ipc-broker-private-stream.json | 914 ++++++++++++++++++ .../arm64/private-stream-no-alias.log | 6 + .../arm64/private-stream-no-mount.log | 4 + .../arm64/private-stream-wrong-cwd.log | 6 + .../x64/linux-ipc-broker-private-stream.json | 914 ++++++++++++++++++ .../x64/private-stream-no-alias.log | 6 + .../x64/private-stream-no-mount.log | 4 + .../x64/private-stream-wrong-cwd.log | 6 + 15 files changed, 2039 insertions(+), 3 deletions(-) create mode 100644 openspec/changes/complete-plugin-hook-runtime/linux-private-peer-identity.md create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/linux-ipc-broker-private-stream.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/private-stream-no-alias.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/private-stream-no-mount.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/private-stream-wrong-cwd.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/linux-ipc-broker-private-stream.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/private-stream-no-alias.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/private-stream-no-mount.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/private-stream-wrong-cwd.log diff --git a/.github/workflows/plugin-linux-ipc.yml b/.github/workflows/plugin-linux-ipc.yml index 1deb0bfa9..2d00467f3 100644 --- a/.github/workflows/plugin-linux-ipc.yml +++ b/.github/workflows/plugin-linux-ipc.yml @@ -134,6 +134,27 @@ jobs: target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/socket-broker-audit" "$RUNNER_TEMP/linux-ipc-broker-saturation.json" --broker-saturation target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/broker-private-stream" "$RUNNER_TEMP/linux-ipc-broker-private-stream.json" --broker-private-stream target/debug/examples/plugin_unix_socket_probe "$RUNNER_TEMP/broker-private-stream-mutation" "$RUNNER_TEMP/linux-ipc-broker-private-stream-mutation.json" --broker-private-stream-mutation + - name: Record accepted-side kernel peer identity compatibility + shell: bash + run: | + set -euo pipefail + python3 - "$RUNNER_TEMP/linux-ipc-broker-private-stream.json" <<'PY' + import json + import sys + report = json.load(open(sys.argv[1])) + rows = [row for row in report['rows'] if row.get('mode') == 'peer-identity'] + assert len(rows) == 4, rows + for row in rows: + control, observed = row['unconfined_control'], row['observed'] + assert control['exchanged'] and control['peer_checks'] == 1, row + assert control['peer_matches'] and control['client_peer_matches'], row + assert control['accepted_pid'] == control['expected_pid'], row + assert observed['exchanged'] and observed['peer_checks'] == 1, row + assert observed['client_peer_matches'], row + assert observed['accepted_pid'] != observed['expected_pid'], row + assert not observed['peer_matches'] and not row['compatibility_accepted'], row + print('Recorded accepted-side peer PID mismatch in all four capability combinations; full IPC acceptance remains open') + PY - name: Reject pathname re-resolution after private endpoint pinning shell: bash run: | diff --git a/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs b/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs index d97ee00f3..4c701bfdb 100644 --- a/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs +++ b/crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs @@ -259,6 +259,55 @@ mod probe { } } + fn peer_identity_row(policy: &LinuxPolicy<'_>) -> Value { + let target_args = [ + policy.target_args[0].clone(), + policy.target_args[1].clone(), + "peer-identity".into(), + policy + .scratch + .join("identity.sock") + .to_str() + .unwrap() + .into(), + ]; + let control: Value = serde_json::from_slice( + &run(Command::new(policy.target).args(&target_args).env_clear()).stdout, + ) + .unwrap(); + assert_eq!( + control["exchanged"], true, + "unconfined peer exchange: {control}" + ); + assert_eq!(control["peer_checks"], 1); + assert_eq!( + control["peer_matches"], true, + "unconfined accepted peer: {control}" + ); + assert_eq!(control["client_peer_matches"], true); + let observed = observe( + &LinuxPolicy { + target_args: &target_args, + ..*policy + }, + Mode::BrokerPrivateStream, + ); + assert_eq!( + observed["exchanged"], true, + "broker peer exchange: {observed}" + ); + assert_eq!(observed["peer_checks"], 1); + assert_eq!( + observed["client_peer_matches"], true, + "broker listener identity: {observed}" + ); + // Record the accepted side honestly. A successful byte exchange cannot + // turn a peer-identity mismatch into private IPC compatibility. + json!({"mode":"peer-identity", "fs_read":policy.fs_read, "fs_write":policy.fs_write, + "shell":false,"compatibility_accepted":observed["peer_matches"] == true, + "unconfined_control":control,"observed":observed}) + } + fn candidate_rows( policy: LinuxPolicy<'_>, listener: &UnixListener, @@ -266,6 +315,9 @@ mod probe { mode: Mode, ) -> Vec { let mut rows = Vec::new(); + if mode == Mode::BrokerPrivateStream && label == "outside" { + rows.push(peer_identity_row(&policy)); + } if mode == Mode::BrokerPrivateStreamMutation && label == "outside" { let observed = super::cancellation::observe_unix_mutation(&policy, listener); rows.push(json!({"mode":"unix-mutation","socket":label, diff --git a/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c b/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c index 22d44634d..f589beb4d 100644 --- a/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c +++ b/crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c @@ -26,6 +26,28 @@ static int abi(void) { #endif } +#ifdef __linux__ +static int peer_checks, peer_matches = 1, client_peer_matches = 1; +static int peer_pid = -1, client_peer_pid = -1; +static void record_peer_identity(int client, int peer) { + struct ucred accepted = {0}, listener = {0}; + socklen_t accepted_size = sizeof(accepted), listener_size = sizeof(listener); + int accepted_ok = getsockopt(peer, SOL_SOCKET, SO_PEERCRED, &accepted, &accepted_size) == 0 && + accepted_size == sizeof(accepted); + int listener_ok = getsockopt(client, SOL_SOCKET, SO_PEERCRED, &listener, &listener_size) == 0 && + listener_size == sizeof(listener); + peer_checks++; + peer_pid = accepted_ok ? accepted.pid : -1; + client_peer_pid = listener_ok ? listener.pid : -1; + peer_matches = peer_matches && accepted_ok && accepted.pid == getpid() && + accepted.uid == getuid() && accepted.gid == getgid(); + client_peer_matches = client_peer_matches && listener_ok && listener.pid == getpid() && + listener.uid == getuid() && listener.gid == getgid(); +} +#else +static void record_peer_identity(int client, int peer) { (void)client; (void)peer; } +#endif + static int local_exchange_to(int family, const char *path, int server, const char *destination) { int client = -1, peer = -1, ok = 0; struct sockaddr_storage storage = {0}; @@ -58,6 +80,7 @@ static int local_exchange_to(int family, const char *path, int server, const cha ok = peer >= 0 && send(client, "fixture-only", 12, MSG_NOSIGNAL) == 12 && recv(peer, token, sizeof(token), MSG_WAITALL) == 12 && memcmp(token, "fixture-only", 12) == 0 && send(peer, "A", 1, MSG_NOSIGNAL) == 1 && recv(client, &ack, 1, MSG_WAITALL) == 1 && ack == 'A'; + if (ok && family == AF_UNIX) record_peer_identity(client, peer); done: if (peer >= 0) close(peer); if (client >= 0) close(client); @@ -221,6 +244,17 @@ int main(int argc, char **argv) { if (argc == 4 && strcmp(argv[3], "mutation") == 0) return mutation_probe(); if (argc == 4 && strcmp(argv[3], "escape") == 0) return escape_probe(); if (argc == 4 && strcmp(argv[3], "saturation") == 0) return saturation_probe(); +#ifdef __linux__ + if (argc == 5 && strcmp(argv[3], "peer-identity") == 0) { + int exchanged = local_exchange(AF_UNIX, argv[4], -1); + printf("{\"started\":true,\"exchanged\":%s,\"peer_checks\":%d," + "\"expected_pid\":%d,\"accepted_pid\":%d,\"client_peer_pid\":%d," + "\"peer_matches\":%s,\"client_peer_matches\":%s}\n", + exchanged ? "true" : "false", peer_checks, (int)getpid(), peer_pid, client_peer_pid, + peer_matches ? "true" : "false", client_peer_matches ? "true" : "false"); + return 0; + } +#endif if (argc == 5 && strcmp(argv[3], "unix-mutation") == 0) return unix_mutation_probe(argv[1], argv[4]); if (argc >= 4) { if (strcmp(argv[3], "pair") != 0) return 2; diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-aliases.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-aliases.md index b0810792e..c419ed1b4 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-aliases.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-aliases.md @@ -49,8 +49,29 @@ Local checks cover portable C syntax, Rust example Clippy, intercepted candidate transformations, Python/workflow syntax and spec validation. An unconfined macOS component check exercises all six positive fixture exchanges and both reachable owned host controls, adapting O_PATH/CLOEXEC flags for that platform. It does not -test Linux flags, mount identity or confinement. Hosted Linux x64/arm64 results -for this extension remain pending. +test Linux flags, mount identity or confinement. The hosted result below supplies +Linux evidence for the exact tested revision. + +## Native result for 2f1fee99 + +[Run 41091051579](https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41091051579) +passes both Linux jobs. Each architecture has 32 socket rows: 16 direct host +denials and 16 pair cases. All six pathname forms exchange successfully in every +pair case, while direct and symlink escapes neither connect nor send and the +owned host listeners receive no token. Independent read/write expectations and +the original broker/runtime regression matrices pass. + +Wrong-CWD lookup fails its named relative-root exchange. Removing only the mount +guard actually delivers to the owned outside listener and fails the named +socket-denial assertion. Adding NO_SYMLINKS preserves absolute scratch, +relative-root and outside-CWD exchanges, then fails the named relative-alias +assertion. Original socket reports and the three logs are retained under +`scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/{x64,arm64}`. +They bind tested merge `4d8c4576b941f32fdcad6dc97c0c6e8396e28108`, whose tree +equals source `2f1fee99b730db5d3d37876b603e5c059399088d`, and source manifest +SHA-256 `ca4ffbe66815bc3a696f0296c9ffbe978244b0d511fc09c65c3d802409a4da52`. +Tree equality and the manifest were independently verified. These receipts do +not cover the subsequent peer-identity diagnostic. Datagram/seqpacket, destination-bearing sends, ancillary and peer identity, proxy/network intersections and production admission/settlement remain required. diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-peer-identity.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-peer-identity.md new file mode 100644 index 000000000..e1f8ab39a --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-peer-identity.md @@ -0,0 +1,43 @@ +# Kernel peer identity diagnostic + +Status: diagnostic implementation; hosted execution pending. Full private IPC +acceptance and production native activation remain open. + +The approved broker direction preserves full private IPC compatibility as a +requirement. Its byte-exchange controls do not establish the accepted socket's +kernel peer identity. The candidate currently emulates connect in an owned worker +using a pinned copy of the guest socket. That needs a separate SO_PEERCRED check. + +In the [Linux 6.9 UNIX socket implementation](https://github.com/torvalds/linux/blob/v6.9/net/unix/af_unix.c#L1507-L1541), +the accepted-side socket receives credentials initialized from the task doing +connect. The client receives the listener's credentials. This suggests that +worker emulation can preserve the client's view of the listener while changing +the listener's view of the caller. This is a source-based inference until the +native diagnostic supplies actual observations for the tested kernels. + +The fixture creates its listener and client in the same process and exchanges +a real token and acknowledgement. It reads SO_PEERCRED from both sockets and +compares PID, UID and GID with its own identity. Its output records the actual +PID values, syscall-check count and combined identity matches. + +For each read/write capability combination, the owner first runs an unconfined +control and requires both identities to match. It then runs the same fixture +under the private-stream broker, requiring exchange and listener identity to +work, but recording accepted-side identity separately. The report marks +`compatibility_accepted` from the actual match, without equating exchange with +compatibility. The workflow currently expects the source-predicted accepted PID +mismatch as a counterexample; a successful diagnostic is not acceptance of that +behavior. Startup refusal or failed exchange cannot satisfy the counterexample. + +If native execution confirms this mismatch, it is a concrete unresolved +compatibility issue for the approved strategy. Return that evidence for the +required design/support review before activation. Do not silently accept a +worker identity, weaken the requirement or advertise the green diagnostic as +completed IPC support. Kernel-enforced endpoint policy that permits the guest's +own connect, or a complete protected endpoint view, would require separate +proof of both isolation and identity semantics. + +Local checks cover Rust example Clippy, portable C syntax excluding Linux-only +bodies, and workflow shell/embedded Python syntax. Linux SO_PEERCRED behavior +requires hosted x64/arm64 execution. Datagram/seqpacket, ancillary behavior, +proxy/network intersections and production resource ownership also remain open. diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md index ae5235ee8..3d5e0d3da 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md @@ -94,7 +94,9 @@ has source-bound passing x64/arm64 evidence. The scratch-relative handling with retained x64/arm64 evidence. The [runtime API exchange extension](linux-private-runtime-ipc.md) adds acceptance for each runtime's own private pathname socket operations with retained passing -x64/arm64 results. The alias extension's native results remain pending. +x64/arm64 results. The alias extension also has source-bound passing native +results. The [peer-identity diagnostic](linux-private-peer-identity.md) separately +tests accepted-side kernel credentials; its execution remains pending. Still required before complete IPC/production acceptance: verified post-pin replacement, relative/alias forms, datagram/seqpacket and diff --git a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md index 7ede07e7b..0b87aa5b1 100644 --- a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md @@ -115,6 +115,9 @@ App's legacy launch path does not implement this sequence today. private pathname exchanges from each supported runtime. These increments do not complete this task. The [alias extension](linux-private-aliases.md) covers safe symlinks and outside-scratch caller contexts through pinned mount identity. + The [kernel peer identity diagnostic](linux-private-peer-identity.md) separately + checks the listener's view of a broker-emulated caller; data exchange alone + cannot establish that compatibility. - [ ] N3 Implement registry-owned generation admission and immutable resource binding with actual production startup, revocation and quarantine tests. - [ ] N4 Integrate the native launch owner and independently intersect all diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/linux-ipc-broker-private-stream.json b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/linux-ipc-broker-private-stream.json new file mode 100644 index 000000000..70de06457 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/linux-ipc-broker-private-stream.json @@ -0,0 +1,914 @@ +{ + "platform": "linux", + "architecture": "aarch64", + "checkout": "4d8c4576b941f32fdcad6dc97c0c6e8396e28108", + "run_id": "41091051579", + "candidate": true, + "landlock9": false, + "socket_broker": true, + "private_stream_probe": true, + "unix_mutation_probe": false, + "cancellation_probe": false, + "mutation_probe": false, + "escape_probe": null, + "saturation_probe": false, + "sources": [ + "crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h", + "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", + "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", + "crates/cyber-sandbox/src/plugin_policy.rs", + "crates/cyber-sandbox/src/plugin_policy/linux.rs", + "crates/cyber-sandbox/native/linux_plugin_exec.c", + "crates/cyber-sandbox/native/linux_filter.h", + "crates/cyber-sandbox/native/linux_initial_exec.h", + "crates/cyber-sandbox/src/native_exec.rs", + "crates/cyber-sandbox/src/bin/cyber-sandbox-exec.rs", + "crates/cyber-sandbox/build.rs", + "crates/cyber-sandbox/Cargo.toml", + "Cargo.lock", + ".github/workflows/plugin-linux-ipc.yml", + "scripts/probes/plugin-native-entry/linux_socket_candidate.h", + "scripts/probes/plugin-native-entry/linux_socket_broker.h", + "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", + "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", + "scripts/probes/plugin-native-entry/linux_unix9_policy.h", + "scripts/probes/plugin-native-entry/build_socket_candidate.py" + ], + "source_sha256": "ca4ffbe66815bc3a696f0296c9ffbe978244b0d511fc09c65c3d802409a4da52", + "helper_sha256": "565633f7644917046571aa9139a7880deef6423dfb999448c81eff676ab31419", + "rows": [ + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + } + ], + "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/private-stream-no-alias.log b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/private-stream-no-alias.log new file mode 100644 index 000000000..7f74c2c34 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/private-stream-no-alias.log @@ -0,0 +1,6 @@ + +thread 'main' (5811) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:211:13: +assertion `left == right` failed: private relative stream exchange: alias_relative_roundtrip: {"started":true,"connected":false,"sent":false,"project_read":false,"pair_roundtrip":true,"pair_disconnect":false,"pair_reconnect":false,"pair_bind":false,"pair_listen":false,"pair_sendto":false,"pair_sendmsg":false,"datagram_pair":false,"seqpacket_pair":false,"landlock_abi":8,"tcp_roundtrip":true,"thread_tcp_roundtrip":true,"scratch_unix_roundtrip":true,"regular_reparent":false,"cross_mount_alias_errno":18,"relative_root_roundtrip":true,"relative_parent_roundtrip":true,"relative_escape_connected":false,"relative_escape_sent":false,"outside_cwd_roundtrip":true,"alias_relative_roundtrip":false,"alias_absolute_roundtrip":false,"alias_directory_roundtrip":false,"alias_escape_connected":false,"alias_escape_sent":false} + left: Bool(false) + right: true +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/private-stream-no-mount.log b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/private-stream-no-mount.log new file mode 100644 index 000000000..036e7aa54 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/private-stream-no-mount.log @@ -0,0 +1,4 @@ + +thread 'main' (5798) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:425:21: +socket denial: outside: {"host_received_fixture":true,"observed":{"started":true,"connected":true,"sent":true,"errno":0,"project_read":false,"landlock_abi":8}} +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/private-stream-wrong-cwd.log b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/private-stream-wrong-cwd.log new file mode 100644 index 000000000..97d9d4f42 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/arm64/private-stream-wrong-cwd.log @@ -0,0 +1,6 @@ + +thread 'main' (5774) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:211:13: +assertion `left == right` failed: private relative stream exchange: relative_root_roundtrip: {"started":true,"connected":false,"sent":false,"project_read":false,"pair_roundtrip":true,"pair_disconnect":false,"pair_reconnect":false,"pair_bind":false,"pair_listen":false,"pair_sendto":false,"pair_sendmsg":false,"datagram_pair":false,"seqpacket_pair":false,"landlock_abi":8,"tcp_roundtrip":true,"thread_tcp_roundtrip":true,"scratch_unix_roundtrip":true,"regular_reparent":false,"cross_mount_alias_errno":18,"relative_root_roundtrip":false,"relative_parent_roundtrip":false,"relative_escape_connected":false,"relative_escape_sent":false,"outside_cwd_roundtrip":false,"alias_relative_roundtrip":true,"alias_absolute_roundtrip":true,"alias_directory_roundtrip":true,"alias_escape_connected":false,"alias_escape_sent":false} + left: Bool(false) + right: true +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/linux-ipc-broker-private-stream.json b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/linux-ipc-broker-private-stream.json new file mode 100644 index 000000000..77519cfbe --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/linux-ipc-broker-private-stream.json @@ -0,0 +1,914 @@ +{ + "platform": "linux", + "architecture": "x86_64", + "checkout": "4d8c4576b941f32fdcad6dc97c0c6e8396e28108", + "run_id": "41091051579", + "candidate": true, + "landlock9": false, + "socket_broker": true, + "private_stream_probe": true, + "unix_mutation_probe": false, + "cancellation_probe": false, + "mutation_probe": false, + "escape_probe": null, + "saturation_probe": false, + "sources": [ + "crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h", + "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", + "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", + "crates/cyber-sandbox/src/plugin_policy.rs", + "crates/cyber-sandbox/src/plugin_policy/linux.rs", + "crates/cyber-sandbox/native/linux_plugin_exec.c", + "crates/cyber-sandbox/native/linux_filter.h", + "crates/cyber-sandbox/native/linux_initial_exec.h", + "crates/cyber-sandbox/src/native_exec.rs", + "crates/cyber-sandbox/src/bin/cyber-sandbox-exec.rs", + "crates/cyber-sandbox/build.rs", + "crates/cyber-sandbox/Cargo.toml", + "Cargo.lock", + ".github/workflows/plugin-linux-ipc.yml", + "scripts/probes/plugin-native-entry/linux_socket_candidate.h", + "scripts/probes/plugin-native-entry/linux_socket_broker.h", + "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", + "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", + "scripts/probes/plugin-native-entry/linux_unix9_policy.h", + "scripts/probes/plugin-native-entry/build_socket_candidate.py" + ], + "source_sha256": "ca4ffbe66815bc3a696f0296c9ffbe978244b0d511fc09c65c3d802409a4da52", + "helper_sha256": "a2167ac308f9a9775424484bed23134eb58404f737c9354dd815ebce2509dee4", + "rows": [ + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + } + ], + "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/private-stream-no-alias.log b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/private-stream-no-alias.log new file mode 100644 index 000000000..43ffdfa1e --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/private-stream-no-alias.log @@ -0,0 +1,6 @@ + +thread 'main' (5846) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:211:13: +assertion `left == right` failed: private relative stream exchange: alias_relative_roundtrip: {"started":true,"connected":false,"sent":false,"project_read":false,"pair_roundtrip":true,"pair_disconnect":false,"pair_reconnect":false,"pair_bind":false,"pair_listen":false,"pair_sendto":false,"pair_sendmsg":false,"datagram_pair":false,"seqpacket_pair":false,"landlock_abi":8,"tcp_roundtrip":true,"thread_tcp_roundtrip":true,"scratch_unix_roundtrip":true,"regular_reparent":false,"cross_mount_alias_errno":18,"relative_root_roundtrip":true,"relative_parent_roundtrip":true,"relative_escape_connected":false,"relative_escape_sent":false,"outside_cwd_roundtrip":true,"alias_relative_roundtrip":false,"alias_absolute_roundtrip":false,"alias_directory_roundtrip":false,"alias_escape_connected":false,"alias_escape_sent":false} + left: Bool(false) + right: true +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/private-stream-no-mount.log b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/private-stream-no-mount.log new file mode 100644 index 000000000..b4d037142 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/private-stream-no-mount.log @@ -0,0 +1,4 @@ + +thread 'main' (5833) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:425:21: +socket denial: outside: {"host_received_fixture":true,"observed":{"started":true,"connected":true,"sent":true,"errno":0,"project_read":false,"landlock_abi":8}} +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/private-stream-wrong-cwd.log b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/private-stream-wrong-cwd.log new file mode 100644 index 000000000..a860985c1 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-aliases-2f1fee99/x64/private-stream-wrong-cwd.log @@ -0,0 +1,6 @@ + +thread 'main' (5809) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:211:13: +assertion `left == right` failed: private relative stream exchange: relative_root_roundtrip: {"started":true,"connected":false,"sent":false,"project_read":false,"pair_roundtrip":true,"pair_disconnect":false,"pair_reconnect":false,"pair_bind":false,"pair_listen":false,"pair_sendto":false,"pair_sendmsg":false,"datagram_pair":false,"seqpacket_pair":false,"landlock_abi":8,"tcp_roundtrip":true,"thread_tcp_roundtrip":true,"scratch_unix_roundtrip":true,"regular_reparent":false,"cross_mount_alias_errno":18,"relative_root_roundtrip":false,"relative_parent_roundtrip":false,"relative_escape_connected":false,"relative_escape_sent":false,"outside_cwd_roundtrip":false,"alias_relative_roundtrip":true,"alias_absolute_roundtrip":true,"alias_directory_roundtrip":true,"alias_escape_connected":false,"alias_escape_sent":false} + left: Bool(false) + right: true +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace From cb385fdb547d102be44fb3a519af4c7e6a38acba Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 12:47:45 -0400 Subject: [PATCH 12/21] docs(plugins): record peer identity gap and mediation revision --- docs/goal-delivery.md | 8 + .../linux-kernel-unix-revision.md | 89 ++ .../linux-private-peer-identity.md | 41 +- .../linux-private-stream-integration.md | 3 +- .../native-host-integration.md | 6 + .../linux-ipc-broker-private-stream.json | 1022 +++++++++++++++++ .../arm64/linux-ipc-unix9-availability.json | 10 + .../arm64/unix9-unavailable.log | 4 + .../x64/linux-ipc-broker-private-stream.json | 1022 +++++++++++++++++ .../x64/linux-ipc-unix9-availability.json | 10 + .../x64/unix9-unavailable.log | 4 + 11 files changed, 2210 insertions(+), 9 deletions(-) create mode 100644 openspec/changes/complete-plugin-hook-runtime/linux-kernel-unix-revision.md create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/arm64/linux-ipc-broker-private-stream.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/arm64/linux-ipc-unix9-availability.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/arm64/unix9-unavailable.log create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/x64/linux-ipc-broker-private-stream.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/x64/linux-ipc-unix9-availability.json create mode 100644 scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/x64/unix9-unavailable.log diff --git a/docs/goal-delivery.md b/docs/goal-delivery.md index 774866df4..4bd3204c2 100644 --- a/docs/goal-delivery.md +++ b/docs/goal-delivery.md @@ -62,3 +62,11 @@ Linux UNIX-socket diagnostic found a real host-reachability gap. Its experimenta filter and runtime checks remain experimental. The broker direction is approved; complete support acceptance and host activation remain pending. Daily coding and binary editor implementation have not started. The linked task lists remain authoritative for completion. + +The [Linux peer-identity diagnostic](../openspec/changes/complete-plugin-hook-runtime/linux-private-peer-identity.md) +confirms that the current broker changes the caller PID observed by a UNIX +listener, despite successful data exchange. The +[kernel UNIX revision](../openspec/changes/complete-plugin-hook-runtime/linux-kernel-unix-revision.md) +is a concrete proposal awaiting review. It does not reduce IPC requirements or +authorize a new production support floor. Preserve this review gate before +production activation or protocol-feature integration. diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-kernel-unix-revision.md b/openspec/changes/complete-plugin-hook-runtime/linux-kernel-unix-revision.md new file mode 100644 index 000000000..92810402d --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/linux-kernel-unix-revision.md @@ -0,0 +1,89 @@ +# Linux UNIX mediation revision for review + +Status: proposal for review, not an approved support change or production +activation. The original plugins/hooks, daily-coding and binary-editor scope +remains required. The previously approved broker direction remains the recorded +decision until the user reviews this revision. + +## Problem and evidence gate + +The [peer-identity diagnostic](linux-private-peer-identity.md) confirms a caller +PID mismatch on both Linux x64 and arm64 in +[run 41092065028](https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41092065028). +All four read/write combinations exchange real data, but the listener sees PID 4 +instead of caller PID 3. Positive unconfined controls report the actual caller +at both ends. Source-bound reports explicitly mark compatibility unaccepted; +their source manifest and tested-merge/tree equality have been verified. +Successful exchange alone is insufficient. + +The current hosted Linux kernels expose Landlock ABI 8. The existing ABI-9 +alternative explicitly refuses there; it has no positive native acceptance on +those hosts. This proposal does not turn that refusal into support evidence. + +## Recommended direction + +Evaluate kernel-enforced pathname UNIX policy as the Linux path to full private +IPC compatibility. Require actual support for Landlock's RESOLVE_UNIX right +(ABI 9 or later), socket creation restrictions, private namespaces and the other +existing filesystem/initial-exec boundaries. Admit only after feature checks and +positive execution establish the complete contract. This changes the proposed +Linux capability dependency and therefore requires review; it does not weaken +IPC behavior or authorize production activation. + +UNIX connect and destination-bearing sends execute in the guest under kernel +endpoint enforcement, preserving native caller context. Retain private network +and IPC namespaces, dropped capabilities, descriptor sanitation and immutable +inherited execution restrictions. Preserve real private IP bind/listen and +stream/datagram/seqpacket behavior. Host-facing traffic continues only through +the exact owned proxy and its effective allowlist/secret intersection. + +Do not inspect a descriptor in a notification and then CONTINUE merely because +it was UNIX at inspection time. A concurrent replacement could change the object +before the real syscall. Any direct syscall path must have its complete boundary +enforced at actual execution, including the effective network ceiling. + +The existing ABI-9 experiment is a starting point, not a ready implementation. +Its profile validation, socket provenance, owner lifetime, complete endpoint +policy and proxy composition still need implementation and adversarial review. +Keep production App activation and protocol-feature integration behind the +existing native proof/design gate. + +## Implementation and acceptance sequence + +- [ ] R1 Review this changed Linux dependency and direction with the user. +- [ ] R2 Provision isolated Linux x64 and arm64 test environments with actual + required kernel/LSM features. Pin and record kernel/image inputs and verify + their provenance. Record ABI and enabled features at execution; do not infer + support from a version string. Do not replace the user's host kernel. +- [ ] R3 Require direct native positive exchanges for pathname and abstract + stream/datagram/seqpacket sockets, pairs, named sendto/sendmsg, reconnect, + relative and symlink forms, ancillary FD/credential passing and peer identity. + Pair positive unconfined controls with denied actual host-listener delivery. +- [ ] R4 Add concurrent pathname/FD/address replacement and inherited descendant + cases. The kernel must authorize the endpoint used by the actual operation. + Omitting the exact UNIX policy must reach an owned host endpoint and fail its + named isolation assertion; generic launch failure cannot satisfy the control. +- [ ] R5 Run Node, Python, Bun, Deno and native runtime capability matrices on + both architectures, including real tool execution and private IPC. Verify + independent read/write/shell grants, effective proxy/network/secret ceilings + and resource settlement. Retain source-bound reports and exact controls. +- [ ] R6 Return complete evidence for support/activation review, then finish the + existing N3–N7 production ownership, integration and acceptance tasks. Update + README/support documentation in the same production behavior change. + +Older kernels without proven equivalent enforcement remain explicitly unsupported +for this proposed path. Startup refusal must explain the missing feature and +cannot retry in an ordinary tool sandbox or count as positive acceptance. +No required runtime, private IPC behavior or other goal feature is removed. + +## Alternative if older-kernel support remains required + +Investigate a protected filesystem endpoint view that excludes foreign sockets +while allowing the guest's own native operations. This must preserve required +file visibility/write semantics and live changes, exclude aliases and concurrent +foreign endpoint insertion, retain private process/network isolation and prove +the same IPC/runtime contract. The existing direct bind-mounted Location is not +such a view. This is a separate, more extensive design/proof effort, not a reason +to accept worker identity or limit IPC to the current stream candidate. + +Neither route is complete. The original parent task checkboxes remain open. diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-peer-identity.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-peer-identity.md index e1f8ab39a..191e96d4f 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-peer-identity.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-peer-identity.md @@ -1,7 +1,8 @@ # Kernel peer identity diagnostic -Status: diagnostic implementation; hosted execution pending. Full private IPC -acceptance and production native activation remain open. +Status: accepted-side PID mismatch confirmed on Linux x64 and arm64. Full private +IPC acceptance and production native activation remain open. The +[kernel UNIX revision](linux-kernel-unix-revision.md) is proposed for review. The approved broker direction preserves full private IPC compatibility as a requirement. Its byte-exchange controls do not establish the accepted socket's @@ -12,8 +13,9 @@ In the [Linux 6.9 UNIX socket implementation](https://github.com/torvalds/linux/ the accepted-side socket receives credentials initialized from the task doing connect. The client receives the listener's credentials. This suggests that worker emulation can preserve the client's view of the listener while changing -the listener's view of the caller. This is a source-based inference until the -native diagnostic supplies actual observations for the tested kernels. +the listener's view of the caller. The native diagnostic below confirms the +mismatch on the tested kernels; it does not prove every possible broker design +has the same limitation. The fixture creates its listener and client in the same process and exchanges a real token and acknowledgement. It reads SO_PEERCRED from both sockets and @@ -29,15 +31,38 @@ compatibility. The workflow currently expects the source-predicted accepted PID mismatch as a counterexample; a successful diagnostic is not acceptance of that behavior. Startup refusal or failed exchange cannot satisfy the counterexample. -If native execution confirms this mismatch, it is a concrete unresolved -compatibility issue for the approved strategy. Return that evidence for the +Native execution confirms this mismatch, a concrete unresolved compatibility +issue for the current implementation of the approved strategy. Return the evidence for the required design/support review before activation. Do not silently accept a worker identity, weaken the requirement or advertise the green diagnostic as completed IPC support. Kernel-enforced endpoint policy that permits the guest's own connect, or a complete protected endpoint view, would require separate proof of both isolation and identity semantics. +## Native result for 4d7b13ec + +[Run 41092065028](https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41092065028) +passes both Linux jobs by recording the expected counterexample. Each +architecture's report has 36 rows: the existing 32 socket rows and four +peer-identity diagnostic rows, one for each read/write combination. All four +unconfined controls exchange successfully and report the fixture's actual PID +at both ends. All four confined rows exchange successfully and correctly report +the listener as PID 3, but the accepted side reports PID 4 instead of caller PID 3. +Every diagnostic row explicitly records `compatibility_accepted: false`. + +Original socket reports, ABI availability reports and exact ABI-9 refusal logs +are retained under +`scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/{x64,arm64}`. +They bind tested merge `1f27f418bf3654e99e01e44f9d38760ff7f473c1`, whose tree +equals source `4d7b13ec7177680ccb6dcbf73d4bf06c94f25c11`, kernel +`7.0.0-1017-azure`, and source manifest SHA-256 +`97e1ca54276e939ba4abe7bb0e648ac9a74fec98da1010a85df64e821924dad7`. +The manifest and tree equality were independently verified. Both hosts report +Landlock ABI 8 and explicitly refuse the existing ABI-9 alternative. That +alternative's positive execution remains unverified. + Local checks cover Rust example Clippy, portable C syntax excluding Linux-only -bodies, and workflow shell/embedded Python syntax. Linux SO_PEERCRED behavior -requires hosted x64/arm64 execution. Datagram/seqpacket, ancillary behavior, +bodies, 21 workflow shell steps/14 embedded Python blocks, formatting/diff, +107 strict OpenSpec items and spec lint (zero errors, 25 warnings). The C build +emits two deprecated Seatbelt SDK warnings. Datagram/seqpacket, ancillary behavior, proxy/network intersections and production resource ownership also remain open. diff --git a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md index 3d5e0d3da..b4b451139 100644 --- a/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/linux-private-stream-integration.md @@ -96,7 +96,8 @@ scratch-relative handling with retained x64/arm64 evidence. The for each runtime's own private pathname socket operations with retained passing x64/arm64 results. The alias extension also has source-bound passing native results. The [peer-identity diagnostic](linux-private-peer-identity.md) separately -tests accepted-side kernel credentials; its execution remains pending. +confirms an accepted-side PID mismatch on both architectures. That compatibility +issue remains unresolved and requires the proposed design/support review. Still required before complete IPC/production acceptance: verified post-pin replacement, relative/alias forms, datagram/seqpacket and diff --git a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md index 0b87aa5b1..c00b16f07 100644 --- a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md @@ -5,6 +5,12 @@ implementation handoff after the #76 foundations milestone, not production activation or completed native support acceptance. The full plugins/hooks, daily-coding and binary-editor scope remains unchanged. +The [peer-identity result](linux-private-peer-identity.md) now confirms an +accepted-side caller PID mismatch in the current Linux broker. The +[kernel UNIX revision](linux-kernel-unix-revision.md) proposes a changed dependency +for review; it is not approved and does not replace the recorded direction yet. +Full IPC compatibility and the production activation gate remain unmet. + ## Approved implementation direction Continue the descriptor-pinned Linux broker toward production integration rather diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/arm64/linux-ipc-broker-private-stream.json b/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/arm64/linux-ipc-broker-private-stream.json new file mode 100644 index 000000000..fa1e88c6b --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/arm64/linux-ipc-broker-private-stream.json @@ -0,0 +1,1022 @@ +{ + "platform": "linux", + "architecture": "aarch64", + "checkout": "1f27f418bf3654e99e01e44f9d38760ff7f473c1", + "run_id": "41092065028", + "candidate": true, + "landlock9": false, + "socket_broker": true, + "private_stream_probe": true, + "unix_mutation_probe": false, + "cancellation_probe": false, + "mutation_probe": false, + "escape_probe": null, + "saturation_probe": false, + "sources": [ + "crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h", + "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", + "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", + "crates/cyber-sandbox/src/plugin_policy.rs", + "crates/cyber-sandbox/src/plugin_policy/linux.rs", + "crates/cyber-sandbox/native/linux_plugin_exec.c", + "crates/cyber-sandbox/native/linux_filter.h", + "crates/cyber-sandbox/native/linux_initial_exec.h", + "crates/cyber-sandbox/src/native_exec.rs", + "crates/cyber-sandbox/src/bin/cyber-sandbox-exec.rs", + "crates/cyber-sandbox/build.rs", + "crates/cyber-sandbox/Cargo.toml", + "Cargo.lock", + ".github/workflows/plugin-linux-ipc.yml", + "scripts/probes/plugin-native-entry/linux_socket_candidate.h", + "scripts/probes/plugin-native-entry/linux_socket_broker.h", + "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", + "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", + "scripts/probes/plugin-native-entry/linux_unix9_policy.h", + "scripts/probes/plugin-native-entry/build_socket_candidate.py" + ], + "source_sha256": "97e1ca54276e939ba4abe7bb0e648ac9a74fec98da1010a85df64e821924dad7", + "helper_sha256": "565633f7644917046571aa9139a7880deef6423dfb999448c81eff676ab31419", + "rows": [ + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "mode": "peer-identity", + "fs_read": false, + "fs_write": false, + "shell": false, + "compatibility_accepted": false, + "unconfined_control": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 5051, + "accepted_pid": 5051, + "client_peer_pid": 5051, + "peer_matches": true, + "client_peer_matches": true + }, + "observed": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 3, + "accepted_pid": 4, + "client_peer_pid": 3, + "peer_matches": false, + "client_peer_matches": true + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "mode": "peer-identity", + "fs_read": false, + "fs_write": true, + "shell": false, + "compatibility_accepted": false, + "unconfined_control": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 5076, + "accepted_pid": 5076, + "client_peer_pid": 5076, + "peer_matches": true, + "client_peer_matches": true + }, + "observed": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 3, + "accepted_pid": 4, + "client_peer_pid": 3, + "peer_matches": false, + "client_peer_matches": true + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "mode": "peer-identity", + "fs_read": true, + "fs_write": false, + "shell": false, + "compatibility_accepted": false, + "unconfined_control": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 5101, + "accepted_pid": 5101, + "client_peer_pid": 5101, + "peer_matches": true, + "client_peer_matches": true + }, + "observed": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 3, + "accepted_pid": 4, + "client_peer_pid": 3, + "peer_matches": false, + "client_peer_matches": true + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "mode": "peer-identity", + "fs_read": true, + "fs_write": true, + "shell": false, + "compatibility_accepted": false, + "unconfined_control": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 5126, + "accepted_pid": 5126, + "client_peer_pid": 5126, + "peer_matches": true, + "client_peer_matches": true + }, + "observed": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 3, + "accepted_pid": 4, + "client_peer_pid": 3, + "peer_matches": false, + "client_peer_matches": true + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + } + ], + "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/arm64/linux-ipc-unix9-availability.json b/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/arm64/linux-ipc-unix9-availability.json new file mode 100644 index 000000000..74d2e19dd --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/arm64/linux-ipc-unix9-availability.json @@ -0,0 +1,10 @@ +{ + "required_abi": 9, + "observed_abi": 8, + "available": false, + "acceptance": "unverified; kernel unsupported", + "checkout": "1f27f418bf3654e99e01e44f9d38760ff7f473c1", + "run_id": "41092065028", + "source_sha256": "97e1ca54276e939ba4abe7bb0e648ac9a74fec98da1010a85df64e821924dad7", + "scope": "Kernel availability only; refusal on an older kernel is not confinement acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/arm64/unix9-unavailable.log b/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/arm64/unix9-unavailable.log new file mode 100644 index 000000000..581543247 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/arm64/unix9-unavailable.log @@ -0,0 +1,4 @@ + +thread 'main' (6240) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:27:17: +fixture bootstrap failed: Output { status: ExitStatus(unix_wait_status(512)), stdout: "", stderr: "experimental pathname UNIX policy requires Landlock ABI >= 9 (observed 8)\nnative Landlock admission failed\n" } +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/x64/linux-ipc-broker-private-stream.json b/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/x64/linux-ipc-broker-private-stream.json new file mode 100644 index 000000000..ec6c0948d --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/x64/linux-ipc-broker-private-stream.json @@ -0,0 +1,1022 @@ +{ + "platform": "linux", + "architecture": "x86_64", + "checkout": "1f27f418bf3654e99e01e44f9d38760ff7f473c1", + "run_id": "41092065028", + "candidate": true, + "landlock9": false, + "socket_broker": true, + "private_stream_probe": true, + "unix_mutation_probe": false, + "cancellation_probe": false, + "mutation_probe": false, + "escape_probe": null, + "saturation_probe": false, + "sources": [ + "crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_socket.c", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_cancel.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_mutation.h", + "crates/cyber-sandbox/tests/fixtures/plugin_unix_relative.h", + "crates/cyber-sandbox/tests/fixtures/plugin_process_escape.h", + "crates/cyber-sandbox/tests/fixtures/plugin_socket_saturation.h", + "crates/cyber-sandbox/examples/support/plugin_socket_cancel.rs", + "crates/cyber-sandbox/src/plugin_policy.rs", + "crates/cyber-sandbox/src/plugin_policy/linux.rs", + "crates/cyber-sandbox/native/linux_plugin_exec.c", + "crates/cyber-sandbox/native/linux_filter.h", + "crates/cyber-sandbox/native/linux_initial_exec.h", + "crates/cyber-sandbox/src/native_exec.rs", + "crates/cyber-sandbox/src/bin/cyber-sandbox-exec.rs", + "crates/cyber-sandbox/build.rs", + "crates/cyber-sandbox/Cargo.toml", + "Cargo.lock", + ".github/workflows/plugin-linux-ipc.yml", + "scripts/probes/plugin-native-entry/linux_socket_candidate.h", + "scripts/probes/plugin-native-entry/linux_socket_broker.h", + "scripts/probes/plugin-native-entry/linux_socket_broker_mutation.h", + "scripts/probes/plugin-native-entry/linux_socket_private_stream.h", + "scripts/probes/plugin-native-entry/linux_socket_private_unix.h", + "scripts/probes/plugin-native-entry/linux_socket_landlock9.h", + "scripts/probes/plugin-native-entry/linux_unix9_policy.h", + "scripts/probes/plugin-native-entry/build_socket_candidate.py" + ], + "source_sha256": "97e1ca54276e939ba4abe7bb0e648ac9a74fec98da1010a85df64e821924dad7", + "helper_sha256": "a2167ac308f9a9775424484bed23134eb58404f737c9354dd815ebce2509dee4", + "rows": [ + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "mode": "peer-identity", + "fs_read": false, + "fs_write": false, + "shell": false, + "compatibility_accepted": false, + "unconfined_control": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 5145, + "accepted_pid": 5145, + "client_peer_pid": 5145, + "peer_matches": true, + "client_peer_matches": true + }, + "observed": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 3, + "accepted_pid": 4, + "client_peer_pid": 3, + "peer_matches": false, + "client_peer_matches": true + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "mode": "peer-identity", + "fs_read": false, + "fs_write": true, + "shell": false, + "compatibility_accepted": false, + "unconfined_control": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 5170, + "accepted_pid": 5170, + "client_peer_pid": 5170, + "peer_matches": true, + "client_peer_matches": true + }, + "observed": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 3, + "accepted_pid": 4, + "client_peer_pid": 3, + "peer_matches": false, + "client_peer_matches": true + } + }, + { + "socket": "outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "mode": "peer-identity", + "fs_read": true, + "fs_write": false, + "shell": false, + "compatibility_accepted": false, + "unconfined_control": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 5195, + "accepted_pid": 5195, + "client_peer_pid": 5195, + "peer_matches": true, + "client_peer_matches": true + }, + "observed": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 3, + "accepted_pid": 4, + "client_peer_pid": 3, + "peer_matches": false, + "client_peer_matches": true + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "mode": "peer-identity", + "fs_read": true, + "fs_write": true, + "shell": false, + "compatibility_accepted": false, + "unconfined_control": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 5220, + "accepted_pid": 5220, + "client_peer_pid": 5220, + "peer_matches": true, + "client_peer_matches": true + }, + "observed": { + "started": true, + "exchanged": true, + "peer_checks": 1, + "expected_pid": 3, + "accepted_pid": 4, + "client_peer_pid": 3, + "peer_matches": false, + "client_peer_matches": true + } + }, + { + "socket": "outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "public", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 13, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "private-mask", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 13, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": false, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": false, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": false, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": false, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": false, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "errno": 1, + "project_read": true, + "landlock_abi": 8 + } + }, + { + "socket": "symlink-outside", + "fs_read": true, + "fs_write": true, + "shell": false, + "mode": "pair", + "host_received_fixture": false, + "observed": { + "started": true, + "connected": false, + "sent": false, + "project_read": true, + "pair_roundtrip": true, + "pair_disconnect": false, + "pair_reconnect": false, + "pair_bind": false, + "pair_listen": false, + "pair_sendto": false, + "pair_sendmsg": false, + "datagram_pair": false, + "seqpacket_pair": false, + "landlock_abi": 8, + "tcp_roundtrip": true, + "thread_tcp_roundtrip": true, + "scratch_unix_roundtrip": true, + "regular_reparent": true, + "cross_mount_alias_errno": 18, + "relative_root_roundtrip": true, + "relative_parent_roundtrip": true, + "relative_escape_connected": false, + "relative_escape_sent": false, + "outside_cwd_roundtrip": true, + "alias_relative_roundtrip": true, + "alias_absolute_roundtrip": true, + "alias_directory_roundtrip": true, + "alias_escape_connected": false, + "alias_escape_sent": false + } + } + ], + "scope": "Fixture-owned socket, caller and worker observations in experimental helpers only. Proof rows are case-specific; no ambient service contact or production capability acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/x64/linux-ipc-unix9-availability.json b/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/x64/linux-ipc-unix9-availability.json new file mode 100644 index 000000000..74d2e19dd --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/x64/linux-ipc-unix9-availability.json @@ -0,0 +1,10 @@ +{ + "required_abi": 9, + "observed_abi": 8, + "available": false, + "acceptance": "unverified; kernel unsupported", + "checkout": "1f27f418bf3654e99e01e44f9d38760ff7f473c1", + "run_id": "41092065028", + "source_sha256": "97e1ca54276e939ba4abe7bb0e648ac9a74fec98da1010a85df64e821924dad7", + "scope": "Kernel availability only; refusal on an older kernel is not confinement acceptance." +} diff --git a/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/x64/unix9-unavailable.log b/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/x64/unix9-unavailable.log new file mode 100644 index 000000000..39bddbf03 --- /dev/null +++ b/scripts/probes/plugin-native-entry/evidence/linux-private-peer-4d7b13ec/x64/unix9-unavailable.log @@ -0,0 +1,4 @@ + +thread 'main' (6336) panicked at crates/cyber-sandbox/examples/plugin_unix_socket_probe.rs:27:17: +fixture bootstrap failed: Output { status: ExitStatus(unix_wait_status(512)), stdout: "", stderr: "experimental pathname UNIX policy requires Landlock ABI >= 9 (observed 8)\nnative Landlock admission failed\n" } +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace From e22ce12c35f2c871a35a8400e2793f666cb1b7bf Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 13:02:38 -0400 Subject: [PATCH 13/21] test(plugins): require macOS private UNIX runtime exchanges --- .../workflows/plugin-confinement-proof.yml | 32 +- .github/workflows/plugin-native-launcher.yml | 4 +- .../macos-private-runtime-ipc.md | 57 ++ .../native-host-integration.md | 2 + scripts/probes/plugin-confinement/README.md | 17 + .../missing-grant.log | 31 + .../macos-private-unix-local/native.json | 543 +++++++++++++++++ .../macos-private-unix-local/node.json | 462 +++++++++++++++ .../packaged-native.json | 549 ++++++++++++++++++ .../packaged-node.json | 468 +++++++++++++++ .../packaged-python.json | 459 +++++++++++++++ .../macos-private-unix-local/python.json | 453 +++++++++++++++ scripts/probes/plugin-confinement/run.mts | 27 +- 13 files changed, 3091 insertions(+), 13 deletions(-) create mode 100644 openspec/changes/complete-plugin-hook-runtime/macos-private-runtime-ipc.md create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-unix-local/missing-grant.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-unix-local/native.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-unix-local/node.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-unix-local/packaged-native.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-unix-local/packaged-node.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-unix-local/packaged-python.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-unix-local/python.json diff --git a/.github/workflows/plugin-confinement-proof.yml b/.github/workflows/plugin-confinement-proof.yml index 027ea1567..70c671d8a 100644 --- a/.github/workflows/plugin-confinement-proof.yml +++ b/.github/workflows/plugin-confinement-proof.yml @@ -146,8 +146,35 @@ jobs: # matching-identity counterexamples and descriptor isolation. # The historical re-signing experiment remains an opt-in diagnostic; # its failed startup control is never counted as confinement. - node --experimental-strip-types scripts/probes/plugin-confinement/run.mts --runtime native --macos-signing-native --report "$RUNNER_TEMP/matrix.json" > "$RUNNER_TEMP/matrix.log" 2>&1 + node --experimental-strip-types scripts/probes/plugin-confinement/run.mts --runtime native --macos-signing-native --macos-private-unix --report "$RUNNER_TEMP/matrix.json" > "$RUNNER_TEMP/matrix.log" 2>&1 node --experimental-strip-types scripts/probes/plugin-confinement/macos_signing_exec.mts --report "$RUNNER_TEMP/exec.json" > "$RUNNER_TEMP/exec.log" 2>&1 + - name: Reject missing scratch UNIX policy + shell: bash + run: | + set -euo pipefail + control="$RUNNER_TEMP/macos-private-unix-missing-grant" + python3 - "$control" <<'PYCONTROL' + from pathlib import Path + import shutil, sys + target = Path(sys.argv[1]) + shutil.copytree('scripts/probes/plugin-confinement', target, ignore=shutil.ignore_patterns('evidence', '__pycache__')) + driver = target / 'run.mts' + text = driver.read_text() + before = ' if (privateUnix) {' + assert text.count(before) == 1 + driver.write_text(text.replace(before, ' if (false) { // Missing scratch UNIX grant control.')) + PYCONTROL + log="$RUNNER_TEMP/private-unix-missing-grant.log" + if node --experimental-strip-types "$control/run.mts" --runtime native --macos-signing-native --macos-private-unix --report "$control/result.json" > "$log" 2>&1; then + echo 'Missing private UNIX policy unexpectedly passed' >&2 + exit 1 + fi + python3 - "$log" <<'PYCONTROL' + from pathlib import Path + import sys + text = Path(sys.argv[1]).read_text() + assert 'no-capabilities: private UNIX runtime exchange failed: [false,false]' in text, text + PYCONTROL - name: Retain signing-identity candidate evidence if: always() uses: actions/upload-artifact@v4 @@ -156,6 +183,7 @@ jobs: path: | ${{ runner.temp }}/matrix.json ${{ runner.temp }}/matrix.log + ${{ runner.temp }}/private-unix-missing-grant.log ${{ runner.temp }}/exec.json ${{ runner.temp }}/exec.log if-no-files-found: error @@ -197,7 +225,7 @@ jobs: if [[ "$runtime" == python-system ]]; then runtime=python fi - args=(--runtime "$runtime" --macos-signing-runtime --report "$RUNNER_TEMP/proof.json") + args=(--runtime "$runtime" --macos-signing-runtime --macos-private-unix --report "$RUNNER_TEMP/proof.json") if [[ "$PROOF_RUNTIME" == python ]]; then args+=(--python "$(command -v python3)") elif [[ "$PROOF_RUNTIME" == python-system ]]; then diff --git a/.github/workflows/plugin-native-launcher.yml b/.github/workflows/plugin-native-launcher.yml index ee207230b..d63949132 100644 --- a/.github/workflows/plugin-native-launcher.yml +++ b/.github/workflows/plugin-native-launcher.yml @@ -209,7 +209,7 @@ jobs: if [[ "$RUNNER_OS" == Linux ]]; then args+=(--initial-exec --trace "$RUNNER_TEMP/packaged-runtime/trace-$runtime") else - args+=(--macos-signing-runtime) + args+=(--macos-signing-runtime --macos-private-unix) fi if ! node --experimental-strip-types scripts/probes/plugin-confinement/run.mts "${args[@]}" > "$RUNNER_TEMP/packaged-runtime/$runtime.log" 2>&1; then cat "$RUNNER_TEMP/packaged-runtime/$runtime.log" @@ -217,7 +217,7 @@ jobs: fi done if [[ "$RUNNER_OS" == macOS ]]; then - if ! node --experimental-strip-types scripts/probes/plugin-confinement/run.mts --runtime python --python /usr/bin/python3 --macos-signing-runtime --packaged-helper "$helper" --report "$RUNNER_TEMP/packaged-runtime/python-system.json" > "$RUNNER_TEMP/packaged-runtime/python-system.log" 2>&1; then + if ! node --experimental-strip-types scripts/probes/plugin-confinement/run.mts --runtime python --python /usr/bin/python3 --macos-signing-runtime --macos-private-unix --packaged-helper "$helper" --report "$RUNNER_TEMP/packaged-runtime/python-system.json" > "$RUNNER_TEMP/packaged-runtime/python-system.log" 2>&1; then cat "$RUNNER_TEMP/packaged-runtime/python-system.log" matrix_status=1 fi diff --git a/openspec/changes/complete-plugin-hook-runtime/macos-private-runtime-ipc.md b/openspec/changes/complete-plugin-hook-runtime/macos-private-runtime-ipc.md new file mode 100644 index 000000000..691e3c5ae --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/macos-private-runtime-ipc.md @@ -0,0 +1,57 @@ +# macOS private runtime UNIX exchanges + +This is independent progress within the approved native-proof scope. The +[Linux mediation revision](linux-kernel-unix-revision.md) remains unapproved; +this extension does not select that direction or activate production hosts. + +The existing pre-runtime macOS signing candidate checks capabilities without +exchanging data through runtime-owned UNIX pathname sockets. Its default-deny +network policy also blocks private scratch socket creation/communication. The +opt-in `--macos-private-unix` extension adds scratch-scoped network-inbound/local +and network-outbound/remote UNIX socket rules to the experimental Seatbelt +profile. It requires the pre-runtime signing candidate. Ordinary profiles and +production launch paths do not change. + +The same untrusted Node/Python/Bun/Deno/native fixtures used by the Linux stream +candidate now require real absolute and relative pathname token/ack exchanges on +macOS. Every capability combination and the unconfined control must report +`private_unix: [true, true]`. Original read/write/shell, pre-main, descriptor, +constructor and image-signature assertions remain. Reports identify the macOS +candidate separately from the Linux broker candidate. + +Darwin's bounded UNIX address cannot contain the per-user TMPDIR plus long case +names. For this opt-in experiment only, create the same private 0700 temporary +root beneath canonical `/tmp`. Keep the absolute socket exchange and its strict +expectation; do not replace it with a relative-only test or count an address-size +failure as policy enforcement. + +The native signing workflow on both macOS architectures also runs a copied +fixture driver with only the scratch UNIX grants omitted. The unconfined row +must pass, then the no-capabilities row must fail specifically at +`private UNIX runtime exchange failed: [false,false]`. Generic profile syntax or +startup failure cannot satisfy this control. The packaged-helper workflow adds +the positive exchanges to all five runtime families and system Python. + +## Local result + +On macOS arm64, Darwin 25.6.0, native C, Node 22.20.0 and system Python 3.9.6 each +pass all nine pre-runtime rows using both the fixture-built launcher and the +freshly built packaged helper: 54 cases total, with no unsupported rows. Both +private exchanges succeed in every row, and the missing-grant control fails its +exact named assertion after the unconfined control succeeds. The default native +signing matrix also passes its nine rows without the opt-in observation field. +Original reports and the control log are retained under +`scripts/probes/plugin-confinement/evidence/macos-private-unix-local`. +Their independently recomputed source manifest SHA-256 is +`819f7e4455d5d9c4803197328ff0bef845803515202711349897af9260789ff7`. +Packaged reports record input helper SHA-256 +`64ee74d21d1ddc470989450014f1e89fa33ab5aec230cd998890df3ec5717225`. +Each private launcher copy receives its fresh signing identifier, so its executed +digest is separately recorded rather than asserted equal to the input digest. + +Bun/Deno are unavailable locally. Hosted Intel/arm64 runtime matrices and the +complete packaged-helper matrix are configured but pending for this revision. These stream +exchanges are not full private IPC acceptance: owned-host/alias adversarial +coverage, datagram/seqpacket, ancillary credentials/FDs, proxy/network ceilings +and complete production admission/settlement remain required. Native support +and parent task checkboxes stay open. diff --git a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md index c00b16f07..59931c79e 100644 --- a/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md +++ b/openspec/changes/complete-plugin-hook-runtime/native-host-integration.md @@ -124,6 +124,8 @@ App's legacy launch path does not implement this sequence today. The [kernel peer identity diagnostic](linux-private-peer-identity.md) separately checks the listener's view of a broker-emulated caller; data exchange alone cannot establish that compatibility. + Independent [macOS private runtime exchanges](macos-private-runtime-ipc.md) + extend the pre-runtime signing candidate while the Linux revision awaits review. - [ ] N3 Implement registry-owned generation admission and immutable resource binding with actual production startup, revocation and quarantine tests. - [ ] N4 Integrate the native launch owner and independently intersect all diff --git a/scripts/probes/plugin-confinement/README.md b/scripts/probes/plugin-confinement/README.md index 3966afcef..63259704a 100644 --- a/scripts/probes/plugin-confinement/README.md +++ b/scripts/probes/plugin-confinement/README.md @@ -69,6 +69,23 @@ sources, and actual observations. A failure exits nonzero and does not produce a new success report. Use a fresh report destination or check its timestamp and digest before treating an existing report as evidence. +## macOS private UNIX stream candidate + +`--macos-private-unix` extends the pre-runtime signing candidate with scratch-only +UNIX inbound/outbound rules and real absolute/relative socket exchanges in every +capability row. For example: + +```sh +node --experimental-strip-types scripts/probes/plugin-confinement/run.mts --runtime native --macos-signing-native --macos-private-unix --report /tmp/native-private-unix.json +``` + +Use `--macos-signing-runtime` for Node/Python/Bun/Deno and supply the same explicit +runtime arguments as the existing pre-runtime matrix. This opt-in experiment +uses an owned short temporary root under canonical `/tmp` to retain a genuine +absolute-path exchange within Darwin's UNIX address bound. CI includes a precise +missing-grant control. See the [evidence and remaining acceptance](../../../openspec/changes/complete-plugin-hook-runtime/macos-private-runtime-ipc.md). +This is not production launch policy or complete private IPC/network acceptance. + ## Boundary and coverage `macos_python.c` embeds an isolated Python and preloads trusted standard-library diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/missing-grant.log b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/missing-grant.log new file mode 100644 index 000000000..d0a6b2c9f --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/missing-grant.log @@ -0,0 +1,31 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: no-capabilities: private UNIX runtime exchange failed: [false,false] ++ actual - expected + + [ ++ false, ++ false +- true, +- true + ] + + at check (file:///private/tmp/cyber-mac-unix-control-w87dehyc/source/run.mts:334:12) + at file:///private/tmp/cyber-mac-unix-control-w87dehyc/source/run.mts:438:31 + at Array.map () + at main (file:///private/tmp/cyber-mac-unix-control-w87dehyc/source/run.mts:438:8) + at file:///private/tmp/cyber-mac-unix-control-w87dehyc/source/run.mts:461:1 + at ModuleJob.run (node:internal/modules/esm/module_job:345:25) + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:665:26) + at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: [ false, false ], + expected: [ true, true ], + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/native.json b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/native.json new file mode 100644 index 000000000..645537a84 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/native.json @@ -0,0 +1,543 @@ +{ + "recorded_at": "2026-10-30T16:57:18.159Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "819f7e4455d5d9c4803197328ff0bef845803515202711349897af9260789ff7", + "platform": "darwin", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.814eb374-6050-4f1f-aa89-e6ae18d84ed7", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/node.json b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/node.json new file mode 100644 index 000000000..05d86323c --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/node.json @@ -0,0 +1,462 @@ +{ + "recorded_at": "2026-10-30T16:57:21.144Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "819f7e4455d5d9c4803197328ff0bef845803515202711349897af9260789ff7", + "platform": "darwin", + "architecture": "arm64", + "runtime": "node", + "version": "22.20.0", + "signing_identifier": "com.cyberdyne.probe.bootstrap.8f24c058-4365-45d8-9741-607e8c62d83e", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/packaged-native.json b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/packaged-native.json new file mode 100644 index 000000000..40bf2eca4 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/packaged-native.json @@ -0,0 +1,549 @@ +{ + "recorded_at": "2026-10-30T17:00:55.822Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "819f7e4455d5d9c4803197328ff0bef845803515202711349897af9260789ff7", + "platform": "darwin", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.0824ddae-e974-48fc-a63b-b119e046fac5", + "packaged_helper": { + "input_sha256": "64ee74d21d1ddc470989450014f1e89fa33ab5aec230cd998890df3ec5717225", + "executed_sha256": "7ffb48fee46462bb42fa36ff39f3bbbaf8ce23a0f52c69ecb8ff00a3cd6eee75", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": true, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/packaged-node.json b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/packaged-node.json new file mode 100644 index 000000000..ad33600bf --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/packaged-node.json @@ -0,0 +1,468 @@ +{ + "recorded_at": "2026-10-30T17:00:59.910Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "819f7e4455d5d9c4803197328ff0bef845803515202711349897af9260789ff7", + "platform": "darwin", + "architecture": "arm64", + "runtime": "node", + "version": "22.20.0", + "signing_identifier": "com.cyberdyne.probe.bootstrap.6569a7f8-9796-40ad-a92a-86e94531a32d", + "packaged_helper": { + "input_sha256": "64ee74d21d1ddc470989450014f1e89fa33ab5aec230cd998890df3ec5717225", + "executed_sha256": "d3ace785329bd0c7314d99fe70bfecb020d0b28f4e8860e167459644021e4c38", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/packaged-python.json b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/packaged-python.json new file mode 100644 index 000000000..39ba40e1d --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/packaged-python.json @@ -0,0 +1,459 @@ +{ + "recorded_at": "2026-10-30T17:00:57.931Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "819f7e4455d5d9c4803197328ff0bef845803515202711349897af9260789ff7", + "platform": "darwin", + "architecture": "arm64", + "runtime": "python", + "version": "3.9.6", + "signing_identifier": "com.cyberdyne.probe.bootstrap.7e64449d-6d6d-4696-b8b3-2f18744afed2", + "packaged_helper": { + "input_sha256": "64ee74d21d1ddc470989450014f1e89fa33ab5aec230cd998890df3ec5717225", + "executed_sha256": "3e02719f7605933cf82c3a991c3046b68594227f47197f430ed03c7292aba47c", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "cannot_relax": null, + "child_reads": [ + true, + true + ], + "hardlink_private": true, + "inherited_descriptor": true, + "native_child_reads": [ + true, + true + ], + "native_fork": true, + "package_read": true, + "private_list": true, + "private_read": true, + "private_unix": [ + true, + true + ], + "private_write": true, + "project_list": true, + "project_read": true, + "project_rename": true, + "project_write": true, + "protected_read": true, + "protected_write": true, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/python.json b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/python.json new file mode 100644 index 000000000..0cd368cf7 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-unix-local/python.json @@ -0,0 +1,453 @@ +{ + "recorded_at": "2026-10-30T16:57:19.624Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "819f7e4455d5d9c4803197328ff0bef845803515202711349897af9260789ff7", + "platform": "darwin", + "architecture": "arm64", + "runtime": "python", + "version": "3.9.6", + "signing_identifier": "com.cyberdyne.probe.bootstrap.e1fe66c4-e296-49db-a2d0-24bdbde8c929", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "cannot_relax": null, + "child_reads": [ + true, + true + ], + "hardlink_private": true, + "inherited_descriptor": false, + "native_child_reads": [ + true, + true + ], + "native_fork": true, + "package_read": true, + "private_list": true, + "private_read": true, + "private_unix": [ + true, + true + ], + "private_write": true, + "project_list": true, + "project_read": true, + "project_rename": true, + "project_write": true, + "protected_read": true, + "protected_write": true, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/run.mts b/scripts/probes/plugin-confinement/run.mts index 00ba80973..ffb418e22 100644 --- a/scripts/probes/plugin-confinement/run.mts +++ b/scripts/probes/plugin-confinement/run.mts @@ -12,7 +12,7 @@ import { fileURLToPath } from "node:url"; import { parseArgs } from "node:util"; type Runtime = { kind: "python" | "node" | "bun" | "deno" | "native"; executable: string; prefix: string; include: string; libdir: string; library?: string; version: string }; -type Artifacts = { executable: string; addon?: string; landlock?: string; initialExec: boolean; stagedPlatform?: boolean; signingIdentifier?: string; trace?: string; packaged?: boolean; unixScratch?: boolean; privateStream?: boolean }; +type Artifacts = { executable: string; addon?: string; landlock?: string; initialExec: boolean; stagedPlatform?: boolean; signingIdentifier?: string; trace?: string; packaged?: boolean; unixScratch?: boolean; privateUnix?: boolean }; type Flags = { read: boolean; write: boolean; shell: boolean; unrestricted?: boolean }; type Observation = Record; const source = dirname(fileURLToPath(import.meta.url)); @@ -125,7 +125,7 @@ function build(root: string, runtime: Runtime, initialExec: boolean, signingRunt return { executable, landlock, initialExec }; } -function policy(runtime: Runtime, paths: Record, flags: Flags, stagedPlatform = false, signingIdentifier?: string): string { +function policy(runtime: Runtime, paths: Record, flags: Flags, stagedPlatform = false, signingIdentifier?: string, privateUnix = false): string { const allow = (operation: string, path: string) => `(allow ${operation} (subpath ${JSON.stringify(path)}))`; // The child runtime requires directory-data access to the root object itself. // A literal root rule does not grant reads of descendant files/directories. @@ -146,6 +146,10 @@ function policy(runtime: Runtime, paths: Record, flags: Flags, s } if (runtime.kind === "native") lines.push(`(allow file-read* file-map-executable (literal ${JSON.stringify(runtime.executable)}))`); lines.push(allow("file-write*", paths.scratch)); + if (privateUnix) { + lines.push(`(allow network-inbound (local unix-socket (subpath ${JSON.stringify(paths.scratch)})))`); + lines.push(`(allow network-outbound (remote unix-socket (subpath ${JSON.stringify(paths.scratch)})))`); + } if (flags.read) lines.push(allow("file-read*", paths.project)); if (flags.write) lines.push(allow("file-write*", paths.project)); for (const path of [paths.private, paths.protected]) { @@ -229,7 +233,7 @@ function observe(artifacts: Artifacts, runtime: Runtime, paths: Record Date: Fri, 30 Oct 2026 13:26:56 -0400 Subject: [PATCH 14/21] test(plugins): verify macOS owned UNIX endpoint isolation --- .../workflows/plugin-confinement-proof.yml | 24 +- .../macos-owned-unix-boundary.md | 81 +++ .../macos-private-runtime-ipc.md | 5 + scripts/probes/plugin-confinement/README.md | 6 + .../macos-owned-unix-local/boundary.json | 379 ++++++++++++ .../macos-owned-unix-local/missing-grant.log | 31 + .../macos-owned-unix-local/missing-scope.log | 20 + .../packaged-native.json | 550 ++++++++++++++++++ .../macos-owned-unix-local/packaged-node.json | 469 +++++++++++++++ .../packaged-python.json | 460 +++++++++++++++ .../runtime-native.json | 544 +++++++++++++++++ .../macos-owned-unix-local/runtime-node.json | 463 +++++++++++++++ .../runtime-python.json | 454 +++++++++++++++ .../plugin-confinement/fixture_native.c | 90 ++- .../plugin-confinement/macos_policy.mts | 42 ++ .../plugin-confinement/macos_private_ipc.mts | 149 +++++ scripts/probes/plugin-confinement/run.mts | 40 +- 17 files changed, 3765 insertions(+), 42 deletions(-) create mode 100644 openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/boundary.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/missing-grant.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/missing-scope.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/packaged-native.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/packaged-node.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/packaged-python.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/runtime-native.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/runtime-node.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/runtime-python.json create mode 100644 scripts/probes/plugin-confinement/macos_policy.mts create mode 100644 scripts/probes/plugin-confinement/macos_private_ipc.mts diff --git a/.github/workflows/plugin-confinement-proof.yml b/.github/workflows/plugin-confinement-proof.yml index 70c671d8a..93261ac75 100644 --- a/.github/workflows/plugin-confinement-proof.yml +++ b/.github/workflows/plugin-confinement-proof.yml @@ -158,7 +158,7 @@ jobs: import shutil, sys target = Path(sys.argv[1]) shutil.copytree('scripts/probes/plugin-confinement', target, ignore=shutil.ignore_patterns('evidence', '__pycache__')) - driver = target / 'run.mts' + driver = target / 'macos_policy.mts' text = driver.read_text() before = ' if (privateUnix) {' assert text.count(before) == 1 @@ -175,6 +175,25 @@ jobs: text = Path(sys.argv[1]).read_text() assert 'no-capabilities: private UNIX runtime exchange failed: [false,false]' in text, text PYCONTROL + - name: Verify owned UNIX endpoints and native peer identity + shell: bash + run: | + set -euo pipefail + node --experimental-strip-types scripts/probes/plugin-confinement/macos_private_ipc.mts --report "$RUNNER_TEMP/unix-boundary.json" > "$RUNNER_TEMP/unix-boundary.log" 2>&1 + log="$RUNNER_TEMP/unix-missing-scope.log" + if node --experimental-strip-types scripts/probes/plugin-confinement/macos_private_ipc.mts --missing-scope > "$log" 2>&1; then + echo 'Missing UNIX outbound scope unexpectedly passed' >&2 + exit 1 + fi + python3 - "$log" <<'PYCONTROL' + from pathlib import Path + import sys + text = Path(sys.argv[1]).read_text() + assert 'macOS UNIX socket boundary escaped scratch:' in text, text + for token in ['"owner_received_fixture":true', '"acknowledged":true', + '"private_aliases":[true,true]', '"private_peer_matches":true']: + assert token in text, text + PYCONTROL - name: Retain signing-identity candidate evidence if: always() uses: actions/upload-artifact@v4 @@ -184,6 +203,9 @@ jobs: ${{ runner.temp }}/matrix.json ${{ runner.temp }}/matrix.log ${{ runner.temp }}/private-unix-missing-grant.log + ${{ runner.temp }}/unix-boundary.json + ${{ runner.temp }}/unix-boundary.log + ${{ runner.temp }}/unix-missing-scope.log ${{ runner.temp }}/exec.json ${{ runner.temp }}/exec.log if-no-files-found: error diff --git a/openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md b/openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md new file mode 100644 index 000000000..22d19e513 --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md @@ -0,0 +1,81 @@ +# macOS owned UNIX listener and peer identity controls + +This extends the approved native proof independently of the pending +[Linux revision](linux-kernel-unix-revision.md). It uses the same experimental +profile as the runtime matrix. It does not activate production hosts or close +full private IPC acceptance. + +`macos_policy.mts` contains the profile builder shared by `run.mts` and the new +`macos_private_ipc.mts` driver. Extraction preserves the preceding function body +apart from its export; that equality was checked against the preceding Git +source. The runtime source manifest now includes this module, and the +missing-grant control modifies its temporary copy instead of a duplicate policy. + +The driver owns a UNIX listener in a fixture Location. It starts the compiled native guest without changing its image/signature, +through the freshly signed pre-runtime launcher, with +descriptor sanitation and the existing exact-target execution rule. The native +guest has no policy installation step. Each of the eight read/write/shell +combinations runs separately after an unconfined positive control. + +The guest must exchange a token and acknowledgement through absolute and +relative scratch sockets and through hard-link and symlink aliases of its own +scratch socket. Both ends of all four exchanges call getpeereid and +LOCAL_PEERPID: eight identity checks must match the guest's PID, UID and GID. +This checks actual native caller identity, separately from byte exchange. + +The guest then tries the owned host listener directly and through scratch +hard-link/symlink routes. It reports connection, token-send and acknowledgement +results independently. The owner records the complete fixed token before +acknowledging; target-reported failure alone cannot prove isolation. The +unconfined control must create both aliases and deliver three acknowledged +tokens. Every confined case must report no host connection/send/ack and no +actual owner receipt. A refused foreign hard-link creation is recorded as such; +it is not mislabeled as a successful alias followed by denied connect. Positive +private aliases ensure this does not accept a blanket ban on socket aliases. + +The missing-scope control widens only the outbound UNIX path grant from scratch +to `/`. It must retain private exchanges/aliases and identity, actually receive +an acknowledgement from the owned host listener, and fail the named +`macOS UNIX socket boundary escaped scratch` assertion. Profile parse failure, +startup refusal or a broken private exchange cannot satisfy that control. + +The owner bounds connection count, token buffering, socket waits, subprocess +output and execution time. Each listener closes after the guest settles, all +accepted sockets are disposed, and the owned temporary root is removed. This +fixed-process diagnostic does not replace the production tree owner or prove +arbitrary escaped-descendant settlement. + +## Local result + +On macOS arm64, Darwin 25.6.0, all nine native listener cases pass. The control +receives three real host tokens; all eight confined cases receive none, retain +all four private exchanges and pass all eight identity checks. Scratch-created +hard links and symlinks work. Foreign hard-link creation is refused in the +confined cases, and created foreign symlinks cannot connect. The widened-scope +control actually reaches the owned listener and fails its exact assertion. + +Native C, Node and system Python also pass all 54 runtime cases through the +fixture-built and packaged launchers after the extraction. The shared-policy +missing-grant control passes its unconfined row and fails the exact +no-capabilities exchange assertion. + +Original reports and both logs are retained under +`scripts/probes/plugin-confinement/evidence/macos-owned-unix-local`. +The owned-listener source manifest SHA-256 is +`fbe318d5d33b107ef35c988168203d005b87a11c24805f412a27bb65c5511416`; +the runtime manifest SHA-256 is +`b8db40c4efa39e283514b64648916bfb3657e2233f9c7a3c7194be949fe620c1`. +Both were independently recomputed from the actual source inputs. + +The cognitive-complexity skill measured byte-identical `.ts` copies because its +walker omits `.mts`: the shared builder scores 13 and the largest emitted new +driver function scores 3, with no analyzer warnings. Native C and TypeScript +syntax checks pass. Hosted macOS Intel/arm64 execution remains pending for this +extension. The preceding [Intel Python job](https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41095335363/job/124199509520) passed its runtime assertions but its +artifact upload failed after five service timeouts; that missing report is not +counted as retained acceptance evidence. + +Still required: concurrent alias replacement, datagram/seqpacket, ancillary FD +and credential behavior, proxy/network intersections, immutable owner admission, +full resource settlement and actual App/server execution. Native and parent +task checkboxes remain open. diff --git a/openspec/changes/complete-plugin-hook-runtime/macos-private-runtime-ipc.md b/openspec/changes/complete-plugin-hook-runtime/macos-private-runtime-ipc.md index 691e3c5ae..60ba11d02 100644 --- a/openspec/changes/complete-plugin-hook-runtime/macos-private-runtime-ipc.md +++ b/openspec/changes/complete-plugin-hook-runtime/macos-private-runtime-ipc.md @@ -55,3 +55,8 @@ exchanges are not full private IPC acceptance: owned-host/alias adversarial coverage, datagram/seqpacket, ancillary credentials/FDs, proxy/network ceilings and complete production admission/settlement remain required. Native support and parent task checkboxes stay open. + +The [owned-listener and peer-identity extension](macos-owned-unix-boundary.md) +adds actual host receipts, positive private aliases, native credential checks +and a precise widened-scope counterexample. It shares the profile builder with +this runtime matrix; its source-bound results remain separate from those above. diff --git a/scripts/probes/plugin-confinement/README.md b/scripts/probes/plugin-confinement/README.md index 63259704a..b000dc018 100644 --- a/scripts/probes/plugin-confinement/README.md +++ b/scripts/probes/plugin-confinement/README.md @@ -86,6 +86,12 @@ absolute-path exchange within Darwin's UNIX address bound. CI includes a precise missing-grant control. See the [evidence and remaining acceptance](../../../openspec/changes/complete-plugin-hook-runtime/macos-private-runtime-ipc.md). This is not production launch policy or complete private IPC/network acceptance. +`macos_private_ipc.mts` also runs the shared profile against a fixture-owned host +listener. Its nine native cases require private socket aliases and correct peer +PID/UID/GID while denying actual host delivery. `--missing-scope` must expose the +owned host endpoint and fail the named isolation assertion. See the +[owned-listener evidence and limits](../../../openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md). + ## Boundary and coverage `macos_python.c` embeds an isolated Python and preloads trusted standard-library diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/boundary.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/boundary.json new file mode 100644 index 000000000..e17a676cc --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/boundary.json @@ -0,0 +1,379 @@ +{ + "recorded_at": "2026-10-30T17:26:22.177Z", + "platform": "darwin", + "architecture": "arm64", + "kernel_release": "25.6.0", + "sources": [ + "macos_private_ipc.mts", + "macos_policy.mts", + "fixture_native.c", + "process_policy.h", + "macos_exec.c" + ], + "source_sha256": "fbe318d5d33b107ef35c988168203d005b87a11c24805f412a27bb65c5511416", + "target_sha256": "257daefa9483bf6d441fa754f06daee7e559515718c69359faf007203e0d9772", + "rows": [ + { + "name": "unconfined", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": true, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "hardlink": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "symlink": { + "connected": true, + "sent": true, + "acknowledged": true + } + }, + "owner_receipts": 3, + "owner_received_fixture": true + }, + { + "name": "r0w0s0", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w0s1", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w1s0", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w1s1", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w0s0", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w0s1", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w1s0", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w1s1", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + } + ], + "scope": "Experimental pre-runtime native UNIX stream controls only; complete IPC/proxy/ownership and App acceptance remain required." +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/missing-grant.log b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/missing-grant.log new file mode 100644 index 000000000..dd2253970 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/missing-grant.log @@ -0,0 +1,31 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: no-capabilities: private UNIX runtime exchange failed: [false,false] ++ actual - expected + + [ ++ false, ++ false +- true, +- true + ] + + at check (file:///private/tmp/cyber-mac-grant-ry8_9lcl/source/run.mts:298:12) + at file:///private/tmp/cyber-mac-grant-ry8_9lcl/source/run.mts:402:31 + at Array.map () + at main (file:///private/tmp/cyber-mac-grant-ry8_9lcl/source/run.mts:402:8) + at file:///private/tmp/cyber-mac-grant-ry8_9lcl/source/run.mts:425:1 + at ModuleJob.run (node:internal/modules/esm/module_job:345:25) + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:665:26) + at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: [ false, false ], + expected: [ true, true ], + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/missing-scope.log b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/missing-scope.log new file mode 100644 index 000000000..656502acd --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/missing-scope.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: macOS UNIX socket boundary escaped scratch: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"owner_receipts":2,"owner_received_fixture":true} + +true !== false + + at check (file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:113:12) + at file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:135:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/packaged-native.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/packaged-native.json new file mode 100644 index 000000000..0320df511 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/packaged-native.json @@ -0,0 +1,550 @@ +{ + "recorded_at": "2026-10-30T17:26:20.716Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "b8db40c4efa39e283514b64648916bfb3657e2233f9c7a3c7194be949fe620c1", + "platform": "darwin", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.6487c2e0-341c-4550-8799-cf8b52789b06", + "packaged_helper": { + "input_sha256": "64ee74d21d1ddc470989450014f1e89fa33ab5aec230cd998890df3ec5717225", + "executed_sha256": "079b42662e5f439dd4cb46e670f6f139dc66a808f7094875c428620a658d12a5", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": true, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/packaged-node.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/packaged-node.json new file mode 100644 index 000000000..ee02c6680 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/packaged-node.json @@ -0,0 +1,469 @@ +{ + "recorded_at": "2026-10-30T17:26:26.798Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "b8db40c4efa39e283514b64648916bfb3657e2233f9c7a3c7194be949fe620c1", + "platform": "darwin", + "architecture": "arm64", + "runtime": "node", + "version": "22.20.0", + "signing_identifier": "com.cyberdyne.probe.bootstrap.08c7f32c-a858-4721-bde6-dab517030ce3", + "packaged_helper": { + "input_sha256": "64ee74d21d1ddc470989450014f1e89fa33ab5aec230cd998890df3ec5717225", + "executed_sha256": "584dec31f1cfc22fcca8437a758870607ebd3ed42a786d6519400490f8426244", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/packaged-python.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/packaged-python.json new file mode 100644 index 000000000..eaf1f53cc --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/packaged-python.json @@ -0,0 +1,460 @@ +{ + "recorded_at": "2026-10-30T17:26:22.866Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "b8db40c4efa39e283514b64648916bfb3657e2233f9c7a3c7194be949fe620c1", + "platform": "darwin", + "architecture": "arm64", + "runtime": "python", + "version": "3.9.6", + "signing_identifier": "com.cyberdyne.probe.bootstrap.db7e942e-c23f-4269-afbd-50b4932f03c7", + "packaged_helper": { + "input_sha256": "64ee74d21d1ddc470989450014f1e89fa33ab5aec230cd998890df3ec5717225", + "executed_sha256": "a33d3794098db4a24cd47ae86889ed1700560eeba19bdf0aa0c138e7b218982d", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "cannot_relax": null, + "child_reads": [ + true, + true + ], + "hardlink_private": true, + "inherited_descriptor": true, + "native_child_reads": [ + true, + true + ], + "native_fork": true, + "package_read": true, + "private_list": true, + "private_read": true, + "private_unix": [ + true, + true + ], + "private_write": true, + "project_list": true, + "project_read": true, + "project_rename": true, + "project_write": true, + "protected_read": true, + "protected_write": true, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/runtime-native.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/runtime-native.json new file mode 100644 index 000000000..dc870fb79 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/runtime-native.json @@ -0,0 +1,544 @@ +{ + "recorded_at": "2026-10-30T17:26:22.124Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "b8db40c4efa39e283514b64648916bfb3657e2233f9c7a3c7194be949fe620c1", + "platform": "darwin", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.0628ea28-d24b-44b3-8ced-ec7751e4eb5c", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/runtime-node.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/runtime-node.json new file mode 100644 index 000000000..bc22bf90e --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/runtime-node.json @@ -0,0 +1,463 @@ +{ + "recorded_at": "2026-10-30T17:26:27.102Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "b8db40c4efa39e283514b64648916bfb3657e2233f9c7a3c7194be949fe620c1", + "platform": "darwin", + "architecture": "arm64", + "runtime": "node", + "version": "22.20.0", + "signing_identifier": "com.cyberdyne.probe.bootstrap.fea03cde-2f8d-4f86-b52a-5de6aaaca796", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/runtime-python.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/runtime-python.json new file mode 100644 index 000000000..4f13b24f7 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-local/runtime-python.json @@ -0,0 +1,454 @@ +{ + "recorded_at": "2026-10-30T17:26:21.766Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "b8db40c4efa39e283514b64648916bfb3657e2233f9c7a3c7194be949fe620c1", + "platform": "darwin", + "architecture": "arm64", + "runtime": "python", + "version": "3.9.6", + "signing_identifier": "com.cyberdyne.probe.bootstrap.be002e65-85dc-4a6e-a43d-1d5fb5a68b9c", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "cannot_relax": null, + "child_reads": [ + true, + true + ], + "hardlink_private": true, + "inherited_descriptor": false, + "native_child_reads": [ + true, + true + ], + "native_fork": true, + "package_read": true, + "private_list": true, + "private_read": true, + "private_unix": [ + true, + true + ], + "private_write": true, + "project_list": true, + "project_read": true, + "project_rename": true, + "project_write": true, + "protected_read": true, + "protected_write": true, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": true, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "written_project_read": false + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "cannot_relax": true, + "child_reads": null, + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": null, + "native_fork": false, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": false, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "written_project_read": true + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": false, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + false, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + false, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": false, + "project_read": false, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "written_project_read": false + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "cannot_relax": true, + "child_reads": [ + true, + false + ], + "hardlink_private": false, + "inherited_descriptor": false, + "native_child_reads": [ + true, + false + ], + "native_fork": true, + "package_read": true, + "private_list": false, + "private_read": false, + "private_unix": [ + true, + true + ], + "private_write": false, + "project_list": true, + "project_read": true, + "project_rename": false, + "project_write": true, + "protected_read": false, + "protected_write": false, + "scratch_read": true, + "scratch_write": true, + "shell": true, + "stdio_tool": true, + "symlink_private_read": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "written_project_read": true + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/fixture_native.c b/scripts/probes/plugin-confinement/fixture_native.c index 9c4e5e432..3fc3fff8e 100644 --- a/scripts/probes/plugin-confinement/fixture_native.c +++ b/scripts/probes/plugin-confinement/fixture_native.c @@ -81,17 +81,37 @@ static int joined(char *out, const char *directory, const char *name) { return size > 0 && size < PATH_MAX; } -static int private_stream_exchange(const char *path) { +#ifdef __APPLE__ +static int private_peer_checks, private_peer_matches = 1; +static void private_peer_identity(int fd) { + uid_t uid = 0; gid_t gid = 0; pid_t pid = 0; + socklen_t size = sizeof(pid); + int match = getpeereid(fd, &uid, &gid) == 0 && uid == getuid() && gid == getgid() && + getsockopt(fd, SOL_LOCAL, LOCAL_PEERPID, &pid, &size) == 0 && + size == sizeof(pid) && pid == getpid(); + private_peer_checks++; + private_peer_matches = private_peer_matches && match; +} +#endif + +static int private_stream_exchange_to(const char *path, const char *destination, int alias_type) { struct sockaddr_un address = { .sun_family = AF_UNIX }; - if (strlen(path) >= sizeof(address.sun_path)) return 0; + if (strlen(path) >= sizeof(address.sun_path) || + (destination != NULL && strlen(destination) >= sizeof(address.sun_path))) return 0; strcpy(address.sun_path, path); int server = socket(AF_UNIX, SOCK_STREAM, 0), client = -1, peer = -1; - int bound = 0, result = 0; + int bound = 0, aliased = 0, result = 0; struct timeval timeout = { .tv_sec = 2 }; if (server < 0 || setsockopt(server, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) != 0 || bind(server, (struct sockaddr *)&address, sizeof(address)) != 0) goto done; bound = 1; if (listen(server, 1) != 0) goto done; + if (destination != NULL) { + int result = alias_type == 1 ? link(path, destination) : symlink(path, destination); + if (result != 0) goto done; + aliased = 1; + strcpy(address.sun_path, destination); + } client = socket(AF_UNIX, SOCK_STREAM, 0); if (client < 0 || setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) != 0 || setsockopt(client, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) != 0 || @@ -101,14 +121,22 @@ static int private_stream_exchange(const char *path) { char token = 0, ack = 0; result = send(client, "T", 1, 0) == 1 && recv(peer, &token, 1, 0) == 1 && token == 'T' && send(peer, "A", 1, 0) == 1 && recv(client, &ack, 1, 0) == 1 && ack == 'A'; +#ifdef __APPLE__ + if (result) { private_peer_identity(client); private_peer_identity(peer); } +#endif done: if (peer >= 0) close(peer); if (client >= 0) close(client); if (server >= 0) close(server); + if (aliased) unlink(destination); if (bound) unlink(path); return result; } +static int private_stream_exchange(const char *path) { + return private_stream_exchange_to(path, NULL, 0); +} + static int private_stream_probe(const char *scratch, int result[2]) { char absolute[PATH_MAX]; if (!joined(absolute, scratch, "a.sock")) return 0; @@ -124,6 +152,59 @@ static int private_stream_probe(const char *scratch, int result[2]) { return restored; } +#ifdef __APPLE__ +struct unix_attempt { int connected, sent, acknowledged; }; +static struct unix_attempt host_unix_attempt(const char *path) { + struct unix_attempt result = {0}; + struct sockaddr_un address = { .sun_family = AF_UNIX }; + if (strlen(path) >= sizeof(address.sun_path)) return result; + strcpy(address.sun_path, path); + int fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) return result; + struct timeval timeout = { .tv_sec = 2 }; + if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) != 0 || + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) != 0) goto done; + result.connected = connect(fd, (struct sockaddr *)&address, sizeof(address)) == 0; + result.sent = result.connected && send(fd, "fixture-only", 12, 0) == 12; + char ack = 0; + result.acknowledged = result.sent && recv(fd, &ack, 1, 0) == 1 && ack == 'A'; +done: + close(fd); + return result; +} + +static void print_unix_attempt(const char *name, struct unix_attempt result) { + printf(",\"%s\":{\"connected\":%s,\"sent\":%s,\"acknowledged\":%s}", name, + truth(result.connected), truth(result.sent), truth(result.acknowledged)); +} + +static int unix_boundary(const char *scratch, const char *host) { + if (strlen(scratch) >= PATH_MAX || strlen(host) >= PATH_MAX) return 2; + int ipc[2] = {0}; + if (!private_stream_probe(scratch, ipc)) return 2; + char owned[PATH_MAX], owned_alias[PATH_MAX]; + if (!joined(owned, scratch, "owned.sock") || !joined(owned_alias, scratch, "owned-alias.sock")) return 2; + int own_hardlink = private_stream_exchange_to(owned, owned_alias, 1); + int own_symlink = private_stream_exchange_to(owned, owned_alias, 2); + struct unix_attempt direct = host_unix_attempt(host); + char alias[PATH_MAX], symbolic[PATH_MAX]; + if (!joined(alias, scratch, "host-alias.sock") || !joined(symbolic, scratch, "host-symlink.sock")) return 2; + int linked = link(host, alias) == 0; + struct unix_attempt hardlink = linked ? host_unix_attempt(alias) : (struct unix_attempt){0}; + int symlinked = symlink(host, symbolic) == 0; + struct unix_attempt symlink_result = symlinked ? host_unix_attempt(symbolic) : (struct unix_attempt){0}; + printf("{\"started\":true,\"private_unix\":[%s,%s],\"private_peer_checks\":%d," + "\"private_peer_matches\":%s,\"hardlink_created\":%s,\"symlink_created\":%s", + truth(ipc[0]), truth(ipc[1]), private_peer_checks, truth(private_peer_matches), truth(linked), truth(symlinked)); + printf(",\"private_aliases\":[%s,%s]", truth(own_hardlink), truth(own_symlink)); + print_unix_attempt("direct", direct); + print_unix_attempt("hardlink", hardlink); + print_unix_attempt("symlink", symlink_result); + puts("}"); + return 0; +} +#endif + /* No untrusted shell strings: only fixed commands and separate fixture paths. */ static int child(char *const args[], char *output, size_t size) { int channel[2]; @@ -211,6 +292,9 @@ static int parent_directory(const char *path, char *out) { } int main(int argc, char **argv) { +#ifdef __APPLE__ + if (argc == 4 && strcmp(argv[1], "unix-boundary") == 0) return unix_boundary(argv[2], argv[3]); +#endif if (argc == 2 && strcmp(argv[1], "receipt") == 0) { puts("{\"self_exec\":true}"); return 0; diff --git a/scripts/probes/plugin-confinement/macos_policy.mts b/scripts/probes/plugin-confinement/macos_policy.mts new file mode 100644 index 000000000..4600f23db --- /dev/null +++ b/scripts/probes/plugin-confinement/macos_policy.mts @@ -0,0 +1,42 @@ +/** Shared experimental macOS profile; not production host admission. */ +import { dirname } from "node:path"; + +type Runtime = { kind: string; executable: string; libdir: string; library?: string }; +type Flags = { read: boolean; write: boolean; shell: boolean }; + +export function policy(runtime: Runtime, paths: Record, flags: Flags, stagedPlatform = false, signingIdentifier?: string, privateUnix = false): string { + const allow = (operation: string, path: string) => `(allow ${operation} (subpath ${JSON.stringify(path)}))`; + // The child runtime requires directory-data access to the root object itself. + // A literal root rule does not grant reads of descendant files/directories. + const lines = ["(version 1)", "(deny default)", "(allow file-read-metadata)", "(allow sysctl-read)", + "(allow signal (target same-sandbox))", "(allow process-info* (target same-sandbox))", + '(allow file-read* file-write* (literal "/dev/null"))', + '(allow file-read-data (literal "/"))']; + for (const path of ["/System", "/usr/lib", "/bin", "/usr/bin", runtime.libdir, ...runtime.kind === "native" ? [] : [dirname(runtime.executable)], paths.package, paths.scratch]) { + lines.push(allow("file-read* file-map-executable", path)); + } + // Framework Python's libpython symlink points outside LIBDIR to the + // framework binary. Admit that exact trusted file for descendant startup. + if (runtime.library) lines.push(`(allow file-read* file-map-executable (literal ${JSON.stringify(runtime.library)}))`); + if (runtime.kind === "python" && signingIdentifier) { + // Older framework Python initializes its hash seed from this public device. + // Do not admit /dev generally or substitute a predictable random seed. + lines.push('(allow file-read-data (literal "/dev/urandom"))'); + } + if (runtime.kind === "native") lines.push(`(allow file-read* file-map-executable (literal ${JSON.stringify(runtime.executable)}))`); + lines.push(allow("file-write*", paths.scratch)); + if (privateUnix) { + lines.push(`(allow network-inbound (local unix-socket (subpath ${JSON.stringify(paths.scratch)})))`); + lines.push(`(allow network-outbound (remote unix-socket (subpath ${JSON.stringify(paths.scratch)})))`); + } + if (flags.read) lines.push(allow("file-read*", paths.project)); + if (flags.write) lines.push(allow("file-write*", paths.project)); + for (const path of [paths.private, paths.protected]) { + lines.push(`(deny file-read* file-write* (subpath ${JSON.stringify(path)}))`); + } + lines.push(`(deny file-write-unlink (literal ${JSON.stringify(paths.project)}))`); + if (flags.shell) lines.push("(allow process-fork)", "(allow process-exec)"); + else if (signingIdentifier) lines.push(`(allow process-exec (require-all (signing-identifier ${JSON.stringify(signingIdentifier)}) (literal ${JSON.stringify(runtime.executable)})))`); + else if (stagedPlatform) lines.push(`(allow process-exec (require-all (process-attribute is-platform-binary) (literal ${JSON.stringify(runtime.executable)})))`); + return lines.join("\n"); +} diff --git a/scripts/probes/plugin-confinement/macos_private_ipc.mts b/scripts/probes/plugin-confinement/macos_private_ipc.mts new file mode 100644 index 000000000..f06a33993 --- /dev/null +++ b/scripts/probes/plugin-confinement/macos_private_ipc.mts @@ -0,0 +1,149 @@ +/** Actual owned-listener observations for the experimental macOS profile. */ +import assert from "node:assert/strict"; +import { execFile, spawnSync } from "node:child_process"; +import { createHash, randomUUID } from "node:crypto"; +import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs"; +import { createServer } from "node:net"; +import { release } from "node:os"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; +import { parseArgs, promisify } from "node:util"; +import { policy } from "./macos_policy.mts"; + +const source = dirname(fileURLToPath(import.meta.url)); +const environment = { PATH: "/usr/bin:/bin:/usr/sbin:/sbin" }; +const execute = promisify(execFile); +type Flags = { read: boolean; write: boolean; shell: boolean; unrestricted?: boolean }; + +function success(program: string, args: string[]) { + const result = spawnSync(program, args, { env: environment, encoding: "utf8", timeout: 30_000, maxBuffer: 65536 }); + if (result.error) throw result.error; + assert.equal(result.status, 0, JSON.stringify({ program, ...result })); +} + +function prepare(root: string) { + const packagePath = join(root, "package"); + mkdirSync(packagePath, { mode: 0o700 }); + const target = join(packagePath, "guest"), helper = join(root, "helper"); + for (const [file, output] of [["fixture_native.c", target], ["macos_exec.c", helper]]) { + success("/usr/bin/xcrun", ["clang", "-Wall", "-Wextra", "-Werror", "-Wno-error=deprecated-declarations", "-pthread", join(source, file), "-o", output]); + } + const identifier = `com.cyberdyne.probe.unix.helper.${randomUUID()}`; + success("/usr/bin/codesign", ["--force", "--sign", "-", "--identifier", identifier, "--timestamp=none", helper]); + success("/usr/bin/codesign", ["--verify", "--strict", "--all-architectures", helper]); + return { target, helper, identifier, packagePath }; +} + +async function owner(path: string) { + const peers = new Set(); + let receipts = 0, invalid = false; + const server = createServer(peer => { + peers.add(peer); + peer.setTimeout(2000, () => peer.destroy()); + peer.on("close", () => peers.delete(peer)); + peer.on("error", () => {}); + let bytes = Buffer.alloc(0), complete = false; + peer.on("data", data => { + if (complete || bytes.length + data.length > 12) { invalid = true; peer.destroy(); return; } + bytes = Buffer.concat([bytes, data]); + if (bytes.length !== 12) return; + complete = true; + if (bytes.toString() !== "fixture-only") { invalid = true; peer.destroy(); return; } + receipts++; + peer.end("A"); + }); + }); + server.maxConnections = 8; + server.on("error", () => { invalid = true; }); + await new Promise((resolve, reject) => { + server.once("error", reject); + server.listen(path, resolve); + }); + return { + receipt: () => ({ count: receipts, invalid }), + close: async () => { + for (const peer of peers) peer.destroy(); + await new Promise(resolve => server.close(() => resolve())); + }, + }; +} + +async function row(root: string, prepared: ReturnType, name: string, flags: Flags, missingScope: boolean) { + const base = join(root, name); + mkdirSync(base, { mode: 0o700 }); + const paths: Record = { package: prepared.packagePath }; + for (const key of ["project", "private", "protected", "scratch"]) { + paths[key] = join(base, key); + mkdirSync(paths[key], { mode: 0o700 }); + } + const host = join(paths.project, "host.sock"); + const listener = await owner(host); + try { + let profile = policy({ kind: "native", executable: prepared.target, libdir: "/usr/lib" }, paths, flags, false, prepared.identifier, true); + if (missingScope) { + const before = `(remote unix-socket (subpath ${JSON.stringify(paths.scratch)}))`; + assert.equal(profile.split(before).length, 2); + profile = profile.replace(before, '(remote unix-socket (subpath "/"))'); + } + const file = join(root, `policy-${name}.sb`); + writeFileSync(file, profile, { mode: 0o600 }); + const result = await execute(prepared.helper, [flags.unrestricted ? "-" : file, prepared.target, "unix-boundary", paths.scratch, host], { + cwd: paths.scratch, env: environment, encoding: "utf8", timeout: 15_000, maxBuffer: 65536, + }); + const observed = JSON.parse(result.stdout); + const receipt = listener.receipt(); + assert(!receipt.invalid, "invalid owned-listener protocol"); + return { name, flags, observed, owner_receipts: receipt.count, owner_received_fixture: receipt.count > 0 }; + } finally { + await listener.close(); + } +} + +function check(entry: Awaited>) { + assert.equal(entry.observed.started, true); + assert.deepEqual(entry.observed.private_unix, [true, true], `private exchange: ${JSON.stringify(entry)}`); + assert.deepEqual(entry.observed.private_aliases, [true, true], `private aliases: ${JSON.stringify(entry)}`); + assert.equal(entry.observed.private_peer_checks, 8); + assert.equal(entry.observed.private_peer_matches, true, `private peer identity: ${JSON.stringify(entry)}`); + if (entry.flags.unrestricted) { + assert.equal(entry.observed.hardlink_created, true); + assert.equal(entry.observed.symlink_created, true); + assert.equal(entry.owner_receipts, 3, `owned-listener control: ${JSON.stringify(entry)}`); + } else { + assert.equal(entry.owner_received_fixture, false, `macOS UNIX socket boundary escaped scratch: ${JSON.stringify(entry)}`); + } + for (const route of ["direct", "hardlink", "symlink"]) { + assert.deepEqual(entry.observed[route], { + connected: !!entry.flags.unrestricted, sent: !!entry.flags.unrestricted, acknowledged: !!entry.flags.unrestricted, + }, `host UNIX route: ${route}: ${JSON.stringify(entry)}`); + } +} + +assert.equal(process.platform, "darwin", "macOS native UNIX boundary proof requires Darwin"); +const { values } = parseArgs({ options: { report: { type: "string" }, "missing-scope": { type: "boolean", default: false } } }); +const root = realpathSync(mkdtempSync("/tmp/cyber-unix-")); +try { + const prepared = prepare(root); + const targetHash = createHash("sha256").update(readFileSync(prepared.target)).digest("hex"); + const rows = []; + const cases: Array<[string, Flags]> = [["unconfined", { read: true, write: true, shell: true, unrestricted: true }]]; + for (const read of [false, true]) for (const write of [false, true]) for (const shell of [false, true]) { + cases.push([`r${+read}w${+write}s${+shell}`, { read, write, shell }]); + } + for (const [name, flags] of cases) { + const observed = await row(root, prepared, name, flags, values["missing-scope"]); + check(observed); + rows.push(observed); + } + assert.equal(createHash("sha256").update(readFileSync(prepared.target)).digest("hex"), targetHash); + const sources = ["macos_private_ipc.mts", "macos_policy.mts", "fixture_native.c", "process_policy.h", "macos_exec.c"]; + const hash = createHash("sha256"); + for (const file of sources) hash.update(file + "\0").update(readFileSync(join(source, file))); + const report = { recorded_at: new Date().toISOString(), platform: process.platform, architecture: process.arch, + kernel_release: release(), sources, source_sha256: hash.digest("hex"), target_sha256: targetHash, rows, + scope: "Experimental pre-runtime native UNIX stream controls only; complete IPC/proxy/ownership and App acceptance remain required." }; + if (values.report) writeFileSync(values.report, JSON.stringify(report, null, 2) + "\n", { mode: 0o600 }); + console.log(JSON.stringify(report, null, 2)); +} finally { + rmSync(root, { recursive: true, force: true }); +} diff --git a/scripts/probes/plugin-confinement/run.mts b/scripts/probes/plugin-confinement/run.mts index ffb418e22..5958f603f 100644 --- a/scripts/probes/plugin-confinement/run.mts +++ b/scripts/probes/plugin-confinement/run.mts @@ -3,6 +3,7 @@ */ import assert from "node:assert/strict"; import { stageNative } from "./macos_stage.mts"; +import { policy } from "./macos_policy.mts"; import { spawnSync } from "node:child_process"; import { closeSync, copyFileSync, existsSync, mkdirSync, mkdtempSync, openSync, readFileSync, realpathSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs"; import { release, tmpdir } from "node:os"; @@ -125,43 +126,6 @@ function build(root: string, runtime: Runtime, initialExec: boolean, signingRunt return { executable, landlock, initialExec }; } -function policy(runtime: Runtime, paths: Record, flags: Flags, stagedPlatform = false, signingIdentifier?: string, privateUnix = false): string { - const allow = (operation: string, path: string) => `(allow ${operation} (subpath ${JSON.stringify(path)}))`; - // The child runtime requires directory-data access to the root object itself. - // A literal root rule does not grant reads of descendant files/directories. - const lines = ["(version 1)", "(deny default)", "(allow file-read-metadata)", "(allow sysctl-read)", - "(allow signal (target same-sandbox))", "(allow process-info* (target same-sandbox))", - '(allow file-read* file-write* (literal "/dev/null"))', - '(allow file-read-data (literal "/"))']; - for (const path of ["/System", "/usr/lib", "/bin", "/usr/bin", runtime.libdir, ...runtime.kind === "native" ? [] : [dirname(runtime.executable)], paths.package, paths.scratch]) { - lines.push(allow("file-read* file-map-executable", path)); - } - // Framework Python's libpython symlink points outside LIBDIR to the - // framework binary. Admit that exact trusted file for descendant startup. - if (runtime.library) lines.push(`(allow file-read* file-map-executable (literal ${JSON.stringify(runtime.library)}))`); - if (runtime.kind === "python" && signingIdentifier) { - // Older framework Python initializes its hash seed from this public device. - // Do not admit /dev generally or substitute a predictable random seed. - lines.push('(allow file-read-data (literal "/dev/urandom"))'); - } - if (runtime.kind === "native") lines.push(`(allow file-read* file-map-executable (literal ${JSON.stringify(runtime.executable)}))`); - lines.push(allow("file-write*", paths.scratch)); - if (privateUnix) { - lines.push(`(allow network-inbound (local unix-socket (subpath ${JSON.stringify(paths.scratch)})))`); - lines.push(`(allow network-outbound (remote unix-socket (subpath ${JSON.stringify(paths.scratch)})))`); - } - if (flags.read) lines.push(allow("file-read*", paths.project)); - if (flags.write) lines.push(allow("file-write*", paths.project)); - for (const path of [paths.private, paths.protected]) { - lines.push(`(deny file-read* file-write* (subpath ${JSON.stringify(path)}))`); - } - lines.push(`(deny file-write-unlink (literal ${JSON.stringify(paths.project)}))`); - if (flags.shell) lines.push("(allow process-fork)", "(allow process-exec)"); - else if (signingIdentifier) lines.push(`(allow process-exec (require-all (signing-identifier ${JSON.stringify(signingIdentifier)}) (literal ${JSON.stringify(runtime.executable)})))`); - else if (stagedPlatform) lines.push(`(allow process-exec (require-all (process-attribute is-platform-binary) (literal ${JSON.stringify(runtime.executable)})))`); - return lines.join("\n"); -} - function fixture(root: string): Record { const paths = Object.fromEntries(["package", "project", "private", "scratch"].map(name => [name, join(root, name)])); for (const path of Object.values(paths)) mkdirSync(path, { mode: 0o700 }); @@ -437,7 +401,7 @@ function main() { const rows = cases.filter(([name]) => !unsupported_cases.some(item => item.name === name)) .map(([name, flags]) => check(root, artifacts, runtime, name, flags)); const digest = createHash("sha256"); - const sources = ["run.mts", "macos_python.c", "macos_node.c", "native_exec.c", "node_bootstrap.cjs", "fixture.py", "fixture.cjs", "private_unix.cjs", "process_policy.h", "linux_filter.h", "linux_exec.c", "linux_initial_exec.h", "fixture_native.c", "macos_exec.c", "macos_stage.mts"]; + const sources = ["run.mts", "macos_policy.mts", "macos_python.c", "macos_node.c", "native_exec.c", "node_bootstrap.cjs", "fixture.py", "fixture.cjs", "private_unix.cjs", "process_policy.h", "linux_filter.h", "linux_exec.c", "linux_initial_exec.h", "fixture_native.c", "macos_exec.c", "macos_stage.mts"]; for (const file of sources) { digest.update(file + "\0").update(readFileSync(join(source, file))); } From 48a5481c531fcf64db38b62a73c7fb79f290b642 Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 14:00:27 -0400 Subject: [PATCH 15/21] test(plugins): verify private descriptor transfer and pinned effects --- .../workflows/plugin-confinement-proof.yml | 50 ++ .../macos-owned-unix-boundary.md | 22 + .../macos-private-descriptor-passing.md | 64 ++ scripts/probes/plugin-confinement/README.md | 5 + .../arm64/matrix.json | 544 +++++++++++++++++ .../arm64/private-unix-missing-grant.log | 31 + .../arm64/source-binding.json | 10 + .../arm64/unix-boundary.json | 379 ++++++++++++ .../arm64/unix-missing-scope.log | 20 + .../macos-owned-unix-bf87b7b9/x64/matrix.json | 544 +++++++++++++++++ .../x64/private-unix-missing-grant.log | 31 + .../x64/source-binding.json | 10 + .../x64/unix-boundary.json | 379 ++++++++++++ .../x64/unix-missing-scope.log | 20 + .../macos-private-rights-local/boundary.json | 506 ++++++++++++++++ .../drop-rights.log | 56 ++ .../missing-scope.log | 20 + .../packaged-native.json | 551 ++++++++++++++++++ .../path-reader.log | 20 + .../runtime-native.json | 545 +++++++++++++++++ .../runtime-node.json | 464 +++++++++++++++ .../plugin-confinement/fixture_native.c | 6 + .../plugin-confinement/macos_private_ipc.mts | 35 +- .../probes/plugin-confinement/macos_rights.h | 95 +++ scripts/probes/plugin-confinement/run.mts | 2 +- 25 files changed, 4400 insertions(+), 9 deletions(-) create mode 100644 openspec/changes/complete-plugin-hook-runtime/macos-private-descriptor-passing.md create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/matrix.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/private-unix-missing-grant.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/source-binding.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/unix-boundary.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/unix-missing-scope.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/matrix.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/private-unix-missing-grant.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/source-binding.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/unix-boundary.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/unix-missing-scope.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-local/boundary.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-local/drop-rights.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-local/missing-scope.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-local/packaged-native.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-local/path-reader.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-local/runtime-native.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-local/runtime-node.json create mode 100644 scripts/probes/plugin-confinement/macos_rights.h diff --git a/.github/workflows/plugin-confinement-proof.yml b/.github/workflows/plugin-confinement-proof.yml index 93261ac75..68795c3ab 100644 --- a/.github/workflows/plugin-confinement-proof.yml +++ b/.github/workflows/plugin-confinement-proof.yml @@ -194,6 +194,54 @@ jobs: '"private_aliases":[true,true]', '"private_peer_matches":true']: assert token in text, text PYCONTROL + - name: Reject missing private descriptor reception + shell: bash + run: | + set -euo pipefail + log="$RUNNER_TEMP/unix-dropped-rights.log" + if node --experimental-strip-types scripts/probes/plugin-confinement/macos_private_ipc.mts --drop-rights > "$log" 2>&1; then + echo 'Missing SCM_RIGHTS reception unexpectedly passed' >&2 + exit 1 + fi + python3 - "$log" <<'PYCONTROL' + from pathlib import Path + import sys + text = Path(sys.argv[1]).read_text() + assert 'private SCM_RIGHTS exchange failed:' in text, text + for token in ['"original_closed":true', '"sent":true', '"token":true', + '"received":false', '"rights_payload":"A"', '"private_aliases":[true,true]']: + assert token in text, text + PYCONTROL + - name: Reject owner payload path re-resolution + shell: bash + run: | + set -euo pipefail + control="$RUNNER_TEMP/macos-rights-path-reader" + python3 - "$control" <<'PYCONTROL' + from pathlib import Path + import shutil, sys + target = Path(sys.argv[1]) + shutil.copytree('scripts/probes/plugin-confinement', target, ignore=shutil.ignore_patterns('evidence', '__pycache__')) + driver = target / 'macos_private_ipc.mts' + text = driver.read_text() + before = ' const rights_payload = contents.subarray(0, count).toString();' + assert text.count(before) == 1 + driver.write_text(text.replace(before, ' const rights_payload = readFileSync(join(paths.scratch, "rights.bin"), "utf8");')) + PYCONTROL + log="$RUNNER_TEMP/unix-rights-path-reader.log" + if node --experimental-strip-types "$control/macos_private_ipc.mts" > "$log" 2>&1; then + echo 'Owner path re-resolution unexpectedly passed' >&2 + exit 1 + fi + python3 - "$log" <<'PYCONTROL' + from pathlib import Path + import sys + text = Path(sys.argv[1]).read_text() + assert 'received descriptor file effect:' in text, text + for token in ['"rights_path_replaced":true', '"rights_link_count":0', + '"rights_payload":"XX"', '"written":true', '"original_closed":true']: + assert token in text, text + PYCONTROL - name: Retain signing-identity candidate evidence if: always() uses: actions/upload-artifact@v4 @@ -206,6 +254,8 @@ jobs: ${{ runner.temp }}/unix-boundary.json ${{ runner.temp }}/unix-boundary.log ${{ runner.temp }}/unix-missing-scope.log + ${{ runner.temp }}/unix-dropped-rights.log + ${{ runner.temp }}/unix-rights-path-reader.log ${{ runner.temp }}/exec.json ${{ runner.temp }}/exec.log if-no-files-found: error diff --git a/openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md b/openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md index 22d19e513..d48d3e062 100644 --- a/openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md +++ b/openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md @@ -79,3 +79,25 @@ Still required: concurrent alias replacement, datagram/seqpacket, ancillary FD and credential behavior, proxy/network intersections, immutable owner admission, full resource settlement and actual App/server execution. Native and parent task checkboxes remain open. + +## Hosted result for bf87b7b9 + +[Run 41098929223](https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41098929223) +passes both native signing jobs on macOS arm64 and Intel, Darwin 24.6.0. Each +architecture has nine owned-listener cases and nine native runtime cases. +Private streams, both private aliases and all eight peer identity checks pass; +only the unconfined control delivers its three host tokens. The missing-scope +and missing-grant controls fail their exact assertions. + +Original reports and logs are retained under +`scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/{arm64,x64}`. +Both checkout logs identify merge `de3eabe960ec62c2820eea11c56ff208cd48a9ae`; +its tree equals source head `bf87b7b9ecc4e179902b78147fa9fd737c5bf629`. +Both source manifests above were independently recomputed from that Git tree. +A separate binding receipt records these checks without modifying the original +reports. This is native-only hosted acceptance for the named cases, not the full +five-runtime matrix or production support. + +The subsequent [private descriptor extension](macos-private-descriptor-passing.md) +adds real SCM_RIGHTS transfer and a pinned owner file-effect check resilient to +guest pathname replacement. The receipts above do not cover that extension. diff --git a/openspec/changes/complete-plugin-hook-runtime/macos-private-descriptor-passing.md b/openspec/changes/complete-plugin-hook-runtime/macos-private-descriptor-passing.md new file mode 100644 index 000000000..6402e8329 --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/macos-private-descriptor-passing.md @@ -0,0 +1,64 @@ +# macOS private descriptor passing and pinned owner effects + +This extends the approved native IPC proof independently of the pending Linux +mediation decision. It does not activate production admission or complete the +remaining ancillary/network compatibility requirements. + +Each owned-listener case now sends one dummy-file descriptor over a private +stream socketpair using SCM_RIGHTS. The sender closes its original descriptor +and checks EBADF before reception. The receiver requires the actual SCM_RIGHTS +header, one descriptor, matching regular-file device/inode identity, successful +read/write and a verified FD_CLOEXEC flag. Successful byte delivery alone cannot +stand in for descriptor reception. + +The parent creates and pins the empty dummy file before launching the guest. +The guest writes `A`, transfers its independently opened descriptor, then reads +`A` and writes `B` through the received descriptor. It subsequently unlinks the +original pathname and replaces it with a symlink to another owned dummy file +containing `XX`. After guest settlement, the parent reads at most three bytes +from its retained descriptor, checks regular-file type and the two-byte limit, +requires link count zero and observes `AB`. It never reopens the guest-controlled +path. This avoids an unbounded or symlink-following owner read while confirming +the file effect belongs to the original owned object. + +Two precise controls cover different failures: + +- `--drop-rights` removes the receive control buffer only in confined cases. + Its unconfined control still passes; the first confined case receives `T`, + has closed its original sender descriptor, receives no descriptor and leaves + the pinned file as `A`. It must fail `private SCM_RIGHTS exchange failed`. + The local Darwin kernel does not set MSG_CTRUNC in this case. The result is + recorded; absence of that flag is not used as evidence of descriptor reception. +- A temporary copied driver reopens the substituted pathname for its final + file-effect observation. Genuine descriptor operations and path replacement + succeed, but it reads `XX` and must fail `received descriptor file effect`. + This directly detects regression from pinned ownership to path re-resolution. + +The existing widened-network-scope control remains and must still reach the +owned host listener after all private operations succeed. Invalid startup or a +broken private exchange cannot satisfy these controls. The new header is in +both source manifests; runtime fixtures using other modes retain their original +behavior. + +## Local result + +On macOS arm64/Darwin 25.6.0, all nine descriptor/listener cases pass. All eight +capability combinations preserve private streams/aliases, correct peer identity, +SCM_RIGHTS transfer and the owner-observed `AB` effect on the unlinked original, +while delivering no host token. All three counterexamples fail their named +assertions after their required positive operations. The native fixture-built, +native packaged-helper and Node runtime regressions each pass nine cases: 27 +runtime cases in addition to the nine extended native cases. Other runtime and +hosted Intel/arm64 checks remain pending for this revision. + +Reports and control logs are retained under +`scripts/probes/plugin-confinement/evidence/macos-private-rights-local`. +The independently recomputed descriptor/listener manifest SHA-256 is +`76fa300cb4534e9d5e571d84b9560db6845eab015cefa10f02023721b4399c1c`; +the runtime manifest SHA-256 is +`dc8028c477b35faa33f4b99183bc2c6e2c8f54c81d58e0785e462eeecdd8e67f`. + +Still required: concurrent endpoint mutation, datagram/seqpacket, ancillary +credential behavior and broader descriptor cases, proxy/network/secret ceilings, +complete native resource ownership and actual App/server execution. Parent +acceptance tasks remain open. diff --git a/scripts/probes/plugin-confinement/README.md b/scripts/probes/plugin-confinement/README.md index b000dc018..9d3ede246 100644 --- a/scripts/probes/plugin-confinement/README.md +++ b/scripts/probes/plugin-confinement/README.md @@ -91,6 +91,11 @@ listener. Its nine native cases require private socket aliases and correct peer PID/UID/GID while denying actual host delivery. `--missing-scope` must expose the owned host endpoint and fail the named isolation assertion. See the [owned-listener evidence and limits](../../../openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md). +The same driver now requires real private SCM_RIGHTS reception after closing the +sender's original descriptor. Its owner observes effects on a pre-pinned file +after the guest replaces the pathname. `--drop-rights` and a copied path-reader +control must fail their precise assertions. See +[descriptor-passing evidence](../../../openspec/changes/complete-plugin-hook-runtime/macos-private-descriptor-passing.md). ## Boundary and coverage diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/matrix.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/matrix.json new file mode 100644 index 000000000..74b106e80 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/matrix.json @@ -0,0 +1,544 @@ +{ + "recorded_at": "2026-10-30T17:40:43.194Z", + "kernel_release": "24.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "b8db40c4efa39e283514b64648916bfb3657e2233f9c7a3c7194be949fe620c1", + "platform": "darwin", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.ad6bd2f9-0b3b-4c52-bbd1-8ad28fd37abe", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/private-unix-missing-grant.log b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/private-unix-missing-grant.log new file mode 100644 index 000000000..dcc00a681 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/private-unix-missing-grant.log @@ -0,0 +1,31 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: no-capabilities: private UNIX runtime exchange failed: [false,false] ++ actual - expected + + [ ++ false, ++ false +- true, +- true + ] + + at check (file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:298:12) + at file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:402:31 + at Array.map () + at main (file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:402:8) + at file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:425:1 + at ModuleJob.run (node:internal/modules/esm/module_job:343:25) + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:681:26) + at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: [ false, false ], + expected: [ true, true ], + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.23.4 diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/source-binding.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/source-binding.json new file mode 100644 index 000000000..e0c888f7a --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/source-binding.json @@ -0,0 +1,10 @@ +{ + "scope": "Independent checkout/source binding; original reports are retained unmodified.", + "run_id": "41098929223", + "job_id": 124211899622, + "tested_merge": "de3eabe960ec62c2820eea11c56ff208cd48a9ae", + "source_head": "bf87b7b9ecc4e179902b78147fa9fd737c5bf629", + "tree_equal": true, + "checkout_evidence": "Git SHA printed by actions/checkout in this job log", + "source_manifests_independently_verified": true +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/unix-boundary.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/unix-boundary.json new file mode 100644 index 000000000..81b61afce --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/unix-boundary.json @@ -0,0 +1,379 @@ +{ + "recorded_at": "2026-10-30T17:40:45.100Z", + "platform": "darwin", + "architecture": "arm64", + "kernel_release": "24.6.0", + "sources": [ + "macos_private_ipc.mts", + "macos_policy.mts", + "fixture_native.c", + "process_policy.h", + "macos_exec.c" + ], + "source_sha256": "fbe318d5d33b107ef35c988168203d005b87a11c24805f412a27bb65c5511416", + "target_sha256": "bde4a8f8a5628b28c5b247d0a42d94db17ed8ea97bc2f2f15e5f81f09ee8db11", + "rows": [ + { + "name": "unconfined", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": true, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "hardlink": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "symlink": { + "connected": true, + "sent": true, + "acknowledged": true + } + }, + "owner_receipts": 3, + "owner_received_fixture": true + }, + { + "name": "r0w0s0", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w0s1", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w1s0", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w1s1", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w0s0", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w0s1", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w1s0", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w1s1", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + } + ], + "scope": "Experimental pre-runtime native UNIX stream controls only; complete IPC/proxy/ownership and App acceptance remain required." +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/unix-missing-scope.log b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/unix-missing-scope.log new file mode 100644 index 000000000..9bbddfb0e --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/arm64/unix-missing-scope.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: macOS UNIX socket boundary escaped scratch: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"owner_receipts":2,"owner_received_fixture":true} + +true !== false + + at check (file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:113:12) + at file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:135:5 + at process.processTicksAndRejections (node:internal/process/task_queues:103:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.23.4 diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/matrix.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/matrix.json new file mode 100644 index 000000000..d884e3781 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/matrix.json @@ -0,0 +1,544 @@ +{ + "recorded_at": "2026-10-30T17:31:07.588Z", + "kernel_release": "24.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "b8db40c4efa39e283514b64648916bfb3657e2233f9c7a3c7194be949fe620c1", + "platform": "darwin", + "architecture": "x64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.29397e87-672e-4d92-9d17-b40b96e78a50", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/private-unix-missing-grant.log b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/private-unix-missing-grant.log new file mode 100644 index 000000000..fa1873517 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/private-unix-missing-grant.log @@ -0,0 +1,31 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: no-capabilities: private UNIX runtime exchange failed: [false,false] ++ actual - expected + + [ ++ false, ++ false +- true, +- true + ] + + at check (file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:298:12) + at file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:402:31 + at Array.map () + at main (file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:402:8) + at file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:425:1 + at ModuleJob.run (node:internal/modules/esm/module_job:343:25) + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:681:26) + at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: [ false, false ], + expected: [ true, true ], + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.23.2 diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/source-binding.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/source-binding.json new file mode 100644 index 000000000..f35f93492 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/source-binding.json @@ -0,0 +1,10 @@ +{ + "scope": "Independent checkout/source binding; original reports are retained unmodified.", + "run_id": "41098929223", + "job_id": 124211899875, + "tested_merge": "de3eabe960ec62c2820eea11c56ff208cd48a9ae", + "source_head": "bf87b7b9ecc4e179902b78147fa9fd737c5bf629", + "tree_equal": true, + "checkout_evidence": "Git SHA printed by actions/checkout in this job log", + "source_manifests_independently_verified": true +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/unix-boundary.json b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/unix-boundary.json new file mode 100644 index 000000000..64d71285d --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/unix-boundary.json @@ -0,0 +1,379 @@ +{ + "recorded_at": "2026-10-30T17:31:10.423Z", + "platform": "darwin", + "architecture": "x64", + "kernel_release": "24.6.0", + "sources": [ + "macos_private_ipc.mts", + "macos_policy.mts", + "fixture_native.c", + "process_policy.h", + "macos_exec.c" + ], + "source_sha256": "fbe318d5d33b107ef35c988168203d005b87a11c24805f412a27bb65c5511416", + "target_sha256": "5e38f2d24cf7ef12a2ec063c1a86cb712d4ed2b3b3190eb6ca8b93ae6502b2ce", + "rows": [ + { + "name": "unconfined", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": true, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "hardlink": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "symlink": { + "connected": true, + "sent": true, + "acknowledged": true + } + }, + "owner_receipts": 3, + "owner_received_fixture": true + }, + { + "name": "r0w0s0", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w0s1", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w1s0", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w1s1", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w0s0", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w0s1", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w1s0", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w1s1", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "owner_receipts": 0, + "owner_received_fixture": false + } + ], + "scope": "Experimental pre-runtime native UNIX stream controls only; complete IPC/proxy/ownership and App acceptance remain required." +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/unix-missing-scope.log b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/unix-missing-scope.log new file mode 100644 index 000000000..f6db6f116 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-owned-unix-bf87b7b9/x64/unix-missing-scope.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: macOS UNIX socket boundary escaped scratch: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"owner_receipts":2,"owner_received_fixture":true} + +true !== false + + at check (file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:113:12) + at file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:135:5 + at process.processTicksAndRejections (node:internal/process/task_queues:103:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.23.2 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/boundary.json b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/boundary.json new file mode 100644 index 000000000..8f42de5e1 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/boundary.json @@ -0,0 +1,506 @@ +{ + "recorded_at": "2026-10-30T17:49:41.764Z", + "platform": "darwin", + "architecture": "arm64", + "kernel_release": "25.6.0", + "sources": [ + "macos_private_ipc.mts", + "macos_policy.mts", + "macos_rights.h", + "fixture_native.c", + "process_policy.h", + "macos_exec.c" + ], + "source_sha256": "76fa300cb4534e9d5e571d84b9560db6845eab015cefa10f02023721b4399c1c", + "target_sha256": "c09e648d200f2636b240691600be6f1ff8eb54f37a327d0a1d800f513057f9a0", + "rows": [ + { + "name": "unconfined", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": true, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "hardlink": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "symlink": { + "connected": true, + "sent": true, + "acknowledged": true + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 3, + "owner_received_fixture": true + }, + { + "name": "r0w0s0", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w0s1", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w1s0", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w1s1", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w0s0", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w0s1", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w1s0", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w1s1", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + } + ], + "scope": "Experimental pre-runtime native UNIX stream controls only; complete IPC/proxy/ownership and App acceptance remain required." +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/drop-rights.log b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/drop-rights.log new file mode 100644 index 000000000..720087c3e --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/drop-rights.log @@ -0,0 +1,56 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: private SCM_RIGHTS exchange failed: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":false,"same_inode":false,"readable":false,"written":false,"cloexec":false},"rights_path_replaced":true,"direct":{"connected":false,"sent":false,"acknowledged":false},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":false,"sent":false,"acknowledged":false}},"rights_payload":"A","rights_link_count":0,"owner_receipts":0,"owner_received_fixture":false} ++ actual - expected + + { ++ cloexec: false, +- cloexec: true, + original_closed: true, ++ readable: false, ++ received: false, ++ same_inode: false, +- readable: true, +- received: true, +- same_inode: true, + sent: true, + token: true, + truncated: false, ++ written: false +- written: true + } + + at check (file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:121:10) + at file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:154:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: { + sent: true, + original_closed: true, + token: true, + truncated: false, + received: false, + same_inode: false, + readable: false, + written: false, + cloexec: false + }, + expected: { + sent: true, + original_closed: true, + token: true, + truncated: false, + received: true, + same_inode: true, + readable: true, + written: true, + cloexec: true + }, + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/missing-scope.log b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/missing-scope.log new file mode 100644 index 000000000..2ebecc013 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/missing-scope.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: macOS UNIX socket boundary escaped scratch: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"AB","rights_link_count":0,"owner_receipts":2,"owner_received_fixture":true} + +true !== false + + at check (file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:131:12) + at file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:154:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/packaged-native.json b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/packaged-native.json new file mode 100644 index 000000000..4ea8dd617 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/packaged-native.json @@ -0,0 +1,551 @@ +{ + "recorded_at": "2026-10-30T17:53:37.034Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "dc8028c477b35faa33f4b99183bc2c6e2c8f54c81d58e0785e462eeecdd8e67f", + "platform": "darwin", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.dc69a69c-b9ea-4d6b-8cf7-d7dcac1b7f24", + "packaged_helper": { + "input_sha256": "64ee74d21d1ddc470989450014f1e89fa33ab5aec230cd998890df3ec5717225", + "executed_sha256": "509acd0fdb51934cb7359c52723afdc28af1fe2915d6cb0d59c727b7aae51333", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": true, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/path-reader.log b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/path-reader.log new file mode 100644 index 000000000..136751921 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/path-reader.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: received descriptor file effect: {"name":"unconfined","flags":{"read":true,"write":true,"shell":true,"unrestricted":true},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":true,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":true,"sent":true,"acknowledged":true},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"XX","rights_link_count":0,"owner_receipts":3,"owner_received_fixture":true} + +'XX' !== 'AB' + + at check (file:///private/tmp/cyber-rights-path-8t3pepns/source/macos_private_ipc.mts:125:10) + at file:///private/tmp/cyber-rights-path-8t3pepns/source/macos_private_ipc.mts:154:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 'XX', + expected: 'AB', + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/runtime-native.json b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/runtime-native.json new file mode 100644 index 000000000..55cd1b3ff --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/runtime-native.json @@ -0,0 +1,545 @@ +{ + "recorded_at": "2026-10-30T17:53:37.989Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "dc8028c477b35faa33f4b99183bc2c6e2c8f54c81d58e0785e462eeecdd8e67f", + "platform": "darwin", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.af5b3b56-838f-4bd8-9b63-c0663687666c", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/runtime-node.json b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/runtime-node.json new file mode 100644 index 000000000..9ed2871c1 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-local/runtime-node.json @@ -0,0 +1,464 @@ +{ + "recorded_at": "2026-10-30T17:53:41.691Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "dc8028c477b35faa33f4b99183bc2c6e2c8f54c81d58e0785e462eeecdd8e67f", + "platform": "darwin", + "architecture": "arm64", + "runtime": "node", + "version": "22.20.0", + "signing_identifier": "com.cyberdyne.probe.bootstrap.8e6a2ec3-ee55-42d8-b580-227f0a88077c", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/fixture_native.c b/scripts/probes/plugin-confinement/fixture_native.c index 3fc3fff8e..9eea90805 100644 --- a/scripts/probes/plugin-confinement/fixture_native.c +++ b/scripts/probes/plugin-confinement/fixture_native.c @@ -153,6 +153,7 @@ static int private_stream_probe(const char *scratch, int result[2]) { } #ifdef __APPLE__ +#include "macos_rights.h" struct unix_attempt { int connected, sent, acknowledged; }; static struct unix_attempt host_unix_attempt(const char *path) { struct unix_attempt result = {0}; @@ -186,6 +187,9 @@ static int unix_boundary(const char *scratch, const char *host) { if (!joined(owned, scratch, "owned.sock") || !joined(owned_alias, scratch, "owned-alias.sock")) return 2; int own_hardlink = private_stream_exchange_to(owned, owned_alias, 1); int own_symlink = private_stream_exchange_to(owned, owned_alias, 2); + const char *drop = getenv("CYBER_PROOF_DROP_RIGHTS"); + struct rights_result rights = private_rights(scratch, drop != NULL && strcmp(drop, "1") == 0); + int rights_path_replaced = replace_rights_path(scratch); struct unix_attempt direct = host_unix_attempt(host); char alias[PATH_MAX], symbolic[PATH_MAX]; if (!joined(alias, scratch, "host-alias.sock") || !joined(symbolic, scratch, "host-symlink.sock")) return 2; @@ -197,6 +201,8 @@ static int unix_boundary(const char *scratch, const char *host) { "\"private_peer_matches\":%s,\"hardlink_created\":%s,\"symlink_created\":%s", truth(ipc[0]), truth(ipc[1]), private_peer_checks, truth(private_peer_matches), truth(linked), truth(symlinked)); printf(",\"private_aliases\":[%s,%s]", truth(own_hardlink), truth(own_symlink)); + print_rights(rights); + printf(",\"rights_path_replaced\":%s", truth(rights_path_replaced)); print_unix_attempt("direct", direct); print_unix_attempt("hardlink", hardlink); print_unix_attempt("symlink", symlink_result); diff --git a/scripts/probes/plugin-confinement/macos_private_ipc.mts b/scripts/probes/plugin-confinement/macos_private_ipc.mts index f06a33993..c7086d4bf 100644 --- a/scripts/probes/plugin-confinement/macos_private_ipc.mts +++ b/scripts/probes/plugin-confinement/macos_private_ipc.mts @@ -2,7 +2,7 @@ import assert from "node:assert/strict"; import { execFile, spawnSync } from "node:child_process"; import { createHash, randomUUID } from "node:crypto"; -import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs"; +import { closeSync, constants, fstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, readSync, realpathSync, rmSync, writeFileSync } from "node:fs"; import { createServer } from "node:net"; import { release } from "node:os"; import { dirname, join } from "node:path"; @@ -68,7 +68,7 @@ async function owner(path: string) { }; } -async function row(root: string, prepared: ReturnType, name: string, flags: Flags, missingScope: boolean) { +async function row(root: string, prepared: ReturnType, name: string, flags: Flags, missingScope: boolean, dropRights: boolean) { const base = join(root, name); mkdirSync(base, { mode: 0o700 }); const paths: Record = { package: prepared.packagePath }; @@ -78,7 +78,9 @@ async function row(root: string, prepared: ReturnType, name: str } const host = join(paths.project, "host.sock"); const listener = await owner(host); + let payload = -1; try { + payload = openSync(join(paths.scratch, "rights.bin"), constants.O_RDWR | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600); let profile = policy({ kind: "native", executable: prepared.target, libdir: "/usr/lib" }, paths, flags, false, prepared.identifier, true); if (missingScope) { const before = `(remote unix-socket (subpath ${JSON.stringify(paths.scratch)}))`; @@ -88,14 +90,23 @@ async function row(root: string, prepared: ReturnType, name: str const file = join(root, `policy-${name}.sb`); writeFileSync(file, profile, { mode: 0o600 }); const result = await execute(prepared.helper, [flags.unrestricted ? "-" : file, prepared.target, "unix-boundary", paths.scratch, host], { - cwd: paths.scratch, env: environment, encoding: "utf8", timeout: 15_000, maxBuffer: 65536, + cwd: paths.scratch, env: { ...environment, ...dropRights && !flags.unrestricted ? { CYBER_PROOF_DROP_RIGHTS: "1" } : {} }, + encoding: "utf8", timeout: 15_000, maxBuffer: 65536, }); const observed = JSON.parse(result.stdout); const receipt = listener.receipt(); assert(!receipt.invalid, "invalid owned-listener protocol"); - return { name, flags, observed, owner_receipts: receipt.count, owner_received_fixture: receipt.count > 0 }; + const identity = fstatSync(payload); + assert(identity.isFile() && identity.size <= 2, "invalid owned rights payload"); + const contents = Buffer.alloc(3); + const count = readSync(payload, contents, 0, contents.length, 0); + assert(count <= 2, "oversized owned rights payload"); + const rights_payload = contents.subarray(0, count).toString(); + return { name, flags, observed, rights_payload, rights_link_count: identity.nlink, + owner_receipts: receipt.count, owner_received_fixture: receipt.count > 0 }; } finally { - await listener.close(); + try { await listener.close(); } + finally { if (payload >= 0) closeSync(payload); } } } @@ -105,6 +116,13 @@ function check(entry: Awaited>) { assert.deepEqual(entry.observed.private_aliases, [true, true], `private aliases: ${JSON.stringify(entry)}`); assert.equal(entry.observed.private_peer_checks, 8); assert.equal(entry.observed.private_peer_matches, true, `private peer identity: ${JSON.stringify(entry)}`); + assert.equal(entry.observed.rights_path_replaced, true); + assert.equal(entry.rights_link_count, 0, `original owner payload remained linked: ${JSON.stringify(entry)}`); + assert.deepEqual(entry.observed.rights, { + sent: true, original_closed: true, token: true, truncated: false, received: true, + same_inode: true, readable: true, written: true, cloexec: true, + }, `private SCM_RIGHTS exchange failed: ${JSON.stringify(entry)}`); + assert.equal(entry.rights_payload, "AB", `received descriptor file effect: ${JSON.stringify(entry)}`); if (entry.flags.unrestricted) { assert.equal(entry.observed.hardlink_created, true); assert.equal(entry.observed.symlink_created, true); @@ -120,7 +138,8 @@ function check(entry: Awaited>) { } assert.equal(process.platform, "darwin", "macOS native UNIX boundary proof requires Darwin"); -const { values } = parseArgs({ options: { report: { type: "string" }, "missing-scope": { type: "boolean", default: false } } }); +const { values } = parseArgs({ options: { report: { type: "string" }, "missing-scope": { type: "boolean", default: false }, "drop-rights": { type: "boolean", default: false } } }); +assert(!(values["missing-scope"] && values["drop-rights"]), "select one precise control"); const root = realpathSync(mkdtempSync("/tmp/cyber-unix-")); try { const prepared = prepare(root); @@ -131,12 +150,12 @@ try { cases.push([`r${+read}w${+write}s${+shell}`, { read, write, shell }]); } for (const [name, flags] of cases) { - const observed = await row(root, prepared, name, flags, values["missing-scope"]); + const observed = await row(root, prepared, name, flags, values["missing-scope"], values["drop-rights"]); check(observed); rows.push(observed); } assert.equal(createHash("sha256").update(readFileSync(prepared.target)).digest("hex"), targetHash); - const sources = ["macos_private_ipc.mts", "macos_policy.mts", "fixture_native.c", "process_policy.h", "macos_exec.c"]; + const sources = ["macos_private_ipc.mts", "macos_policy.mts", "macos_rights.h", "fixture_native.c", "process_policy.h", "macos_exec.c"]; const hash = createHash("sha256"); for (const file of sources) hash.update(file + "\0").update(readFileSync(join(source, file))); const report = { recorded_at: new Date().toISOString(), platform: process.platform, architecture: process.arch, diff --git a/scripts/probes/plugin-confinement/macos_rights.h b/scripts/probes/plugin-confinement/macos_rights.h new file mode 100644 index 000000000..3de53b202 --- /dev/null +++ b/scripts/probes/plugin-confinement/macos_rights.h @@ -0,0 +1,95 @@ +/* Native fixture compatibility check; no policy installation or production API. */ +#ifndef CYBER_MACOS_RIGHTS_H +#define CYBER_MACOS_RIGHTS_H +#include + +struct rights_result { + int sent, original_closed, token, truncated, received, same_inode, readable, written, cloexec; +}; + +static int rights_send(int channel, int descriptor) { + union { struct cmsghdr alignment; char bytes[CMSG_SPACE(sizeof(int))]; } control = {0}; + struct iovec body = { .iov_base = (void *)"T", .iov_len = 1 }; + struct msghdr message = { .msg_iov = &body, .msg_iovlen = 1, + .msg_control = control.bytes, .msg_controllen = sizeof(control.bytes) }; + struct cmsghdr *header = CMSG_FIRSTHDR(&message); + header->cmsg_level = SOL_SOCKET; + header->cmsg_type = SCM_RIGHTS; + header->cmsg_len = CMSG_LEN(sizeof(int)); + memcpy(CMSG_DATA(header), &descriptor, sizeof(descriptor)); + return sendmsg(channel, &message, 0) == 1; +} + +static int rights_receive(int channel, int drop, struct rights_result *result) { + union { struct cmsghdr alignment; char bytes[CMSG_SPACE(sizeof(int))]; } control = {0}; + char token = 0; + struct iovec body = { .iov_base = &token, .iov_len = 1 }; + struct msghdr message = { .msg_iov = &body, .msg_iovlen = 1, + .msg_control = drop ? NULL : control.bytes, + .msg_controllen = drop ? 0 : sizeof(control.bytes) }; + result->token = recvmsg(channel, &message, 0) == 1 && token == 'T'; + result->truncated = (message.msg_flags & MSG_CTRUNC) != 0; + int descriptor = -1; + struct cmsghdr *header = CMSG_FIRSTHDR(&message); + if (header != NULL && header->cmsg_level == SOL_SOCKET && header->cmsg_type == SCM_RIGHTS && + header->cmsg_len == CMSG_LEN(sizeof(int))) memcpy(&descriptor, CMSG_DATA(header), sizeof(descriptor)); + if (!result->token || result->truncated || descriptor < 0 || CMSG_NXTHDR(&message, header) != NULL) { + if (descriptor >= 0) close(descriptor); + return -1; + } + return descriptor; +} + +static struct rights_result private_rights(const char *scratch, int drop) { + struct rights_result result = {0}; + char path[PATH_MAX]; + if (!joined(path, scratch, "rights.bin")) return result; + int original = open(path, O_RDWR | O_NOFOLLOW), received = -1; + int pair[2] = {-1, -1}; + struct stat before, after; + if (original < 0 || write(original, "A", 1) != 1 || fstat(original, &before) != 0 || + lseek(original, 0, SEEK_SET) != 0 || socketpair(AF_UNIX, SOCK_STREAM, 0, pair) != 0) goto done; + struct timeval timeout = { .tv_sec = 2 }; + if (setsockopt(pair[1], SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) != 0) goto done; + result.sent = rights_send(pair[0], original); + int old = original; + if (close(original) != 0) { original = -1; goto done; } + original = -1; + result.original_closed = fcntl(old, F_GETFD) < 0 && errno == EBADF; + if (!result.sent) goto done; + received = rights_receive(pair[1], drop, &result); + result.received = received >= 0; + if (received < 0) goto done; + result.same_inode = fstat(received, &after) == 0 && S_ISREG(after.st_mode) && + before.st_dev == after.st_dev && before.st_ino == after.st_ino; + char byte = 0, contents[2] = {0}; + result.readable = read(received, &byte, 1) == 1 && byte == 'A'; + result.written = result.readable && write(received, "B", 1) == 1 && lseek(received, 0, SEEK_SET) == 0 && + read(received, contents, sizeof(contents)) == 2 && memcmp(contents, "AB", 2) == 0; + int set_flags = fcntl(received, F_SETFD, FD_CLOEXEC), flags = fcntl(received, F_GETFD); + result.cloexec = set_flags == 0 && flags >= 0 && (flags & FD_CLOEXEC) != 0; +done: + if (original >= 0) close(original); + if (received >= 0) close(received); + if (pair[0] >= 0) close(pair[0]); + if (pair[1] >= 0) close(pair[1]); + return result; +} + +static int replace_rights_path(const char *scratch) { + char original[PATH_MAX], replacement[PATH_MAX]; + if (!joined(original, scratch, "rights.bin") || !joined(replacement, scratch, "rights-fake.bin")) return 0; + int fd = open(replacement, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0600); + if (fd < 0) return 0; + int written = write(fd, "XX", 2) == 2; + close(fd); + return written && unlink(original) == 0 && symlink("rights-fake.bin", original) == 0; +} + +static void print_rights(struct rights_result result) { + printf(",\"rights\":{\"sent\":%s,\"original_closed\":%s,\"token\":%s,\"truncated\":%s," + "\"received\":%s,\"same_inode\":%s,\"readable\":%s,\"written\":%s,\"cloexec\":%s}", + truth(result.sent), truth(result.original_closed), truth(result.token), truth(result.truncated), + truth(result.received), truth(result.same_inode), truth(result.readable), truth(result.written), truth(result.cloexec)); +} +#endif diff --git a/scripts/probes/plugin-confinement/run.mts b/scripts/probes/plugin-confinement/run.mts index 5958f603f..9f7e6dd4e 100644 --- a/scripts/probes/plugin-confinement/run.mts +++ b/scripts/probes/plugin-confinement/run.mts @@ -401,7 +401,7 @@ function main() { const rows = cases.filter(([name]) => !unsupported_cases.some(item => item.name === name)) .map(([name, flags]) => check(root, artifacts, runtime, name, flags)); const digest = createHash("sha256"); - const sources = ["run.mts", "macos_policy.mts", "macos_python.c", "macos_node.c", "native_exec.c", "node_bootstrap.cjs", "fixture.py", "fixture.cjs", "private_unix.cjs", "process_policy.h", "linux_filter.h", "linux_exec.c", "linux_initial_exec.h", "fixture_native.c", "macos_exec.c", "macos_stage.mts"]; + const sources = ["run.mts", "macos_policy.mts", "macos_rights.h", "macos_python.c", "macos_node.c", "native_exec.c", "node_bootstrap.cjs", "fixture.py", "fixture.cjs", "private_unix.cjs", "process_policy.h", "linux_filter.h", "linux_exec.c", "linux_initial_exec.h", "fixture_native.c", "macos_exec.c", "macos_stage.mts"]; for (const file of sources) { digest.update(file + "\0").update(readFileSync(join(source, file))); } From 68affad0c56577c548ee6a7b432461fab3859bd0 Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 15:05:49 -0400 Subject: [PATCH 16/21] test(plugins): verify native macOS datagram boundaries --- .../workflows/plugin-confinement-proof.yml | 3 +- .../macos-owned-unix-boundary.md | 3 + .../macos-private-datagrams.md | 57 ++ .../macos-private-descriptor-passing.md | 24 +- scripts/probes/plugin-confinement/README.md | 4 + .../packaged-native.json | 552 +++++++++++ .../runtime-native.json | 546 +++++++++++ .../runtime-node.json | 465 ++++++++++ .../unix-boundary.json | 855 ++++++++++++++++++ .../unix-dropped-rights.log | 56 ++ .../unix-missing-scope.log | 20 + .../unix-rights-path-reader.log | 20 + .../arm64/matrix.json | 545 +++++++++++ .../arm64/private-unix-missing-grant.log | 31 + .../arm64/source-binding.json | 10 + .../arm64/unix-boundary.json | 506 +++++++++++ .../arm64/unix-dropped-rights.log | 56 ++ .../arm64/unix-missing-scope.log | 20 + .../arm64/unix-rights-path-reader.log | 20 + .../check-summary.json | 402 ++++++++ .../x64/matrix.json | 545 +++++++++++ .../x64/private-unix-missing-grant.log | 31 + .../x64/source-binding.json | 10 + .../x64/unix-boundary.json | 506 +++++++++++ .../x64/unix-dropped-rights.log | 56 ++ .../x64/unix-missing-scope.log | 20 + .../x64/unix-rights-path-reader.log | 20 + .../plugin-confinement/fixture_native.c | 8 +- .../plugin-confinement/macos_datagram.h | 95 ++ .../plugin-confinement/macos_datagram_owner.c | 63 ++ .../macos_datagram_owner.mts | 57 ++ .../plugin-confinement/macos_private_ipc.mts | 50 +- scripts/probes/plugin-confinement/run.mts | 2 +- 33 files changed, 5641 insertions(+), 17 deletions(-) create mode 100644 openspec/changes/complete-plugin-hook-runtime/macos-private-datagrams.md create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/packaged-native.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/runtime-native.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/runtime-node.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-boundary.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-dropped-rights.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-missing-scope.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-rights-path-reader.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/matrix.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/private-unix-missing-grant.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/source-binding.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-boundary.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-dropped-rights.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-missing-scope.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-rights-path-reader.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/check-summary.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/matrix.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/private-unix-missing-grant.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/source-binding.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-boundary.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-dropped-rights.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-missing-scope.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-rights-path-reader.log create mode 100644 scripts/probes/plugin-confinement/macos_datagram.h create mode 100644 scripts/probes/plugin-confinement/macos_datagram_owner.c create mode 100644 scripts/probes/plugin-confinement/macos_datagram_owner.mts diff --git a/.github/workflows/plugin-confinement-proof.yml b/.github/workflows/plugin-confinement-proof.yml index 68795c3ab..a21ecf532 100644 --- a/.github/workflows/plugin-confinement-proof.yml +++ b/.github/workflows/plugin-confinement-proof.yml @@ -189,8 +189,9 @@ jobs: from pathlib import Path import sys text = Path(sys.argv[1]).read_text() - assert 'macOS UNIX socket boundary escaped scratch:' in text, text + assert 'macOS datagram endpoint escaped scratch:' in text, text for token in ['"owner_received_fixture":true', '"acknowledged":true', + '"owner_datagram_received_fixture":true', '"datagram_receipts":6', '"private_aliases":[true,true]', '"private_peer_matches":true']: assert token in text, text PYCONTROL diff --git a/openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md b/openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md index d48d3e062..aa24889d5 100644 --- a/openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md +++ b/openspec/changes/complete-plugin-hook-runtime/macos-owned-unix-boundary.md @@ -101,3 +101,6 @@ five-runtime matrix or production support. The subsequent [private descriptor extension](macos-private-descriptor-passing.md) adds real SCM_RIGHTS transfer and a pinned owner file-effect check resilient to guest pathname replacement. The receipts above do not cover that extension. + +The [private datagram extension](macos-private-datagrams.md) adds actual packet +receipt checks without replacing the stream, peer-identity or descriptor tests. diff --git a/openspec/changes/complete-plugin-hook-runtime/macos-private-datagrams.md b/openspec/changes/complete-plugin-hook-runtime/macos-private-datagrams.md new file mode 100644 index 000000000..79e40412c --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/macos-private-datagrams.md @@ -0,0 +1,57 @@ +# macOS private datagram delivery proof + +This extends the approved macOS IPC proof. Production admission remains gated; +the pending Linux direction review and the full goal scope are unchanged. + +The native fixture exercises private pathname UNIX datagrams with connected +`send`, destination-bearing `sendto` and destination-bearing `sendmsg`. Each +operation uses a fresh server/client pair, sends the fixed `fixture-only` token, +checks actual server reception and requires a return acknowledgement. All nine +rows also retain private stream/alias exchanges, eight peer identity checks, +SCM_RIGHTS reception and the pinned original file effect. + +A separate trusted native datagram receiver binds an owned host endpoint before +the guest starts. The guest tries six routes: direct and scratch-symlink forms of +connect/send, sendto and sendmsg. Each uses the exact owned scratch client path. +The receiver accepts only the fixed twelve-byte token from that path, records +receipt before acknowledging, and bounds packets, output and execution time. +After the guest settles, the parent requests stop; the receiver drains queued +packets and must exit successfully with an explicit final receipt report. +A failed receiver never supplies a valid zero. Child ownership uses the process +handle and cached settlement promise, including cleanup on assertion failure. + +Startup controls require a missing executable and a real failed bind to reject. +The failed-bind control also verifies an existing owned file remains unchanged. +These refusals test the recorder; they do not count as positive IPC acceptance. + +The unconfined row must receive and acknowledge all six host attempts. Each of +the eight read/write/shell combinations must retain all three private datagram +exchanges, fail all six host attempts and produce zero actual host receipts. +The `--missing-scope` control widens only the outbound UNIX endpoint scope. It +must reach both owned stream and datagram receivers, deliver six datagrams and +fail `macOS datagram endpoint escaped scratch` after the private, peer and +SCM_RIGHTS checks succeed. Dropped-rights and path-reader counterexamples remain +required and fail their separate named assertions. + +## Local evidence + +On arm64/Darwin 25.6.0, nine extended native IPC rows pass, as do nine native +fixture runtime rows, nine native packaged-helper runtime rows and nine Node +fixture runtime rows. There are no unsupported rows in these selected matrices. +All three precise counterexamples fail as intended. Source manifests were +independently recomputed against the current files before retaining evidence in +`scripts/probes/plugin-confinement/evidence/macos-private-datagram-local`. + +The IPC manifest is +`a82c76656620443cc1739f629eda53958a64551f06f1d9bb064d49455c0248d3`; +the runtime manifest is +`9db4c7e189904e31ca2954e8f82e7324e13ca9f44611a0e76039898e7f3a1b96`. +The IPC manifest includes the native receiver and its typed owner module. +The runtime manifest includes the new header compiled by the native fixture. +Hosted results for this extension are pending. Prior green hosted descriptor +results are documented separately in [descriptor passing](macos-private-descriptor-passing.md). + +These fixed pathname exchanges do not prove concurrent endpoint mutation, +seqpacket compatibility, ancillary credentials, every descriptor operation, +proxy/network/secret ceilings, complete descendant resource settlement or actual +App/server integration. Those acceptance requirements remain open. diff --git a/openspec/changes/complete-plugin-hook-runtime/macos-private-descriptor-passing.md b/openspec/changes/complete-plugin-hook-runtime/macos-private-descriptor-passing.md index 6402e8329..c668fbd74 100644 --- a/openspec/changes/complete-plugin-hook-runtime/macos-private-descriptor-passing.md +++ b/openspec/changes/complete-plugin-hook-runtime/macos-private-descriptor-passing.md @@ -48,8 +48,8 @@ SCM_RIGHTS transfer and the owner-observed `AB` effect on the unlinked original, while delivering no host token. All three counterexamples fail their named assertions after their required positive operations. The native fixture-built, native packaged-helper and Node runtime regressions each pass nine cases: 27 -runtime cases in addition to the nine extended native cases. Other runtime and -hosted Intel/arm64 checks remain pending for this revision. +runtime cases in addition to the nine extended native cases. This local run does not cover every runtime. Hosted results for the same +source revision are recorded below. Reports and control logs are retained under `scripts/probes/plugin-confinement/evidence/macos-private-rights-local`. @@ -58,7 +58,25 @@ The independently recomputed descriptor/listener manifest SHA-256 is the runtime manifest SHA-256 is `dc8028c477b35faa33f4b99183bc2c6e2c8f54c81d58e0785e462eeecdd8e67f`. -Still required: concurrent endpoint mutation, datagram/seqpacket, ancillary +## Hosted result for revision 48a5481c + +On macOS Intel and arm64/Darwin 24.6.0, both native signing jobs in +[run 41103134892](https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892) +passed nine native descriptor/listener cases and nine native runtime cases, +including all three precise controls and the missing-private-grant control. +Original reports and control logs are retained under +`scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c`. +Separate source bindings verify the checkout merge +`f40644b9e88fae0b8e1dfade009ffee2359a9495` has the same tree as +`48a5481c531fcf64db38b62a73c7fb79f290b642`, and independently recompute both +report manifests from that checkout. The check summary records 65 successful +checks and one intentionally skipped historical diagnostic for that head. +These results apply to that revision and do not verify subsequent datagram work. + +The [datagram extension](macos-private-datagrams.md) adds separately bounded +packet ownership and route checks; its evidence remains distinct. + +Still required: concurrent endpoint mutation, full datagram/seqpacket, ancillary credential behavior and broader descriptor cases, proxy/network/secret ceilings, complete native resource ownership and actual App/server execution. Parent acceptance tasks remain open. diff --git a/scripts/probes/plugin-confinement/README.md b/scripts/probes/plugin-confinement/README.md index 9d3ede246..e6e020ab1 100644 --- a/scripts/probes/plugin-confinement/README.md +++ b/scripts/probes/plugin-confinement/README.md @@ -96,6 +96,10 @@ sender's original descriptor. Its owner observes effects on a pre-pinned file after the guest replaces the pathname. `--drop-rights` and a copied path-reader control must fail their precise assertions. See [descriptor-passing evidence](../../../openspec/changes/complete-plugin-hook-runtime/macos-private-descriptor-passing.md). +It also requires private connected/sendto/sendmsg datagram exchanges and denies +six direct/symlink host routes. A bounded native owner records actual receipt +after guest settlement; startup failure cannot count as zero delivery. See +[datagram evidence and limits](../../../openspec/changes/complete-plugin-hook-runtime/macos-private-datagrams.md). ## Boundary and coverage diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/packaged-native.json b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/packaged-native.json new file mode 100644 index 000000000..006bae27d --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/packaged-native.json @@ -0,0 +1,552 @@ +{ + "recorded_at": "2026-10-30T18:58:40.178Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_datagram.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "9db4c7e189904e31ca2954e8f82e7324e13ca9f44611a0e76039898e7f3a1b96", + "platform": "darwin", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.2bd752cd-d466-4669-87ca-a46bc7f97a52", + "packaged_helper": { + "input_sha256": "64ee74d21d1ddc470989450014f1e89fa33ab5aec230cd998890df3ec5717225", + "executed_sha256": "69df3c19884fe2568b75c8b04c2ae16913e7e519970fae699dd1b3eba4f99688", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": true, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/runtime-native.json b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/runtime-native.json new file mode 100644 index 000000000..16a37a263 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/runtime-native.json @@ -0,0 +1,546 @@ +{ + "recorded_at": "2026-10-30T18:55:19.300Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_datagram.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "9db4c7e189904e31ca2954e8f82e7324e13ca9f44611a0e76039898e7f3a1b96", + "platform": "darwin", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.028b6b70-bd26-4d74-8637-253ebd5aebca", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/runtime-node.json b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/runtime-node.json new file mode 100644 index 000000000..2cdbb98f2 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/runtime-node.json @@ -0,0 +1,465 @@ +{ + "recorded_at": "2026-10-30T18:58:43.986Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_datagram.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "9db4c7e189904e31ca2954e8f82e7324e13ca9f44611a0e76039898e7f3a1b96", + "platform": "darwin", + "architecture": "arm64", + "runtime": "node", + "version": "22.20.0", + "signing_identifier": "com.cyberdyne.probe.bootstrap.de4ca88a-5bac-472e-a020-b2ee97f1117f", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-boundary.json b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-boundary.json new file mode 100644 index 000000000..687a39118 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-boundary.json @@ -0,0 +1,855 @@ +{ + "recorded_at": "2026-10-30T18:53:42.956Z", + "platform": "darwin", + "architecture": "arm64", + "kernel_release": "25.6.0", + "sources": [ + "macos_private_ipc.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_datagram.h", + "macos_datagram_owner.mts", + "macos_datagram_owner.c", + "fixture_native.c", + "process_policy.h", + "macos_exec.c" + ], + "source_sha256": "a82c76656620443cc1739f629eda53958a64551f06f1d9bb064d49455c0248d3", + "target_sha256": "74f64a24864078559ff3db3cbd6a772c64d2364b9a96637c24e55126914ecadc", + "receiver_startup_controls": { + "missing_program_refused": true, + "failed_bind_refused": true + }, + "rows": [ + { + "name": "unconfined", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": true, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "dgram_connect": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "dgram_sendto": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "dgram_sendmsg": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "dgram_alias_connect": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "dgram_alias_sendto": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "direct": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "hardlink": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "symlink": { + "connected": true, + "sent": true, + "acknowledged": true + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 3, + "owner_received_fixture": true, + "datagram_receipts": 6, + "owner_datagram_received_fixture": true + }, + { + "name": "r0w0s0", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r0w0s1", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r0w1s0", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r0w1s1", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w0s0", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w0s1", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w1s0", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w1s1", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + } + ], + "scope": "Experimental pre-runtime native UNIX stream/datagram/descriptor controls; complete IPC/proxy/ownership and App acceptance remain required." +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-dropped-rights.log b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-dropped-rights.log new file mode 100644 index 000000000..898de3a61 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-dropped-rights.log @@ -0,0 +1,56 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: private SCM_RIGHTS exchange failed: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":false,"same_inode":false,"readable":false,"written":false,"cloexec":false},"rights_path_replaced":true,"private_datagram":[true,true,true],"datagram_symlink_created":true,"dgram_connect":{"connected":false,"sent":false,"acknowledged":false},"dgram_sendto":{"connected":false,"sent":false,"acknowledged":false},"dgram_sendmsg":{"connected":false,"sent":false,"acknowledged":false},"dgram_alias_connect":{"connected":false,"sent":false,"acknowledged":false},"dgram_alias_sendto":{"connected":false,"sent":false,"acknowledged":false},"dgram_alias_sendmsg":{"connected":false,"sent":false,"acknowledged":false},"direct":{"connected":false,"sent":false,"acknowledged":false},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":false,"sent":false,"acknowledged":false}},"rights_payload":"A","rights_link_count":0,"owner_receipts":0,"owner_received_fixture":false,"datagram_receipts":0,"owner_datagram_received_fixture":false} ++ actual - expected + + { ++ cloexec: false, +- cloexec: true, + original_closed: true, ++ readable: false, ++ received: false, ++ same_inode: false, +- readable: true, +- received: true, +- same_inode: true, + sent: true, + token: true, + truncated: false, ++ written: false +- written: true + } + + at check (file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:130:10) + at file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:183:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: { + sent: true, + original_closed: true, + token: true, + truncated: false, + received: false, + same_inode: false, + readable: false, + written: false, + cloexec: false + }, + expected: { + sent: true, + original_closed: true, + token: true, + truncated: false, + received: true, + same_inode: true, + readable: true, + written: true, + cloexec: true + }, + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-missing-scope.log b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-missing-scope.log new file mode 100644 index 000000000..354ce903b --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-missing-scope.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: macOS datagram endpoint escaped scratch: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"private_datagram":[true,true,true],"datagram_symlink_created":true,"dgram_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_alias_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"AB","rights_link_count":0,"owner_receipts":2,"owner_received_fixture":true,"datagram_receipts":6,"owner_datagram_received_fixture":true} + +6 !== 0 + + at check (file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:137:10) + at file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:183:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 6, + expected: 0, + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-rights-path-reader.log b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-rights-path-reader.log new file mode 100644 index 000000000..9fcdd25d2 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-datagram-local/unix-rights-path-reader.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: received descriptor file effect: {"name":"unconfined","flags":{"read":true,"write":true,"shell":true,"unrestricted":true},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":true,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"private_datagram":[true,true,true],"datagram_symlink_created":true,"dgram_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_alias_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":true,"sent":true,"acknowledged":true},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"XX","rights_link_count":0,"owner_receipts":3,"owner_received_fixture":true,"datagram_receipts":6,"owner_datagram_received_fixture":true} + +'XX' !== 'AB' + + at check (file:///private/var/folders/zh/yw02jfzx4bdbc439_qtcg7740000gn/T/cyber-path-reader-s8922o2i/probe/macos_private_ipc.mts:134:10) + at file:///private/var/folders/zh/yw02jfzx4bdbc439_qtcg7740000gn/T/cyber-path-reader-s8922o2i/probe/macos_private_ipc.mts:183:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 'XX', + expected: 'AB', + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/matrix.json b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/matrix.json new file mode 100644 index 000000000..8a3872321 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/matrix.json @@ -0,0 +1,545 @@ +{ + "recorded_at": "2026-10-30T18:04:43.359Z", + "kernel_release": "24.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "dc8028c477b35faa33f4b99183bc2c6e2c8f54c81d58e0785e462eeecdd8e67f", + "platform": "darwin", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.54236f51-255f-4e60-98a2-0271d68d877f", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/private-unix-missing-grant.log b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/private-unix-missing-grant.log new file mode 100644 index 000000000..dcc00a681 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/private-unix-missing-grant.log @@ -0,0 +1,31 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: no-capabilities: private UNIX runtime exchange failed: [false,false] ++ actual - expected + + [ ++ false, ++ false +- true, +- true + ] + + at check (file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:298:12) + at file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:402:31 + at Array.map () + at main (file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:402:8) + at file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:425:1 + at ModuleJob.run (node:internal/modules/esm/module_job:343:25) + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:681:26) + at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: [ false, false ], + expected: [ true, true ], + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.23.4 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/source-binding.json b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/source-binding.json new file mode 100644 index 000000000..951ce47cf --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/source-binding.json @@ -0,0 +1,10 @@ +{ + "scope": "Independent checkout/source binding for prior revision; original reports retained unmodified. Does not verify later datagram changes.", + "run_id": "41103134892", + "job_id": 124224924428, + "tested_merge": "f40644b9e88fae0b8e1dfade009ffee2359a9495", + "source_head": "48a5481c531fcf64db38b62a73c7fb79f290b642", + "tree_equal": true, + "checkout_evidence": "Git SHA printed by actions/checkout in this job log", + "source_manifests_independently_verified": true +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-boundary.json b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-boundary.json new file mode 100644 index 000000000..1bf69ae1d --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-boundary.json @@ -0,0 +1,506 @@ +{ + "recorded_at": "2026-10-30T18:04:45.662Z", + "platform": "darwin", + "architecture": "arm64", + "kernel_release": "24.6.0", + "sources": [ + "macos_private_ipc.mts", + "macos_policy.mts", + "macos_rights.h", + "fixture_native.c", + "process_policy.h", + "macos_exec.c" + ], + "source_sha256": "76fa300cb4534e9d5e571d84b9560db6845eab015cefa10f02023721b4399c1c", + "target_sha256": "6ac184c24f8dbd9792820f3be74641c67a9ce682d71a9035beb7373236465097", + "rows": [ + { + "name": "unconfined", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": true, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "hardlink": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "symlink": { + "connected": true, + "sent": true, + "acknowledged": true + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 3, + "owner_received_fixture": true + }, + { + "name": "r0w0s0", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w0s1", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w1s0", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w1s1", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w0s0", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w0s1", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w1s0", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w1s1", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + } + ], + "scope": "Experimental pre-runtime native UNIX stream controls only; complete IPC/proxy/ownership and App acceptance remain required." +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-dropped-rights.log b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-dropped-rights.log new file mode 100644 index 000000000..205376af5 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-dropped-rights.log @@ -0,0 +1,56 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: private SCM_RIGHTS exchange failed: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":false,"same_inode":false,"readable":false,"written":false,"cloexec":false},"rights_path_replaced":true,"direct":{"connected":false,"sent":false,"acknowledged":false},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":false,"sent":false,"acknowledged":false}},"rights_payload":"A","rights_link_count":0,"owner_receipts":0,"owner_received_fixture":false} ++ actual - expected + + { ++ cloexec: false, +- cloexec: true, + original_closed: true, ++ readable: false, ++ received: false, ++ same_inode: false, +- readable: true, +- received: true, +- same_inode: true, + sent: true, + token: true, + truncated: false, ++ written: false +- written: true + } + + at check (file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:121:10) + at file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:154:5 + at process.processTicksAndRejections (node:internal/process/task_queues:103:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: { + sent: true, + original_closed: true, + token: true, + truncated: false, + received: false, + same_inode: false, + readable: false, + written: false, + cloexec: false + }, + expected: { + sent: true, + original_closed: true, + token: true, + truncated: false, + received: true, + same_inode: true, + readable: true, + written: true, + cloexec: true + }, + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.23.4 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-missing-scope.log b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-missing-scope.log new file mode 100644 index 000000000..095f2e989 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-missing-scope.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: macOS UNIX socket boundary escaped scratch: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"AB","rights_link_count":0,"owner_receipts":2,"owner_received_fixture":true} + +true !== false + + at check (file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:131:12) + at file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:154:5 + at process.processTicksAndRejections (node:internal/process/task_queues:103:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.23.4 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-rights-path-reader.log b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-rights-path-reader.log new file mode 100644 index 000000000..62fbced0d --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/arm64/unix-rights-path-reader.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: received descriptor file effect: {"name":"unconfined","flags":{"read":true,"write":true,"shell":true,"unrestricted":true},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":true,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":true,"sent":true,"acknowledged":true},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"XX","rights_link_count":0,"owner_receipts":3,"owner_received_fixture":true} + +'XX' !== 'AB' + + at check (file:///Users/runner/work/_temp/macos-rights-path-reader/macos_private_ipc.mts:125:10) + at file:///Users/runner/work/_temp/macos-rights-path-reader/macos_private_ipc.mts:154:5 + at process.processTicksAndRejections (node:internal/process/task_queues:103:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 'XX', + expected: 'AB', + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.23.4 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/check-summary.json b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/check-summary.json new file mode 100644 index 000000000..9e170c4c7 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/check-summary.json @@ -0,0 +1,402 @@ +{ + "source_head": "48a5481c531fcf64db38b62a73c7fb79f290b642", + "scope": "GitHub check run conclusions for this prior revision only; not complete goal acceptance.", + "checks": [ + { + "name": "Historical staged-system diagnostic (${{ matrix.os }})", + "status": "completed", + "conclusion": "skipped", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124227544577" + }, + { + "name": "Host bootstrap (windows-latest)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135129/job/124225893610" + }, + { + "name": "Host bootstrap (ubuntu-24.04)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135129/job/124225893525" + }, + { + "name": "Host bootstrap (macos-15)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135129/job/124225893464" + }, + { + "name": "Host bootstrap (macos-15-intel)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135129/job/124225893306" + }, + { + "name": "Host bootstrap (ubuntu-24.04-arm)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135129/job/124225892907" + }, + { + "name": "TypeScript SDK", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225594176" + }, + { + "name": "Build (x86_64-apple-darwin)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593797" + }, + { + "name": "Build (aarch64-unknown-linux-gnu)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593686" + }, + { + "name": "Rust (ubuntu-latest)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593631" + }, + { + "name": "Build (x86_64-pc-windows-msvc)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593585" + }, + { + "name": "Build (x86_64-unknown-linux-gnu)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593554" + }, + { + "name": "Build (aarch64-pc-windows-msvc)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593541" + }, + { + "name": "Build (aarch64-unknown-linux-musl)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593535" + }, + { + "name": "Build (x86_64-unknown-linux-musl)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593511" + }, + { + "name": "Build (aarch64-apple-darwin)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593510" + }, + { + "name": "Rust (macos-latest)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593374" + }, + { + "name": "Windows lint", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593370" + }, + { + "name": "Windows build", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593230" + }, + { + "name": "Web dashboard", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225593183" + }, + { + "name": "Changes", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225378977" + }, + { + "name": "OpenSpec", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134926/job/124225378757" + }, + { + "name": "Native proof (macos-15-intel, node)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925447" + }, + { + "name": "Native proof (ubuntu-24.04, node)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925426" + }, + { + "name": "Native proof (ubuntu-24.04, bun)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925394" + }, + { + "name": "Native proof (macos-15-intel, native)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925329" + }, + { + "name": "Native proof (macos-15, bun)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925324" + }, + { + "name": "Native proof (macos-15-intel, deno)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925269" + }, + { + "name": "Native proof (macos-15-intel, python)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925263" + }, + { + "name": "Native proof (macos-15-intel, bun)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925232" + }, + { + "name": "Native proof (ubuntu-24.04, python)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925222" + }, + { + "name": "Native proof (ubuntu-24.04, deno)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925206" + }, + { + "name": "Native proof (macos-15, node)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925198" + }, + { + "name": "Native proof (macos-15, native)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925196" + }, + { + "name": "Runtime signing-identity candidate (macos-15-intel, deno)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925157" + }, + { + "name": "Native proof (macos-15, python)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925148" + }, + { + "name": "Native proof (macos-15, deno)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925127" + }, + { + "name": "Runtime signing-identity candidate (macos-15, python-system)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925125" + }, + { + "name": "Runtime signing-identity candidate (macos-15-intel, python)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925039" + }, + { + "name": "Runtime signing-identity candidate (macos-15-intel, node)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925030" + }, + { + "name": "Runtime signing-identity candidate (macos-15, python)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224925002" + }, + { + "name": "Runtime signing-identity candidate (macos-15-intel, bun)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924987" + }, + { + "name": "Runtime signing-identity candidate (macos-15-intel, python-system)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924933" + }, + { + "name": "Runtime signing-identity candidate (macos-15, deno)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924722" + }, + { + "name": "Native proof (ubuntu-24.04-arm, node)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924719" + }, + { + "name": "Native proof (ubuntu-24.04-arm, native)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924659" + }, + { + "name": "Runtime signing-identity candidate (macos-15, node)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924607" + }, + { + "name": "Native proof (ubuntu-24.04-arm, deno)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924555" + }, + { + "name": "Native proof (ubuntu-24.04, native)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924530" + }, + { + "name": "Native proof (ubuntu-24.04-arm, bun)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924522" + }, + { + "name": "Native proof (ubuntu-24.04-arm, python)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924513" + }, + { + "name": "Runtime signing-identity candidate (macos-15, bun)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924510" + }, + { + "name": "Native signing-identity candidate (macos-15)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924428" + }, + { + "name": "Native signing-identity candidate (macos-15-intel)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134892/job/124224924194" + }, + { + "name": "Packaged entry (windows-latest)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135247/job/124224921965" + }, + { + "name": "Packaged entry (macos-15-intel)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135247/job/124224921547" + }, + { + "name": "Packaged entry (ubuntu-24.04)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135247/job/124224921374" + }, + { + "name": "Packaged entry (ubuntu-24.04-arm)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135247/job/124224921365" + }, + { + "name": "Package copy (macos-15)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135140/job/124224921097" + }, + { + "name": "Package copy (windows-latest)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135140/job/124224921094" + }, + { + "name": "Package copy (ubuntu-24.04-arm)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135140/job/124224921085" + }, + { + "name": "Package copy (macos-15-intel)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135140/job/124224921080" + }, + { + "name": "Packaged entry (macos-15)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135247/job/124224921011" + }, + { + "name": "Package copy (ubuntu-24.04)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103135140/job/124224920592" + }, + { + "name": "UNIX socket diagnostic (ubuntu-24.04-arm)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134910/job/124224920186" + }, + { + "name": "UNIX socket diagnostic (ubuntu-24.04)", + "status": "completed", + "conclusion": "success", + "html_url": "https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41103134910/job/124224919667" + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/matrix.json b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/matrix.json new file mode 100644 index 000000000..bb7953c01 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/matrix.json @@ -0,0 +1,545 @@ +{ + "recorded_at": "2026-10-30T18:01:23.677Z", + "kernel_release": "24.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "dc8028c477b35faa33f4b99183bc2c6e2c8f54c81d58e0785e462eeecdd8e67f", + "platform": "darwin", + "architecture": "x64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.e19b7d58-cebd-4099-9a7d-cdf710ab9354", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/private-unix-missing-grant.log b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/private-unix-missing-grant.log new file mode 100644 index 000000000..fa1873517 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/private-unix-missing-grant.log @@ -0,0 +1,31 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: no-capabilities: private UNIX runtime exchange failed: [false,false] ++ actual - expected + + [ ++ false, ++ false +- true, +- true + ] + + at check (file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:298:12) + at file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:402:31 + at Array.map () + at main (file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:402:8) + at file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:425:1 + at ModuleJob.run (node:internal/modules/esm/module_job:343:25) + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:681:26) + at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: [ false, false ], + expected: [ true, true ], + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.23.2 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/source-binding.json b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/source-binding.json new file mode 100644 index 000000000..b648dc9cb --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/source-binding.json @@ -0,0 +1,10 @@ +{ + "scope": "Independent checkout/source binding for prior revision; original reports retained unmodified. Does not verify later datagram changes.", + "run_id": "41103134892", + "job_id": 124224924194, + "tested_merge": "f40644b9e88fae0b8e1dfade009ffee2359a9495", + "source_head": "48a5481c531fcf64db38b62a73c7fb79f290b642", + "tree_equal": true, + "checkout_evidence": "Git SHA printed by actions/checkout in this job log", + "source_manifests_independently_verified": true +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-boundary.json b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-boundary.json new file mode 100644 index 000000000..77313bb77 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-boundary.json @@ -0,0 +1,506 @@ +{ + "recorded_at": "2026-10-30T18:01:27.086Z", + "platform": "darwin", + "architecture": "x64", + "kernel_release": "24.6.0", + "sources": [ + "macos_private_ipc.mts", + "macos_policy.mts", + "macos_rights.h", + "fixture_native.c", + "process_policy.h", + "macos_exec.c" + ], + "source_sha256": "76fa300cb4534e9d5e571d84b9560db6845eab015cefa10f02023721b4399c1c", + "target_sha256": "d91b46ab23fe98fddfec2462e8d292115acd2a45a457aa960f4eb03ac0c73646", + "rows": [ + { + "name": "unconfined", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": true, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "hardlink": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "symlink": { + "connected": true, + "sent": true, + "acknowledged": true + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 3, + "owner_received_fixture": true + }, + { + "name": "r0w0s0", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w0s1", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w1s0", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r0w1s1", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w0s0", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w0s1", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w1s0", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + }, + { + "name": "r1w1s1", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false + } + ], + "scope": "Experimental pre-runtime native UNIX stream controls only; complete IPC/proxy/ownership and App acceptance remain required." +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-dropped-rights.log b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-dropped-rights.log new file mode 100644 index 000000000..4e4193e3f --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-dropped-rights.log @@ -0,0 +1,56 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: private SCM_RIGHTS exchange failed: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":false,"same_inode":false,"readable":false,"written":false,"cloexec":false},"rights_path_replaced":true,"direct":{"connected":false,"sent":false,"acknowledged":false},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":false,"sent":false,"acknowledged":false}},"rights_payload":"A","rights_link_count":0,"owner_receipts":0,"owner_received_fixture":false} ++ actual - expected + + { ++ cloexec: false, +- cloexec: true, + original_closed: true, ++ readable: false, ++ received: false, ++ same_inode: false, +- readable: true, +- received: true, +- same_inode: true, + sent: true, + token: true, + truncated: false, ++ written: false +- written: true + } + + at check (file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:121:10) + at file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:154:5 + at process.processTicksAndRejections (node:internal/process/task_queues:103:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: { + sent: true, + original_closed: true, + token: true, + truncated: false, + received: false, + same_inode: false, + readable: false, + written: false, + cloexec: false + }, + expected: { + sent: true, + original_closed: true, + token: true, + truncated: false, + received: true, + same_inode: true, + readable: true, + written: true, + cloexec: true + }, + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.23.2 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-missing-scope.log b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-missing-scope.log new file mode 100644 index 000000000..b39010a3c --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-missing-scope.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: macOS UNIX socket boundary escaped scratch: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"AB","rights_link_count":0,"owner_receipts":2,"owner_received_fixture":true} + +true !== false + + at check (file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:131:12) + at file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:154:5 + at process.processTicksAndRejections (node:internal/process/task_queues:103:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.23.2 diff --git a/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-rights-path-reader.log b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-rights-path-reader.log new file mode 100644 index 000000000..df1dc2075 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-private-rights-48a5481c/x64/unix-rights-path-reader.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: received descriptor file effect: {"name":"unconfined","flags":{"read":true,"write":true,"shell":true,"unrestricted":true},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":true,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":true,"sent":true,"acknowledged":true},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"XX","rights_link_count":0,"owner_receipts":3,"owner_received_fixture":true} + +'XX' !== 'AB' + + at check (file:///Users/runner/work/_temp/macos-rights-path-reader/macos_private_ipc.mts:125:10) + at file:///Users/runner/work/_temp/macos-rights-path-reader/macos_private_ipc.mts:154:5 + at process.processTicksAndRejections (node:internal/process/task_queues:103:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 'XX', + expected: 'AB', + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.23.2 diff --git a/scripts/probes/plugin-confinement/fixture_native.c b/scripts/probes/plugin-confinement/fixture_native.c index 9eea90805..2e99e1e92 100644 --- a/scripts/probes/plugin-confinement/fixture_native.c +++ b/scripts/probes/plugin-confinement/fixture_native.c @@ -179,7 +179,9 @@ static void print_unix_attempt(const char *name, struct unix_attempt result) { truth(result.connected), truth(result.sent), truth(result.acknowledged)); } -static int unix_boundary(const char *scratch, const char *host) { +#include "macos_datagram.h" + +static int unix_boundary(const char *scratch, const char *host, const char *datagram_host) { if (strlen(scratch) >= PATH_MAX || strlen(host) >= PATH_MAX) return 2; int ipc[2] = {0}; if (!private_stream_probe(scratch, ipc)) return 2; @@ -190,6 +192,7 @@ static int unix_boundary(const char *scratch, const char *host) { const char *drop = getenv("CYBER_PROOF_DROP_RIGHTS"); struct rights_result rights = private_rights(scratch, drop != NULL && strcmp(drop, "1") == 0); int rights_path_replaced = replace_rights_path(scratch); + struct datagram_result datagram = datagram_probe(scratch, datagram_host); struct unix_attempt direct = host_unix_attempt(host); char alias[PATH_MAX], symbolic[PATH_MAX]; if (!joined(alias, scratch, "host-alias.sock") || !joined(symbolic, scratch, "host-symlink.sock")) return 2; @@ -203,6 +206,7 @@ static int unix_boundary(const char *scratch, const char *host) { printf(",\"private_aliases\":[%s,%s]", truth(own_hardlink), truth(own_symlink)); print_rights(rights); printf(",\"rights_path_replaced\":%s", truth(rights_path_replaced)); + print_datagram(datagram); print_unix_attempt("direct", direct); print_unix_attempt("hardlink", hardlink); print_unix_attempt("symlink", symlink_result); @@ -299,7 +303,7 @@ static int parent_directory(const char *path, char *out) { int main(int argc, char **argv) { #ifdef __APPLE__ - if (argc == 4 && strcmp(argv[1], "unix-boundary") == 0) return unix_boundary(argv[2], argv[3]); + if (argc == 5 && strcmp(argv[1], "unix-boundary") == 0) return unix_boundary(argv[2], argv[3], argv[4]); #endif if (argc == 2 && strcmp(argv[1], "receipt") == 0) { puts("{\"self_exec\":true}"); diff --git a/scripts/probes/plugin-confinement/macos_datagram.h b/scripts/probes/plugin-confinement/macos_datagram.h new file mode 100644 index 000000000..60b8e6d37 --- /dev/null +++ b/scripts/probes/plugin-confinement/macos_datagram.h @@ -0,0 +1,95 @@ +/* Fixed native datagram exchanges; requires the enclosing fixture's helpers. */ +#ifndef CYBER_MACOS_DATAGRAM_H +#define CYBER_MACOS_DATAGRAM_H +#include + +static int datagram_address(const char *path, struct sockaddr_un *address) { + if (strlen(path) >= sizeof(address->sun_path)) return 0; + memset(address, 0, sizeof(*address)); + address->sun_family = AF_UNIX; + strcpy(address->sun_path, path); + return 1; +} + +static int datagram_socket(const char *path) { + struct sockaddr_un address; + if (!datagram_address(path, &address)) return -1; + int fd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (fd < 0) return -1; + struct timeval timeout = { .tv_sec = 2 }; + if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) != 0 || + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) != 0 || + bind(fd, (struct sockaddr *)&address, sizeof(address)) != 0) { close(fd); return -1; } + return fd; +} + +static struct unix_attempt datagram_send(int fd, const char *path, int method) { + struct unix_attempt result = {0}; + struct sockaddr_un address; + if (!datagram_address(path, &address)) return result; + if (method == 0) { + result.connected = connect(fd, (struct sockaddr *)&address, sizeof(address)) == 0; + result.sent = result.connected && send(fd, "fixture-only", 12, 0) == 12; + } else if (method == 1) { + result.sent = sendto(fd, "fixture-only", 12, 0, (struct sockaddr *)&address, sizeof(address)) == 12; + } else { + struct iovec body = { .iov_base = (void *)"fixture-only", .iov_len = 12 }; + struct msghdr message = { .msg_name = &address, .msg_namelen = sizeof(address), .msg_iov = &body, .msg_iovlen = 1 }; + result.sent = sendmsg(fd, &message, 0) == 12; + } + return result; +} + +static int private_datagram(const char *scratch, int method) { + char server_path[PATH_MAX], client_path[PATH_MAX]; + if (!joined(server_path, scratch, "dgram-private.sock") || !joined(client_path, scratch, "dgram-client.sock")) return 0; + int server = datagram_socket(server_path), client = datagram_socket(client_path), ok = 0; + if (server < 0 || client < 0) goto done; + struct unix_attempt sent = datagram_send(client, server_path, method); + char token[12], ack = 0; + struct sockaddr_un reply; + ok = sent.sent && recv(server, token, sizeof(token), 0) == 12 && memcmp(token, "fixture-only", 12) == 0 && + datagram_address(client_path, &reply) && sendto(server, "A", 1, 0, (struct sockaddr *)&reply, sizeof(reply)) == 1 && + recv(client, &ack, 1, 0) == 1 && ack == 'A'; +done: + if (server >= 0) close(server); + if (client >= 0) close(client); + unlink(server_path); unlink(client_path); + return ok; +} + +static struct unix_attempt host_datagram(const char *scratch, const char *host, int method) { + struct unix_attempt result = {0}; + char client_path[PATH_MAX]; + if (!joined(client_path, scratch, "dgram-client.sock")) return result; + int client = datagram_socket(client_path); + if (client < 0) return result; + result = datagram_send(client, host, method); + char ack = 0; + result.acknowledged = result.sent && recv(client, &ack, 1, 0) == 1 && ack == 'A'; + close(client); unlink(client_path); + return result; +} + +struct datagram_result { int private[3], symlink_created; struct unix_attempt host[6]; }; +static struct datagram_result datagram_probe(const char *scratch, const char *host) { + struct datagram_result result = {0}; + char alias[PATH_MAX]; + if (!joined(alias, scratch, "dgram-host-link.sock")) return result; + result.symlink_created = symlink(host, alias) == 0; + for (int method = 0; method < 3; ++method) { + result.private[method] = private_datagram(scratch, method); + result.host[method] = host_datagram(scratch, host, method); + if (result.symlink_created) result.host[method + 3] = host_datagram(scratch, alias, method); + } + unlink(alias); + return result; +} + +static void print_datagram(struct datagram_result result) { + printf(",\"private_datagram\":[%s,%s,%s],\"datagram_symlink_created\":%s", + truth(result.private[0]), truth(result.private[1]), truth(result.private[2]), truth(result.symlink_created)); + const char *names[6] = { "dgram_connect", "dgram_sendto", "dgram_sendmsg", "dgram_alias_connect", "dgram_alias_sendto", "dgram_alias_sendmsg" }; + for (int index = 0; index < 6; ++index) print_unix_attempt(names[index], result.host[index]); +} +#endif diff --git a/scripts/probes/plugin-confinement/macos_datagram_owner.c b/scripts/probes/plugin-confinement/macos_datagram_owner.c new file mode 100644 index 000000000..7c99c1523 --- /dev/null +++ b/scripts/probes/plugin-confinement/macos_datagram_owner.c @@ -0,0 +1,63 @@ +/* Trusted diagnostic owner for one fixture socket and one exact client path. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int drain(int server, const char *client, int *receipts) { + for (;;) { + struct sockaddr_un peer = {0}; + socklen_t length = sizeof(peer); + char bytes[13]; + ssize_t size = recvfrom(server, bytes, sizeof(bytes), 0, (struct sockaddr *)&peer, &length); + if (size < 0 && errno == EINTR) continue; + if (size < 0) return errno == EAGAIN || errno == EWOULDBLOCK ? 0 : -1; + if (size != 12 || memcmp(bytes, "fixture-only", 12) != 0 || + length <= offsetof(struct sockaddr_un, sun_path) || length > sizeof(peer) || + peer.sun_family != AF_UNIX || + memchr(peer.sun_path, 0, length - offsetof(struct sockaddr_un, sun_path)) == NULL || + strcmp(peer.sun_path, client) != 0 || ++*receipts > 32) return -1; + if (sendto(server, "A", 1, 0, (struct sockaddr *)&peer, length) != 1) return -1; + } +} + +int main(int argc, char **argv) { + struct sockaddr_un address = { .sun_family = AF_UNIX }; + if (argc != 3 || strlen(argv[1]) >= sizeof(address.sun_path) || + strlen(argv[2]) >= sizeof(address.sun_path)) return 2; + strcpy(address.sun_path, argv[1]); + int server = socket(AF_UNIX, SOCK_DGRAM, 0); + if (server < 0) return 2; + int flags = fcntl(server, F_GETFL); + if (flags < 0 || fcntl(server, F_SETFL, flags | O_NONBLOCK) != 0 || + bind(server, (struct sockaddr *)&address, sizeof(address)) != 0) { close(server); return 2; } + struct timespec started, now; + if (clock_gettime(CLOCK_MONOTONIC, &started) != 0) { close(server); unlink(argv[1]); return 2; } + puts("READY"); + fflush(stdout); + int receipts = 0, result = 2; + for (;;) { + if (clock_gettime(CLOCK_MONOTONIC, &now) != 0 || now.tv_sec - started.tv_sec >= 30) break; + struct pollfd descriptors[2] = { { .fd = server, .events = POLLIN }, { .fd = 0, .events = POLLIN } }; + int ready = poll(descriptors, 2, 100); + if (ready < 0 && errno == EINTR) continue; + if (ready < 0 || descriptors[0].revents & (POLLERR | POLLHUP | POLLNVAL)) break; + if (descriptors[0].revents & POLLIN && drain(server, argv[2], &receipts) != 0) break; + if (descriptors[1].revents & (POLLIN | POLLHUP | POLLERR | POLLNVAL)) { + char stop = 0; + if (read(0, &stop, 1) != 1 || stop != 'S' || drain(server, argv[2], &receipts) != 0) break; + printf("{\"stopped\":true,\"receipts\":%d}\n", receipts); + result = 0; + break; + } + } + close(server); + unlink(argv[1]); + return result; +} diff --git a/scripts/probes/plugin-confinement/macos_datagram_owner.mts b/scripts/probes/plugin-confinement/macos_datagram_owner.mts new file mode 100644 index 000000000..1460b0169 --- /dev/null +++ b/scripts/probes/plugin-confinement/macos_datagram_owner.mts @@ -0,0 +1,57 @@ +/** Bounded native receiver ownership for fixture-only UNIX datagrams. */ +import assert from "node:assert/strict"; +import { spawn } from "node:child_process"; +import { dirname } from "node:path"; + +export async function datagramOwner(program: string, path: string, client: string) { + const child = spawn(program, [path, client], { + cwd: dirname(path), env: { PATH: "/usr/bin:/bin:/usr/sbin:/sbin" }, stdio: ["pipe", "pipe", "pipe"], + }); + let stdout = "", stderr = "", failed: Error | undefined, ready = false; + let admit!: () => void, refuse!: (error: Error) => void; + const started = new Promise((resolve, reject) => { admit = resolve; refuse = reject; }); + const deadline = setTimeout(() => { + failed = new Error("owned datagram receiver timed out"); + child.kill("SIGKILL"); + }, 32_000); + const completed = new Promise<{ code: number | null; signal: string | null }>(resolve => { + child.on("error", error => { failed = error; }); + child.once("close", (code, signal) => { + clearTimeout(deadline); + if (!ready) refuse(failed ?? new Error(`datagram receiver closed before ready: ${code}: ${stderr}`)); + resolve({ code, signal }); + }); + }); + child.stdin.on("error", error => { failed = error; }); + child.stdout.on("data", (bytes: Buffer) => { + if (stdout.length + bytes.length > 4096) { + failed = new Error("owned datagram output exceeds bound"); child.kill("SIGKILL"); return; + } + stdout += bytes.toString(); + if (!ready && stdout.startsWith("READY\n")) { ready = true; admit(); } + }); + child.stderr.on("data", (bytes: Buffer) => { + if (stderr.length + bytes.length > 4096) { + failed = new Error("owned datagram error output exceeds bound"); child.kill("SIGKILL"); return; + } + stderr += bytes.toString(); + }); + try { await started; } + catch (error) { child.kill("SIGKILL"); await completed; throw error; } + let stopping: Promise | undefined; + return { + stop: () => stopping ??= (async () => { + if (child.exitCode === null && child.signalCode === null) child.stdin.end("S"); + const outcome = await completed; + if (failed) throw failed; + assert.equal(outcome.code, 0, JSON.stringify({ ...outcome, stderr })); + const lines = stdout.trim().split("\n"); + assert.equal(lines.length, 2, "unexpected datagram owner transcript"); + assert.equal(lines[0], "READY"); + const report = JSON.parse(lines[1]); + assert.equal(report.stopped, true); + assert(Number.isSafeInteger(report.receipts) && report.receipts >= 0 && report.receipts <= 32); + return report.receipts as number; + })(), + }; +} diff --git a/scripts/probes/plugin-confinement/macos_private_ipc.mts b/scripts/probes/plugin-confinement/macos_private_ipc.mts index c7086d4bf..72bba51c8 100644 --- a/scripts/probes/plugin-confinement/macos_private_ipc.mts +++ b/scripts/probes/plugin-confinement/macos_private_ipc.mts @@ -9,6 +9,7 @@ import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; import { parseArgs, promisify } from "node:util"; import { policy } from "./macos_policy.mts"; +import { datagramOwner } from "./macos_datagram_owner.mts"; const source = dirname(fileURLToPath(import.meta.url)); const environment = { PATH: "/usr/bin:/bin:/usr/sbin:/sbin" }; @@ -24,14 +25,14 @@ function success(program: string, args: string[]) { function prepare(root: string) { const packagePath = join(root, "package"); mkdirSync(packagePath, { mode: 0o700 }); - const target = join(packagePath, "guest"), helper = join(root, "helper"); - for (const [file, output] of [["fixture_native.c", target], ["macos_exec.c", helper]]) { + const target = join(packagePath, "guest"), helper = join(root, "helper"), datagram = join(root, "datagram-owner"); + for (const [file, output] of [["fixture_native.c", target], ["macos_exec.c", helper], ["macos_datagram_owner.c", datagram]]) { success("/usr/bin/xcrun", ["clang", "-Wall", "-Wextra", "-Werror", "-Wno-error=deprecated-declarations", "-pthread", join(source, file), "-o", output]); } const identifier = `com.cyberdyne.probe.unix.helper.${randomUUID()}`; success("/usr/bin/codesign", ["--force", "--sign", "-", "--identifier", identifier, "--timestamp=none", helper]); success("/usr/bin/codesign", ["--verify", "--strict", "--all-architectures", helper]); - return { target, helper, identifier, packagePath }; + return { target, helper, identifier, packagePath, datagram }; } async function owner(path: string) { @@ -79,7 +80,10 @@ async function row(root: string, prepared: ReturnType, name: str const host = join(paths.project, "host.sock"); const listener = await owner(host); let payload = -1; + let datagram: Awaited> | undefined; try { + const datagramHost = join(paths.project, "dgram-host.sock"); + datagram = await datagramOwner(prepared.datagram, datagramHost, join(paths.scratch, "dgram-client.sock")); payload = openSync(join(paths.scratch, "rights.bin"), constants.O_RDWR | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW, 0o600); let profile = policy({ kind: "native", executable: prepared.target, libdir: "/usr/lib" }, paths, flags, false, prepared.identifier, true); if (missingScope) { @@ -89,12 +93,13 @@ async function row(root: string, prepared: ReturnType, name: str } const file = join(root, `policy-${name}.sb`); writeFileSync(file, profile, { mode: 0o600 }); - const result = await execute(prepared.helper, [flags.unrestricted ? "-" : file, prepared.target, "unix-boundary", paths.scratch, host], { + const result = await execute(prepared.helper, [flags.unrestricted ? "-" : file, prepared.target, "unix-boundary", paths.scratch, host, datagramHost], { cwd: paths.scratch, env: { ...environment, ...dropRights && !flags.unrestricted ? { CYBER_PROOF_DROP_RIGHTS: "1" } : {} }, encoding: "utf8", timeout: 15_000, maxBuffer: 65536, }); const observed = JSON.parse(result.stdout); const receipt = listener.receipt(); + const datagram_receipts = await datagram.stop(); assert(!receipt.invalid, "invalid owned-listener protocol"); const identity = fstatSync(payload); assert(identity.isFile() && identity.size <= 2, "invalid owned rights payload"); @@ -103,10 +108,14 @@ async function row(root: string, prepared: ReturnType, name: str assert(count <= 2, "oversized owned rights payload"); const rights_payload = contents.subarray(0, count).toString(); return { name, flags, observed, rights_payload, rights_link_count: identity.nlink, - owner_receipts: receipt.count, owner_received_fixture: receipt.count > 0 }; + owner_receipts: receipt.count, owner_received_fixture: receipt.count > 0, + datagram_receipts, owner_datagram_received_fixture: datagram_receipts > 0 }; } finally { - try { await listener.close(); } - finally { if (payload >= 0) closeSync(payload); } + try { if (datagram) await datagram.stop(); } + finally { + try { await listener.close(); } + finally { if (payload >= 0) closeSync(payload); } + } } } @@ -123,6 +132,16 @@ function check(entry: Awaited>) { same_inode: true, readable: true, written: true, cloexec: true, }, `private SCM_RIGHTS exchange failed: ${JSON.stringify(entry)}`); assert.equal(entry.rights_payload, "AB", `received descriptor file effect: ${JSON.stringify(entry)}`); + assert.deepEqual(entry.observed.private_datagram, [true, true, true], `private datagram exchange: ${JSON.stringify(entry)}`); + assert.equal(entry.observed.datagram_symlink_created, true); + assert.equal(entry.datagram_receipts, entry.flags.unrestricted ? 6 : 0, + `macOS datagram endpoint escaped scratch: ${JSON.stringify(entry)}`); + for (const prefix of ["dgram_", "dgram_alias_"]) for (const method of ["connect", "sendto", "sendmsg"]) { + assert.deepEqual(entry.observed[prefix + method], { + connected: !!entry.flags.unrestricted && method === "connect", + sent: !!entry.flags.unrestricted, acknowledged: !!entry.flags.unrestricted, + }, `host datagram route: ${prefix}${method}: ${JSON.stringify(entry)}`); + } if (entry.flags.unrestricted) { assert.equal(entry.observed.hardlink_created, true); assert.equal(entry.observed.symlink_created, true); @@ -137,12 +156,22 @@ function check(entry: Awaited>) { } } +async function startupControls(root: string, program: string) { + const client = join(root, "startup-client.sock"); + await assert.rejects(datagramOwner(join(root, "missing-owner"), join(root, "missing.sock"), client), { code: "ENOENT" }); + const occupied = join(root, "occupied.sock"); + writeFileSync(occupied, "owned fixture", { mode: 0o600 }); + await assert.rejects(datagramOwner(program, occupied, client), /closed before ready: 2/); + assert.equal(readFileSync(occupied, "utf8"), "owned fixture", "failed bind changed an existing owned file"); +} + assert.equal(process.platform, "darwin", "macOS native UNIX boundary proof requires Darwin"); const { values } = parseArgs({ options: { report: { type: "string" }, "missing-scope": { type: "boolean", default: false }, "drop-rights": { type: "boolean", default: false } } }); assert(!(values["missing-scope"] && values["drop-rights"]), "select one precise control"); const root = realpathSync(mkdtempSync("/tmp/cyber-unix-")); try { const prepared = prepare(root); + await startupControls(root, prepared.datagram); const targetHash = createHash("sha256").update(readFileSync(prepared.target)).digest("hex"); const rows = []; const cases: Array<[string, Flags]> = [["unconfined", { read: true, write: true, shell: true, unrestricted: true }]]; @@ -155,12 +184,13 @@ try { rows.push(observed); } assert.equal(createHash("sha256").update(readFileSync(prepared.target)).digest("hex"), targetHash); - const sources = ["macos_private_ipc.mts", "macos_policy.mts", "macos_rights.h", "fixture_native.c", "process_policy.h", "macos_exec.c"]; + const sources = ["macos_private_ipc.mts", "macos_policy.mts", "macos_rights.h", "macos_datagram.h", "macos_datagram_owner.mts", "macos_datagram_owner.c", "fixture_native.c", "process_policy.h", "macos_exec.c"]; const hash = createHash("sha256"); for (const file of sources) hash.update(file + "\0").update(readFileSync(join(source, file))); const report = { recorded_at: new Date().toISOString(), platform: process.platform, architecture: process.arch, - kernel_release: release(), sources, source_sha256: hash.digest("hex"), target_sha256: targetHash, rows, - scope: "Experimental pre-runtime native UNIX stream controls only; complete IPC/proxy/ownership and App acceptance remain required." }; + kernel_release: release(), sources, source_sha256: hash.digest("hex"), target_sha256: targetHash, + receiver_startup_controls: { missing_program_refused: true, failed_bind_refused: true }, rows, + scope: "Experimental pre-runtime native UNIX stream/datagram/descriptor controls; complete IPC/proxy/ownership and App acceptance remain required." }; if (values.report) writeFileSync(values.report, JSON.stringify(report, null, 2) + "\n", { mode: 0o600 }); console.log(JSON.stringify(report, null, 2)); } finally { diff --git a/scripts/probes/plugin-confinement/run.mts b/scripts/probes/plugin-confinement/run.mts index 9f7e6dd4e..80632c366 100644 --- a/scripts/probes/plugin-confinement/run.mts +++ b/scripts/probes/plugin-confinement/run.mts @@ -401,7 +401,7 @@ function main() { const rows = cases.filter(([name]) => !unsupported_cases.some(item => item.name === name)) .map(([name, flags]) => check(root, artifacts, runtime, name, flags)); const digest = createHash("sha256"); - const sources = ["run.mts", "macos_policy.mts", "macos_rights.h", "macos_python.c", "macos_node.c", "native_exec.c", "node_bootstrap.cjs", "fixture.py", "fixture.cjs", "private_unix.cjs", "process_policy.h", "linux_filter.h", "linux_exec.c", "linux_initial_exec.h", "fixture_native.c", "macos_exec.c", "macos_stage.mts"]; + const sources = ["run.mts", "macos_policy.mts", "macos_rights.h", "macos_datagram.h", "macos_python.c", "macos_node.c", "native_exec.c", "node_bootstrap.cjs", "fixture.py", "fixture.cjs", "private_unix.cjs", "process_policy.h", "linux_filter.h", "linux_exec.c", "linux_initial_exec.h", "fixture_native.c", "macos_exec.c", "macos_stage.mts"]; for (const file of sources) { digest.update(file + "\0").update(readFileSync(join(source, file))); } From 08ee6fe6eb932a3926470f3c113257b97aa26b2d Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 16:00:36 -0400 Subject: [PATCH 17/21] test(plugins): cover concurrent datagram alias replacement --- .../workflows/plugin-confinement-proof.yml | 9 +- .../macos-datagram-alias-race.md | 56 + .../macos-private-datagrams.md | 3 + scripts/probes/plugin-confinement/README.md | 3 + .../packaged-native.json | 553 ++++++++++ .../runtime-native.json | 547 ++++++++++ .../runtime-node.json | 466 +++++++++ .../unix-boundary.json | 955 ++++++++++++++++++ .../unix-dropped-rights.log | 56 + .../unix-missing-scope.log | 20 + .../unix-rights-path-reader.log | 20 + .../plugin-confinement/macos_datagram.h | 6 +- .../plugin-confinement/macos_datagram_race.h | 109 ++ .../plugin-confinement/macos_private_ipc.mts | 13 +- scripts/probes/plugin-confinement/run.mts | 2 +- 15 files changed, 2813 insertions(+), 5 deletions(-) create mode 100644 openspec/changes/complete-plugin-hook-runtime/macos-datagram-alias-race.md create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/packaged-native.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/runtime-native.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/runtime-node.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-boundary.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-dropped-rights.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-missing-scope.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-rights-path-reader.log create mode 100644 scripts/probes/plugin-confinement/macos_datagram_race.h diff --git a/.github/workflows/plugin-confinement-proof.yml b/.github/workflows/plugin-confinement-proof.yml index a21ecf532..ef6a7d5d0 100644 --- a/.github/workflows/plugin-confinement-proof.yml +++ b/.github/workflows/plugin-confinement-proof.yml @@ -190,8 +190,15 @@ jobs: import sys text = Path(sys.argv[1]).read_text() assert 'macOS datagram endpoint escaped scratch:' in text, text + import json, re + match = re.search(r'macOS datagram endpoint escaped scratch: (\{[^\n]+\})', text) + assert match, text + entry = json.loads(match[1]) + race = entry['observed']['datagram_race'] + assert race['host_control'] and race['settled'] and not race['failed'], entry + assert entry['datagram_receipts'] == 7 + race['host_acks'], entry for token in ['"owner_received_fixture":true', '"acknowledged":true', - '"owner_datagram_received_fixture":true', '"datagram_receipts":6', + '"owner_datagram_received_fixture":true', '"private_datagram":[true,true,true]', '"private_aliases":[true,true]', '"private_peer_matches":true']: assert token in text, text PYCONTROL diff --git a/openspec/changes/complete-plugin-hook-runtime/macos-datagram-alias-race.md b/openspec/changes/complete-plugin-hook-runtime/macos-datagram-alias-race.md new file mode 100644 index 000000000..5e7c98793 --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/macos-datagram-alias-race.md @@ -0,0 +1,56 @@ +# macOS concurrent datagram alias replacement + +This extends the approved native proof with concurrent pathname mutation; it does +not activate production launch or resolve the pending Linux direction decision. + +The native fixture binds a private scratch datagram server and creates a scratch +symlink to it. A positive exchange through that alias must complete before the +race starts. A second native thread atomically replaces the alias between the +private endpoint and the existing owned host endpoint. It creates a temporary +symlink and renames it over the alias; it never changes either target socket. + +The sender alternates destination-bearing `sendto` and `sendmsg` for sixteen +attempts. Each attempt waits for a newly published successful replacement while +the mutator continues running. Private delivery receives a distinct `P` +acknowledgement from the actual private receiver; actual host delivery receives +`A` from the independent native owner. Only EACCES/EPERM qualifies as a policy +refusal. Missing acknowledgement, invalid payload, other syscall errors, absent +mutation progress or failed thread settlement fail the test. + +Mutation is bounded to 4096 successful swaps, uses atomics and monotonic wait +limits, and is stopped and joined before any stack/path resources are released. +A join failure terminates the fixture rather than releasing resources under a +possibly live thread. After settlement, a fixed host-target alias exchange +requires delivery when unconfined and refusal when confined. This gives both +positive endpoint controls independently of scheduling during the race. + +The owner records all host packets. The unconfined total must equal six original +routes, one fixed host control and the race's acknowledged host packets. All +eight confined cases require zero actual host receipts and no host race +acknowledgements, while retaining every existing private stream, descriptor and +datagram check. The widened-scope control must expose actual stream and datagram +host delivery and fail the named datagram isolation assertion. It validates the +receipt total against the observed race acknowledgements rather than assuming a +fixed race schedule. + +## Local evidence + +On arm64/Darwin 25.6.0, all nine IPC cases pass. The retained unconfined run has +eight private and eight host acknowledgements during sixteen race sends, with +fifteen actual host packets including the fixed controls. Each confined case has +eight private acknowledgements, eight policy refusals and zero host receipts. +These counts describe this run; tests do not require a particular race schedule. + +Native fixture, native packaged-helper and Node fixture runtime regressions each +pass nine rows, with no unsupported rows. Widened-scope, dropped-rights and +path-reader counterexamples fail their exact assertions. Original reports and +logs are in `scripts/probes/plugin-confinement/evidence/macos-datagram-race-local`. +Independently recomputed source hashes are: + +- IPC: `7eae036bc0756198bd522e570f6e2c7a357efab0f0eb543b7ced11d4e4f88cce`. +- Runtime: `05c2c5808004a944c2582857a16df3f4a2266abbe5911d68886c36aeebd3b5ad`. + +Hosted verification is pending. This tests one concurrently replaced symlink +with destination-bearing sends. It does not establish every pathname/FD/address +mutation, seqpacket or ancillary credential behavior, proxy/network/secret +ceilings, descendant settlement or App integration. Parent acceptance stays open. diff --git a/openspec/changes/complete-plugin-hook-runtime/macos-private-datagrams.md b/openspec/changes/complete-plugin-hook-runtime/macos-private-datagrams.md index 79e40412c..ff3bf1ca2 100644 --- a/openspec/changes/complete-plugin-hook-runtime/macos-private-datagrams.md +++ b/openspec/changes/complete-plugin-hook-runtime/macos-private-datagrams.md @@ -55,3 +55,6 @@ These fixed pathname exchanges do not prove concurrent endpoint mutation, seqpacket compatibility, ancillary credentials, every descriptor operation, proxy/network/secret ceilings, complete descendant resource settlement or actual App/server integration. Those acceptance requirements remain open. + +The subsequent [concurrent alias replacement](macos-datagram-alias-race.md) +extends this fixed-route revision with separately retained race evidence. diff --git a/scripts/probes/plugin-confinement/README.md b/scripts/probes/plugin-confinement/README.md index e6e020ab1..d500edfd1 100644 --- a/scripts/probes/plugin-confinement/README.md +++ b/scripts/probes/plugin-confinement/README.md @@ -100,6 +100,9 @@ It also requires private connected/sendto/sendmsg datagram exchanges and denies six direct/symlink host routes. A bounded native owner records actual receipt after guest settlement; startup failure cannot count as zero delivery. See [datagram evidence and limits](../../../openspec/changes/complete-plugin-hook-runtime/macos-private-datagrams.md). +The [concurrent alias test](../../../openspec/changes/complete-plugin-hook-runtime/macos-datagram-alias-race.md) +replaces a scratch symlink while native sendto/sendmsg run and compares actual +private acknowledgements, policy refusals and owner-recorded host packets. ## Boundary and coverage diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/packaged-native.json b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/packaged-native.json new file mode 100644 index 000000000..febc868bb --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/packaged-native.json @@ -0,0 +1,553 @@ +{ + "recorded_at": "2026-10-30T19:10:09.254Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_datagram.h", + "macos_datagram_race.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "05c2c5808004a944c2582857a16df3f4a2266abbe5911d68886c36aeebd3b5ad", + "platform": "darwin", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.741cb45b-0884-4315-8532-9e6acac74af3", + "packaged_helper": { + "input_sha256": "64ee74d21d1ddc470989450014f1e89fa33ab5aec230cd998890df3ec5717225", + "executed_sha256": "c557db69dc13df99ed38380594564b74192411e9d08a7980700afbd9fd08147b", + "private_copy": true, + "direct_runtime": true + }, + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "packaged entry with experimental policy composition; production admission, protected ownership, network/secret integration and Windows acceptance remain required", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": true, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/runtime-native.json b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/runtime-native.json new file mode 100644 index 000000000..4d3f907e7 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/runtime-native.json @@ -0,0 +1,547 @@ +{ + "recorded_at": "2026-10-30T19:10:09.957Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_datagram.h", + "macos_datagram_race.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "05c2c5808004a944c2582857a16df3f4a2266abbe5911d68886c36aeebd3b5ad", + "platform": "darwin", + "architecture": "arm64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.003805d2-3609-4eed-9fee-9839c0b6df4f", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/runtime-node.json b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/runtime-node.json new file mode 100644 index 000000000..c7fb85131 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/runtime-node.json @@ -0,0 +1,466 @@ +{ + "recorded_at": "2026-10-30T19:10:14.601Z", + "kernel_release": "25.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_datagram.h", + "macos_datagram_race.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "05c2c5808004a944c2582857a16df3f4a2266abbe5911d68886c36aeebd3b5ad", + "platform": "darwin", + "architecture": "arm64", + "runtime": "node", + "version": "22.20.0", + "signing_identifier": "com.cyberdyne.probe.bootstrap.699626cc-af23-4696-a537-b64aa879ac7a", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "hardlink_private": true, + "cannot_relax": null, + "private_read": true, + "symlink_private_read": true, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "written_project_read": true, + "project_rename": true, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": false, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "written_project_read": false, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "startup_artifacts": false, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "hardlink_private": false, + "cannot_relax": true, + "private_read": false, + "symlink_private_read": false, + "project_write": true, + "inherited_descriptor": false, + "thread": true, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "written_project_read": true, + "project_rename": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-boundary.json b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-boundary.json new file mode 100644 index 000000000..44c796c31 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-boundary.json @@ -0,0 +1,955 @@ +{ + "recorded_at": "2026-10-30T19:09:27.379Z", + "platform": "darwin", + "architecture": "arm64", + "kernel_release": "25.6.0", + "sources": [ + "macos_private_ipc.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_datagram.h", + "macos_datagram_race.h", + "macos_datagram_owner.mts", + "macos_datagram_owner.c", + "fixture_native.c", + "process_policy.h", + "macos_exec.c" + ], + "source_sha256": "7eae036bc0756198bd522e570f6e2c7a357efab0f0eb543b7ced11d4e4f88cce", + "target_sha256": "0191b0aa41e4a6a571520d2f175655be847f648055c5cb022107e1db3233e639", + "receiver_startup_controls": { + "missing_program_refused": true, + "failed_bind_refused": true + }, + "rows": [ + { + "name": "unconfined", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": true, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": true, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 8, + "refused": 0, + "swaps": 17 + }, + "dgram_connect": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "dgram_sendto": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "dgram_sendmsg": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "dgram_alias_connect": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "dgram_alias_sendto": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "direct": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "hardlink": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "symlink": { + "connected": true, + "sent": true, + "acknowledged": true + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 3, + "owner_received_fixture": true, + "datagram_receipts": 15, + "owner_datagram_received_fixture": true + }, + { + "name": "r0w0s0", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r0w0s1", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r0w1s0", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r0w1s1", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w0s0", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w0s1", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w1s0", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w1s1", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + } + ], + "scope": "Experimental pre-runtime native UNIX stream/datagram/descriptor controls; complete IPC/proxy/ownership and App acceptance remain required." +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-dropped-rights.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-dropped-rights.log new file mode 100644 index 000000000..ab679983c --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-dropped-rights.log @@ -0,0 +1,56 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: private SCM_RIGHTS exchange failed: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":false,"same_inode":false,"readable":false,"written":false,"cloexec":false},"rights_path_replaced":true,"private_datagram":[true,true,true],"datagram_symlink_created":true,"datagram_race":{"private_control":true,"host_control":false,"settled":true,"failed":false,"attempts":16,"private_acks":8,"host_acks":0,"refused":8,"swaps":17},"dgram_connect":{"connected":false,"sent":false,"acknowledged":false},"dgram_sendto":{"connected":false,"sent":false,"acknowledged":false},"dgram_sendmsg":{"connected":false,"sent":false,"acknowledged":false},"dgram_alias_connect":{"connected":false,"sent":false,"acknowledged":false},"dgram_alias_sendto":{"connected":false,"sent":false,"acknowledged":false},"dgram_alias_sendmsg":{"connected":false,"sent":false,"acknowledged":false},"direct":{"connected":false,"sent":false,"acknowledged":false},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":false,"sent":false,"acknowledged":false}},"rights_payload":"A","rights_link_count":0,"owner_receipts":0,"owner_received_fixture":false,"datagram_receipts":0,"owner_datagram_received_fixture":false} ++ actual - expected + + { ++ cloexec: false, +- cloexec: true, + original_closed: true, ++ readable: false, ++ received: false, ++ same_inode: false, +- readable: true, +- received: true, +- same_inode: true, + sent: true, + token: true, + truncated: false, ++ written: false +- written: true + } + + at check (file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:130:10) + at file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:192:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: { + sent: true, + original_closed: true, + token: true, + truncated: false, + received: false, + same_inode: false, + readable: false, + written: false, + cloexec: false + }, + expected: { + sent: true, + original_closed: true, + token: true, + truncated: false, + received: true, + same_inode: true, + readable: true, + written: true, + cloexec: true + }, + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-missing-scope.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-missing-scope.log new file mode 100644 index 000000000..a71b5088b --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-missing-scope.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: macOS datagram endpoint escaped scratch: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"private_datagram":[true,true,true],"datagram_symlink_created":true,"datagram_race":{"private_control":true,"host_control":true,"settled":true,"failed":false,"attempts":16,"private_acks":8,"host_acks":8,"refused":0,"swaps":16},"dgram_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_alias_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"AB","rights_link_count":0,"owner_receipts":2,"owner_received_fixture":true,"datagram_receipts":15,"owner_datagram_received_fixture":true} + +15 !== 0 + + at check (file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:144:10) + at file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:192:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 15, + expected: 0, + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-rights-path-reader.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-rights-path-reader.log new file mode 100644 index 000000000..c04e25a81 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-race-local/unix-rights-path-reader.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: received descriptor file effect: {"name":"unconfined","flags":{"read":true,"write":true,"shell":true,"unrestricted":true},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":true,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"private_datagram":[true,true,true],"datagram_symlink_created":true,"datagram_race":{"private_control":true,"host_control":true,"settled":true,"failed":false,"attempts":16,"private_acks":8,"host_acks":8,"refused":0,"swaps":17},"dgram_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_alias_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":true,"sent":true,"acknowledged":true},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"XX","rights_link_count":0,"owner_receipts":3,"owner_received_fixture":true,"datagram_receipts":15,"owner_datagram_received_fixture":true} + +'XX' !== 'AB' + + at check (file:///private/var/folders/zh/yw02jfzx4bdbc439_qtcg7740000gn/T/cyber-race-path-reader-6zk7_902/probe/macos_private_ipc.mts:134:10) + at file:///private/var/folders/zh/yw02jfzx4bdbc439_qtcg7740000gn/T/cyber-race-path-reader-6zk7_902/probe/macos_private_ipc.mts:192:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 'XX', + expected: 'AB', + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/macos_datagram.h b/scripts/probes/plugin-confinement/macos_datagram.h index 60b8e6d37..cc818befc 100644 --- a/scripts/probes/plugin-confinement/macos_datagram.h +++ b/scripts/probes/plugin-confinement/macos_datagram.h @@ -71,7 +71,9 @@ static struct unix_attempt host_datagram(const char *scratch, const char *host, return result; } -struct datagram_result { int private[3], symlink_created; struct unix_attempt host[6]; }; +#include "macos_datagram_race.h" + +struct datagram_result { int private[3], symlink_created; struct unix_attempt host[6]; struct datagram_race_result race; }; static struct datagram_result datagram_probe(const char *scratch, const char *host) { struct datagram_result result = {0}; char alias[PATH_MAX]; @@ -83,12 +85,14 @@ static struct datagram_result datagram_probe(const char *scratch, const char *ho if (result.symlink_created) result.host[method + 3] = host_datagram(scratch, alias, method); } unlink(alias); + result.race = datagram_race(scratch, host); return result; } static void print_datagram(struct datagram_result result) { printf(",\"private_datagram\":[%s,%s,%s],\"datagram_symlink_created\":%s", truth(result.private[0]), truth(result.private[1]), truth(result.private[2]), truth(result.symlink_created)); + print_datagram_race(result.race); const char *names[6] = { "dgram_connect", "dgram_sendto", "dgram_sendmsg", "dgram_alias_connect", "dgram_alias_sendto", "dgram_alias_sendmsg" }; for (int index = 0; index < 6; ++index) print_unix_attempt(names[index], result.host[index]); } diff --git a/scripts/probes/plugin-confinement/macos_datagram_race.h b/scripts/probes/plugin-confinement/macos_datagram_race.h new file mode 100644 index 000000000..b29b25f61 --- /dev/null +++ b/scripts/probes/plugin-confinement/macos_datagram_race.h @@ -0,0 +1,109 @@ +/* Concurrent replacement of an owned scratch alias; no host endpoint mutation. */ +#ifndef CYBER_MACOS_DATAGRAM_RACE_H +#define CYBER_MACOS_DATAGRAM_RACE_H +#include +#include + +struct datagram_mutator { + const char *alias, *temporary, *private_path, *host; + atomic_int stop, failed; + atomic_uint swaps; +}; + +static void *replace_datagram_alias(void *value) { + struct datagram_mutator *state = value; + const struct timespec pause = { .tv_nsec = 100000 }; + for (unsigned i = 0; i < 4096 && !atomic_load(&state->stop); ++i) { + const char *target = i % 2 ? state->private_path : state->host; + if (symlink(target, state->temporary) != 0 || rename(state->temporary, state->alias) != 0) { + atomic_store(&state->failed, 1); break; + } + atomic_fetch_add(&state->swaps, 1); + nanosleep(&pause, NULL); + } + return NULL; +} + +static int await_datagram_swap(struct datagram_mutator *state, unsigned previous) { + struct timespec start, now; + if (clock_gettime(CLOCK_MONOTONIC, &start) != 0) return 0; + const struct timespec pause = { .tv_nsec = 50000 }; + while (atomic_load(&state->swaps) <= previous) { + if (atomic_load(&state->failed) || clock_gettime(CLOCK_MONOTONIC, &now) != 0 || now.tv_sec - start.tv_sec >= 2) return 0; + nanosleep(&pause, NULL); + } + return 1; +} + +/* Returns P for an actual private acknowledgement, A for the owned host, + * D for a policy refusal and E for any invalid/unknown exchange. */ +static char datagram_race_exchange(int server, const char *scratch, const char *alias, int method) { + char client_path[PATH_MAX], token[13], ack = 0; + if (!joined(client_path, scratch, "dgram-client.sock")) return 'E'; + int client = datagram_socket(client_path); + if (client < 0) return 'E'; + struct unix_attempt sent = datagram_send(client, alias, method); + int send_error = errno; + if (!sent.sent) { + ack = send_error == EACCES || send_error == EPERM ? 'D' : 'E'; + } else { + ssize_t size = recv(server, token, sizeof(token), MSG_DONTWAIT); + if (size == 12 && memcmp(token, "fixture-only", 12) == 0) { + struct sockaddr_un reply; + if (!datagram_address(client_path, &reply) || sendto(server, "P", 1, 0, (struct sockaddr *)&reply, sizeof(reply)) != 1) goto done; + } else if (size >= 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) goto done; + if (recv(client, &ack, 1, 0) != 1 || (ack != 'P' && ack != 'A')) ack = 'E'; + } +done: + close(client); unlink(client_path); + return ack ? ack : 'E'; +} + +struct datagram_race_result { + int private_control, host_control, settled, failed, attempts, private_acks, host_acks, refused; + unsigned swaps; +}; +static struct datagram_race_result datagram_race(const char *scratch, const char *host) { + struct datagram_race_result result = {0}; + char server_path[PATH_MAX], alias[PATH_MAX], temporary[PATH_MAX]; + if (!joined(server_path, scratch, "dgram-race-private.sock") || !joined(alias, scratch, "dgram-race.sock") || + !joined(temporary, scratch, "dgram-race-next.sock")) return result; + int server = datagram_socket(server_path); + if (server < 0) return result; + if (symlink(server_path, alias) != 0) goto done; + result.private_control = datagram_race_exchange(server, scratch, alias, 1) == 'P'; + if (!result.private_control) goto done; + struct datagram_mutator state = { .alias = alias, .temporary = temporary, .private_path = server_path, .host = host }; + atomic_init(&state.stop, 0); atomic_init(&state.failed, 0); atomic_init(&state.swaps, 0); + pthread_t thread; + if (pthread_create(&thread, NULL, replace_datagram_alias, &state) != 0) goto done; + for (int i = 0; i < 16; ++i) { + if (!await_datagram_swap(&state, atomic_load(&state.swaps))) { result.failed = 1; break; } + char ack = datagram_race_exchange(server, scratch, alias, 1 + i % 2); + result.attempts++; + if (ack == 'P') result.private_acks++; + else if (ack == 'A') result.host_acks++; + else if (ack == 'D') result.refused++; + else { result.failed = 1; break; } + } + atomic_store(&state.stop, 1); + result.settled = pthread_join(thread, NULL) == 0; + result.failed |= atomic_load(&state.failed); + result.swaps = atomic_load(&state.swaps); + if (!result.settled) _exit(2); /* Do not release stack/path ownership under a live thread. */ + if (symlink(host, temporary) != 0 || rename(temporary, alias) != 0) { result.failed = 1; goto done; } + char ack = datagram_race_exchange(server, scratch, alias, 2); + result.host_control = ack == 'A'; + if (ack != 'A' && ack != 'D') result.failed = 1; +done: + close(server); unlink(server_path); unlink(alias); unlink(temporary); + return result; +} + +static void print_datagram_race(struct datagram_race_result result) { + printf(",\"datagram_race\":{\"private_control\":%s,\"host_control\":%s,\"settled\":%s,\"failed\":%s," + "\"attempts\":%d,\"private_acks\":%d,\"host_acks\":%d,\"refused\":%d,\"swaps\":%u}", + truth(result.private_control), truth(result.host_control), truth(result.settled), truth(result.failed), + result.attempts, result.private_acks, result.host_acks, result.refused, result.swaps); +} +#endif diff --git a/scripts/probes/plugin-confinement/macos_private_ipc.mts b/scripts/probes/plugin-confinement/macos_private_ipc.mts index 72bba51c8..0582c29ca 100644 --- a/scripts/probes/plugin-confinement/macos_private_ipc.mts +++ b/scripts/probes/plugin-confinement/macos_private_ipc.mts @@ -134,8 +134,17 @@ function check(entry: Awaited>) { assert.equal(entry.rights_payload, "AB", `received descriptor file effect: ${JSON.stringify(entry)}`); assert.deepEqual(entry.observed.private_datagram, [true, true, true], `private datagram exchange: ${JSON.stringify(entry)}`); assert.equal(entry.observed.datagram_symlink_created, true); - assert.equal(entry.datagram_receipts, entry.flags.unrestricted ? 6 : 0, + const race = entry.observed.datagram_race; + assert.equal(race.private_control, true); + assert.equal(race.settled, true); + assert.equal(race.failed, false, `datagram mutation failed: ${JSON.stringify(entry)}`); + assert.equal(race.attempts, 16); + assert(race.swaps >= race.attempts && race.swaps <= 4096); + assert.equal(race.private_acks + race.host_acks + race.refused, race.attempts); + assert.equal(entry.datagram_receipts, entry.flags.unrestricted ? 7 + race.host_acks : 0, `macOS datagram endpoint escaped scratch: ${JSON.stringify(entry)}`); + assert.equal(race.host_control, !!entry.flags.unrestricted); + assert.equal(race.refused, entry.flags.unrestricted ? 0 : race.attempts - race.private_acks); for (const prefix of ["dgram_", "dgram_alias_"]) for (const method of ["connect", "sendto", "sendmsg"]) { assert.deepEqual(entry.observed[prefix + method], { connected: !!entry.flags.unrestricted && method === "connect", @@ -184,7 +193,7 @@ try { rows.push(observed); } assert.equal(createHash("sha256").update(readFileSync(prepared.target)).digest("hex"), targetHash); - const sources = ["macos_private_ipc.mts", "macos_policy.mts", "macos_rights.h", "macos_datagram.h", "macos_datagram_owner.mts", "macos_datagram_owner.c", "fixture_native.c", "process_policy.h", "macos_exec.c"]; + const sources = ["macos_private_ipc.mts", "macos_policy.mts", "macos_rights.h", "macos_datagram.h", "macos_datagram_race.h", "macos_datagram_owner.mts", "macos_datagram_owner.c", "fixture_native.c", "process_policy.h", "macos_exec.c"]; const hash = createHash("sha256"); for (const file of sources) hash.update(file + "\0").update(readFileSync(join(source, file))); const report = { recorded_at: new Date().toISOString(), platform: process.platform, architecture: process.arch, diff --git a/scripts/probes/plugin-confinement/run.mts b/scripts/probes/plugin-confinement/run.mts index 80632c366..4bde6ea7b 100644 --- a/scripts/probes/plugin-confinement/run.mts +++ b/scripts/probes/plugin-confinement/run.mts @@ -401,7 +401,7 @@ function main() { const rows = cases.filter(([name]) => !unsupported_cases.some(item => item.name === name)) .map(([name, flags]) => check(root, artifacts, runtime, name, flags)); const digest = createHash("sha256"); - const sources = ["run.mts", "macos_policy.mts", "macos_rights.h", "macos_datagram.h", "macos_python.c", "macos_node.c", "native_exec.c", "node_bootstrap.cjs", "fixture.py", "fixture.cjs", "private_unix.cjs", "process_policy.h", "linux_filter.h", "linux_exec.c", "linux_initial_exec.h", "fixture_native.c", "macos_exec.c", "macos_stage.mts"]; + const sources = ["run.mts", "macos_policy.mts", "macos_rights.h", "macos_datagram.h", "macos_datagram_race.h", "macos_python.c", "macos_node.c", "native_exec.c", "node_bootstrap.cjs", "fixture.py", "fixture.cjs", "private_unix.cjs", "process_policy.h", "linux_filter.h", "linux_exec.c", "linux_initial_exec.h", "fixture_native.c", "macos_exec.c", "macos_stage.mts"]; for (const file of sources) { digest.update(file + "\0").update(readFileSync(join(source, file))); } From baee2f01b9818484ae117620a634b85a5dc982df Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 18:27:19 -0400 Subject: [PATCH 18/21] Bound pending file observer replacement ownership --- .../workflows/file-observation-regression.yml | 32 +++++ crates/cyber-tools/src/file_changes/owner.rs | 120 +++++++++++++++++- docs/goal-delivery.md | 5 +- .../file-observation-pending-owner.md | 35 +++++ .../complete-plugin-hook-runtime/tasks.md | 5 + 5 files changed, 189 insertions(+), 8 deletions(-) create mode 100644 openspec/changes/complete-plugin-hook-runtime/file-observation-pending-owner.md diff --git a/.github/workflows/file-observation-regression.yml b/.github/workflows/file-observation-regression.yml index 271836fad..58eb5db21 100644 --- a/.github/workflows/file-observation-regression.yml +++ b/.github/workflows/file-observation-regression.yml @@ -152,6 +152,38 @@ jobs: path: ${{ runner.temp }}/observation-membership-base.log if-no-files-found: error retention-days: 14 + - name: Verify pending observer ownership without the fix + if: runner.os == 'Linux' + shell: bash + run: | + set -euo pipefail + python3 - <<'PYCONTROL' + import os,re,subprocess + from pathlib import Path + owner=Path('crates/cyber-tools/src/file_changes/owner.rs') + source=owner.read_text() + needle='self.sessions.is_empty() && !self.waiting_for_previous' + assert source.count(needle)==1 + try: + owner.write_text(source.replace(needle,'self.sessions.is_empty()')) + name='file_changes::owner::tests::readmission_reuses_one_pending_replacement_until_previous_owner_settles' + result=subprocess.run(['cargo','test','--locked','-p','cyber-tools','--lib',name,'--','--exact'],capture_output=True,text=True) + log=result.stdout+result.stderr + Path(os.environ['RUNNER_TEMP'],'observation-pending-owner-base.log').write_text(log) + assert result.returncode!=0, log[-8000:] + assert re.search(r'^test '+re.escape(name)+r' \.\.\. FAILED$',log,re.M), log[-8000:] + assert 'readmission must not grow a task chain behind a settling owner' in log, log[-8000:] + finally: + owner.write_text(source) + PYCONTROL + - name: Preserve pending observer ownership regression evidence + if: always() && runner.os == 'Linux' + uses: actions/upload-artifact@v4 + with: + name: pending-observer-owner-baseline + path: ${{ runner.temp }}/observation-pending-owner-base.log + if-no-files-found: error + retention-days: 14 - name: Verify known-private retirement without the fix if: runner.os == 'Linux' shell: bash diff --git a/crates/cyber-tools/src/file_changes/owner.rs b/crates/cyber-tools/src/file_changes/owner.rs index 4c0ce6716..b80ba91cd 100644 --- a/crates/cyber-tools/src/file_changes/owner.rs +++ b/crates/cyber-tools/src/file_changes/owner.rs @@ -28,6 +28,9 @@ const RECONCILE: Duration = Duration::from_secs(3); #[derive(Default)] struct Membership { sessions: BTreeMap, + /// Readmission reuses this owner while the previous incarnation settles. + /// Cancelling an empty pending owner would grow an unbounded join chain. + waiting_for_previous: bool, /// Keep only the newest committed acknowledgement per current Session. /// Both maps share the 256-Session bound; input bursts cannot grow a queue. renewals: BTreeMap, @@ -43,8 +46,8 @@ impl Membership { self.renewals.remove(session); self.scopes.remove(session); } - fn is_empty(&self) -> bool { - self.sessions.is_empty() + fn can_stop(&self) -> bool { + self.sessions.is_empty() && !self.waiting_for_previous } } @@ -69,15 +72,20 @@ impl Registry { } let mut members = entry.members.lock().unwrap_or_else(PoisonError::into_inner); members.remove(session); - if members.is_empty() { + if members.can_stop() { entry.cancel.cancel(); } } } } impl Entry { - fn add(&self, host: &BuiltinHost, session: &str) { + fn add_if_live(&self, host: &BuiltinHost, session: &str) -> bool { let mut members = self.members.lock().unwrap_or_else(PoisonError::into_inner); + // Activation may cancel an empty pending owner. Serialize admission with + // that decision rather than adding an already-cancelled child token. + if self.cancel.is_cancelled() { + return false; + } if members.sessions.contains_key(session) || members.sessions.len() < MAX_SESSIONS { members .sessions @@ -91,6 +99,7 @@ impl Entry { "FileChanged coverage unavailable: Session limit reached", ); } + true } } @@ -115,9 +124,8 @@ impl Observers { .retain(|_, entry| !entry.task.is_finished()); registry.remove_other_memberships(&path, &info.id); if let Some(entry) = registry.entries.get(&path) - && !entry.cancel.is_cancelled() + && entry.add_if_live(host, &info.id) { - entry.add(host, &info.id); return; } let previous = registry.entries.remove(&path); @@ -132,6 +140,7 @@ impl Observers { let cancel = CancellationToken::new(); let members = Arc::new(Mutex::new(Membership { sessions: BTreeMap::from([(info.id.clone(), cancel.child_token())]), + waiting_for_previous: previous.is_some(), renewals: BTreeMap::new(), scopes: BTreeSet::new(), explicit: Hints::default(), @@ -145,6 +154,13 @@ impl Observers { if let Some(previous) = previous { let _ = previous.task.await; } + { + let mut members = membership.lock().unwrap_or_else(PoisonError::into_inner); + members.waiting_for_previous = false; + if members.sessions.is_empty() { + owner.cancel(); + } + } run(weak, root, directory, membership, owner).await; }); registry.entries.insert( @@ -210,7 +226,7 @@ impl Observers { for entry in registry.entries.values() { let mut members = entry.members.lock().unwrap_or_else(PoisonError::into_inner); members.remove(session); - if members.is_empty() { + if members.can_stop() { entry.cancel.cancel(); } } @@ -859,6 +875,96 @@ async fn start_observation( mod tests { use super::*; + #[tokio::test] + async fn readmission_reuses_one_pending_replacement_until_previous_owner_settles() { + let temp = tempfile::tempdir().unwrap(); + let root = temp.path().canonicalize().unwrap(); + let store = Arc::new( + cyber_store::Store::open(cyber_store::StoreOptions::new( + cyber_core::paths::DatabaseLocation::Memory, + cyber_server::runtime::Runtime::registry(), + )) + .unwrap(), + ); + let host = BuiltinHost::new(crate::HostOptions { + store, + tool_output_dir: root.join("tool-output"), + allowed_dirs: Vec::new(), + home: root.join("home"), + shell: "bash".into(), + config: Arc::new(|_| Ok((serde_json::json!({}), BTreeMap::new()))), + global_config_dir: root.join("config"), + env: Arc::new(std::collections::HashMap::::new()), + models: None, + temp_dir: root.join("tmp"), + sandbox_policy: None, + sandbox_helper: None, + isolation: crate::IsolationOptions { + dangerously_bypass: false, + container: false, + }, + }); + let info: SessionInfo = serde_json::from_value(serde_json::json!({ + "id": "session", "title": "fixture", "directory": root, + "parent_id": null, "agent": "default", "model": "fixture/model", + "mode": "default", "created_ms": 0 + })) + .unwrap(); + let gate = Arc::new(tokio::sync::Notify::new()); + let held = Arc::clone(&gate); + let previous = tokio::spawn(async move { held.notified().await }); + let cancel = CancellationToken::new(); + cancel.cancel(); + let observers = Observers(Mutex::new(Registry { + entries: BTreeMap::from([( + root.clone(), + Entry { + members: Arc::new(Mutex::new(Membership::default())), + cancel, + task: previous, + }, + )]), + closed: false, + })); + let mut replacements = std::collections::HashSet::new(); + let mut removed_tokens_cancelled = true; + for _ in 0..256 { + observers.refresh(&host, &info); + let token = { + let registry = observers.0.lock().unwrap(); + let entry = ®istry.entries[&root]; + replacements.insert(entry.task.id()); + member_cancellation(&entry.members, &info.id).unwrap() + }; + observers.remove(&info.id); + removed_tokens_cancelled &= token.is_cancelled(); + } + observers.refresh(&host, &info); + let final_token = { + let registry = observers.0.lock().unwrap(); + let entry = ®istry.entries[&root]; + replacements.insert(entry.task.id()); + member_cancellation(&entry.members, &info.id).unwrap() + }; + let final_membership_live = !final_token.is_cancelled(); + gate.notify_one(); + observers.shutdown().await; + assert!(removed_tokens_cancelled); + assert!( + final_membership_live, + "readmission needs live callback authority" + ); + assert!( + final_token.is_cancelled(), + "shutdown must revoke pending authority" + ); + assert_eq!( + replacements.len(), + 1, + "readmission must not grow a task chain behind a settling owner" + ); + } + #[test] fn removing_membership_cancels_held_delivery_without_stopping_other_members() { let owner = CancellationToken::new(); diff --git a/docs/goal-delivery.md b/docs/goal-delivery.md index 4bd3204c2..a56e75ba7 100644 --- a/docs/goal-delivery.md +++ b/docs/goal-delivery.md @@ -43,7 +43,10 @@ separate review. This changes delivery granularity, not feature scope or accepta - Preserve native proof and explicit support/design revision gates. Passing probes are not production feature acceptance. Never weaken the agreed contract merely to finish a PR. Merge only with user authorization; the conditional approval - above applies to #76. + above originally applied to #76. On 2026-10-30 the user additionally authorized + merging ready repository PRs as work continues. Check current-head CI, scope, + review and mergeability before each merge, and recheck composition as main + advances. This does not waive draft, native proof or design-revision gates. PR [#76](https://github.com/CyberdyneCorp/cybercode-cli/pull/76) merged on 2026-10-30 at `ec31ff9fc7627a3a9262d99f0fc0606394368423`, after all 70 applicable diff --git a/openspec/changes/complete-plugin-hook-runtime/file-observation-pending-owner.md b/openspec/changes/complete-plugin-hook-runtime/file-observation-pending-owner.md new file mode 100644 index 000000000..23b1dde5b --- /dev/null +++ b/openspec/changes/complete-plugin-hook-runtime/file-observation-pending-owner.md @@ -0,0 +1,35 @@ +# Bounded pending FileChanged owner replacement + +Review reproduced a resource-lifetime defect in the existing observer registry. +A cancelled owner could still be settling. Each remove/readmit cycle then created +another Tokio task awaiting the previous task. The registry held one entry while +its nested chain grew: 256 cycles created 257 replacement tasks in the regression. +This is candidate evidence, without attributing the defect to an unchecked base. + +A pending replacement now retains its owner token until its predecessor settles. +Removing a Session still cancels that Session's callback token immediately and +removes its renewal/scope admission. Readmission joins the single pending owner +with a fresh callback token. Once the predecessor settles, activation clears the +pending flag under the membership lock and cancels an empty owner. Admission +checks liveness under that same lock, so it cannot attach an already-cancelled +child token during activation. Shutdown independently cancels and joins owners, +including their retained predecessors. No uncertain resources are discarded. + +The regression uses the real registry refresh/remove paths and a controlled held +predecessor. It requires one replacement across 256 cycles, cancellation of every +removed token, fresh live authority after final readmission and revocation on +joined shutdown. The original test executed and failed at the task-chain assertion +with 257 replacements. The corrected file-observation library suite passes 58 +tests with one subprocess helper intentionally ignored by the parent test runner. +All 24 actual HTTP callback lifecycle regressions also pass locally. These +component results do not prove native confinement or current-source platform +acceptance. Scoped `cyber-tools --lib` Clippy with warnings denied and Rust +formatting pass. Strict OpenSpec validates all 107 items; spec lint reports zero +errors and 25 warnings. + +The focused workflow removes only the pending-owner cancellation guard as a +counterexample. It must execute the regression and fail its exact task-chain +assertion; compilation failure cannot satisfy the control. The exact control +was executed locally and failed at that assertion. Platform CI and composed-feature +acceptance remain required. Task 5.2 +stays open, as do the separate plugin native admission and protocol gates. diff --git a/openspec/changes/complete-plugin-hook-runtime/tasks.md b/openspec/changes/complete-plugin-hook-runtime/tasks.md index 9c390bfa8..cdad674d5 100644 --- a/openspec/changes/complete-plugin-hook-runtime/tasks.md +++ b/openspec/changes/complete-plugin-hook-runtime/tasks.md @@ -95,3 +95,8 @@ then review reproduced false deletion dispatch when a known private inode/subtre replaces a public baseline name. The new silent-retirement correction has two real HTTP regressions and a missing-fix behavioral control. Task 5.2 remains open for current-source platform acceptance; see the integration evidence above. + +The [pending observer owner correction](file-observation-pending-owner.md) bounds +remove/readmit replacement behind a settling owner while retaining cancellation +and joined shutdown. Focused and platform acceptance remain required; task 5.2 +stays open. From cf695982a574c64a643a8fbd4f9db04256b91ec1 Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 19:14:52 -0400 Subject: [PATCH 19/21] Record native datagram race failure diagnostics --- .../workflows/plugin-confinement-proof.yml | 35 + .../macos-datagram-alias-race.md | 40 +- scripts/probes/plugin-confinement/README.md | 5 + .../unix-boundary.json | 973 ++++++++++++++++++ .../unix-boundary.log | 973 ++++++++++++++++++ .../unix-datagram-bind-failure.log | 20 + .../unix-dropped-rights.log | 56 + .../unix-missing-scope.log | 20 + .../unix-rights-path-reader.log | 20 + .../macos-datagram-intel-08ee6fe6/exec.json | 82 ++ .../macos-datagram-intel-08ee6fe6/exec.log | 82 ++ .../macos-datagram-intel-08ee6fe6/job.log | 312 ++++++ .../macos-datagram-intel-08ee6fe6/matrix.json | 547 ++++++++++ .../macos-datagram-intel-08ee6fe6/matrix.log | 547 ++++++++++ .../private-unix-missing-grant.log | 31 + .../source-binding.json | 21 + .../unix-boundary.log | 20 + .../plugin-confinement/macos_datagram_race.h | 71 +- .../plugin-confinement/macos_private_ipc.mts | 6 +- 19 files changed, 3838 insertions(+), 23 deletions(-) create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-boundary.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-boundary.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-datagram-bind-failure.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-dropped-rights.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-missing-scope.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-rights-path-reader.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/exec.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/exec.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/job.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/matrix.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/matrix.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/private-unix-missing-grant.log create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/source-binding.json create mode 100644 scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/unix-boundary.log diff --git a/.github/workflows/plugin-confinement-proof.yml b/.github/workflows/plugin-confinement-proof.yml index ef6a7d5d0..d49f1002c 100644 --- a/.github/workflows/plugin-confinement-proof.yml +++ b/.github/workflows/plugin-confinement-proof.yml @@ -202,6 +202,40 @@ jobs: '"private_aliases":[true,true]', '"private_peer_matches":true']: assert token in text, text PYCONTROL + - name: Reject unknown datagram exchange failures + shell: bash + run: | + set -euo pipefail + control="$RUNNER_TEMP/macos-datagram-bind-failure" + python3 - "$control" <<'PYCONTROL' + from pathlib import Path + import shutil, sys + target = Path(sys.argv[1]) + shutil.copytree('scripts/probes/plugin-confinement', target, ignore=shutil.ignore_patterns('evidence', '__pycache__')) + fixture = target / 'macos_datagram_race.h' + source = fixture.read_text() + needle = 'int client = datagram_socket(client_path);' + assert source.count(needle) == 1 + fixture.write_text(source.replace(needle, 'int client = datagram_socket(alias);')) + PYCONTROL + log="$RUNNER_TEMP/unix-datagram-bind-failure.log" + if node --experimental-strip-types "$control/macos_private_ipc.mts" > "$log" 2>&1; then + echo 'Occupied datagram client bind unexpectedly passed' >&2 + exit 1 + fi + python3 - "$log" <<'PYCONTROL' + from pathlib import Path + import errno, json, re, sys + text = Path(sys.argv[1]).read_text() + match = re.search(r'private datagram race control failed: (\{[^\n]+\})', text) + assert match, text + entry = json.loads(match[1]) + race = entry['observed']['datagram_race'] + assert entry['flags']['unrestricted'] and not race['private_control'], entry + assert race['failure_stage'] == 'client_bind', entry + assert race['failure_errno'] == errno.EADDRINUSE, entry + assert race['refused'] == 0 and race['attempts'] == 0, entry + PYCONTROL - name: Reject missing private descriptor reception shell: bash run: | @@ -262,6 +296,7 @@ jobs: ${{ runner.temp }}/unix-boundary.json ${{ runner.temp }}/unix-boundary.log ${{ runner.temp }}/unix-missing-scope.log + ${{ runner.temp }}/unix-datagram-bind-failure.log ${{ runner.temp }}/unix-dropped-rights.log ${{ runner.temp }}/unix-rights-path-reader.log ${{ runner.temp }}/exec.json diff --git a/openspec/changes/complete-plugin-hook-runtime/macos-datagram-alias-race.md b/openspec/changes/complete-plugin-hook-runtime/macos-datagram-alias-race.md index 5e7c98793..4202b3483 100644 --- a/openspec/changes/complete-plugin-hook-runtime/macos-datagram-alias-race.md +++ b/openspec/changes/complete-plugin-hook-runtime/macos-datagram-alias-race.md @@ -50,7 +50,45 @@ Independently recomputed source hashes are: - IPC: `7eae036bc0756198bd522e570f6e2c7a357efab0f0eb543b7ced11d4e4f88cce`. - Runtime: `05c2c5808004a944c2582857a16df3f4a2266abbe5911d68886c36aeebd3b5ad`. -Hosted verification is pending. This tests one concurrently replaced symlink +## Hosted failure and diagnostic follow-up + +The Intel native signing job in [run 41119882444](https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41119882444/job/124283606909) +failed at the `r0w1s1` datagram mutation row: three attempts were recorded before the +fixture reported an unknown exchange failure. Its other private stream, +descriptor and fixed datagram checks passed, but they do not override the failed +race. Zero observed host packets from an incomplete row is not confinement +acceptance. The failure's original report did not identify the failing operation +or errno; its cause remains unresolved. + +Original artifacts and the job log are retained in +`scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6`. +The downloaded archive matches GitHub's SHA-256 digest +`24c3a99bbff97fba00dd1a977ceb5fc6ebd14b3110f6ec9b4a3cc3e807a0f654`. +The source binding verifies that the actual tested merge `ebdb3f33` and head +`08ee6fe6` share tree `b10649b8f6ca411a8506705bbe88f8bc9d5ca44b`. + +The diagnostic extension records the first failure stage and errno, including +send/receive, private replies, client setup, alias replacement and mutation +progress. The mutator publishes its error atomically; it is still stopped and +joined before resource release. Success requires an empty failure stage and zero +errno in addition to the existing acknowledgements and receipt counts. Unknown +errors still fail; they are not retried or classified as permission refusals. + +A copied-fixture control attempts to bind its client through the already occupied +private server alias. It must fail the real private-control assertion and report +`client_bind` with `EADDRINUSE`, zero race attempts and zero policy refusals. +Compiler failure cannot satisfy this control. The workflow retains its log. + +All nine diagnostic rows and four exact workflow steps pass locally on arm64 +Darwin 25.6.0, including occupied-bind, widened-scope, dropped-rights and path-reader +controls. Original reports/logs are retained in +`scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local`. +The current IPC source digest is +`24c0b65db4e5609b386b460b713989b2d2d2954e3b4222f72985b057b8c9bc15`. +These results establish diagnostic behavior, not a fix for the Intel failure. +Fresh hosted verification remains required. + +This tests one concurrently replaced symlink with destination-bearing sends. It does not establish every pathname/FD/address mutation, seqpacket or ancillary credential behavior, proxy/network/secret ceilings, descendant settlement or App integration. Parent acceptance stays open. diff --git a/scripts/probes/plugin-confinement/README.md b/scripts/probes/plugin-confinement/README.md index d500edfd1..18f6442d7 100644 --- a/scripts/probes/plugin-confinement/README.md +++ b/scripts/probes/plugin-confinement/README.md @@ -103,6 +103,11 @@ after guest settlement; startup failure cannot count as zero delivery. See The [concurrent alias test](../../../openspec/changes/complete-plugin-hook-runtime/macos-datagram-alias-race.md) replaces a scratch symlink while native sendto/sendmsg run and compares actual private acknowledgements, policy refusals and owner-recorded host packets. +Its first unexpected operation/errno is retained in `failure_stage` and +`failure_errno`; successful rows require both to be empty/zero. The occupied-bind +control must report `client_bind`/`EADDRINUSE` and fail the real private exchange +assertion. Unknown errors never count as policy refusals. The retained Intel +failure remains unresolved pending the diagnostic run. ## Boundary and coverage diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-boundary.json b/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-boundary.json new file mode 100644 index 000000000..044433474 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-boundary.json @@ -0,0 +1,973 @@ +{ + "recorded_at": "2026-10-30T23:11:15.236Z", + "platform": "darwin", + "architecture": "arm64", + "kernel_release": "25.6.0", + "sources": [ + "macos_private_ipc.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_datagram.h", + "macos_datagram_race.h", + "macos_datagram_owner.mts", + "macos_datagram_owner.c", + "fixture_native.c", + "process_policy.h", + "macos_exec.c" + ], + "source_sha256": "24c0b65db4e5609b386b460b713989b2d2d2954e3b4222f72985b057b8c9bc15", + "target_sha256": "0dc2ad4feff3c475b0d31ca2c0f48d4f59ded5d784c3f7b44afa74748f0c966a", + "receiver_startup_controls": { + "missing_program_refused": true, + "failed_bind_refused": true + }, + "rows": [ + { + "name": "unconfined", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": true, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": true, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 8, + "refused": 0, + "swaps": 17, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "dgram_sendto": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "dgram_sendmsg": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "dgram_alias_connect": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "dgram_alias_sendto": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "direct": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "hardlink": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "symlink": { + "connected": true, + "sent": true, + "acknowledged": true + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 3, + "owner_received_fixture": true, + "datagram_receipts": 15, + "owner_datagram_received_fixture": true + }, + { + "name": "r0w0s0", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r0w0s1", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r0w1s0", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r0w1s1", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w0s0", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w0s1", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w1s0", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w1s1", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + } + ], + "scope": "Experimental pre-runtime native UNIX stream/datagram/descriptor controls; complete IPC/proxy/ownership and App acceptance remain required." +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-boundary.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-boundary.log new file mode 100644 index 000000000..044433474 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-boundary.log @@ -0,0 +1,973 @@ +{ + "recorded_at": "2026-10-30T23:11:15.236Z", + "platform": "darwin", + "architecture": "arm64", + "kernel_release": "25.6.0", + "sources": [ + "macos_private_ipc.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_datagram.h", + "macos_datagram_race.h", + "macos_datagram_owner.mts", + "macos_datagram_owner.c", + "fixture_native.c", + "process_policy.h", + "macos_exec.c" + ], + "source_sha256": "24c0b65db4e5609b386b460b713989b2d2d2954e3b4222f72985b057b8c9bc15", + "target_sha256": "0dc2ad4feff3c475b0d31ca2c0f48d4f59ded5d784c3f7b44afa74748f0c966a", + "receiver_startup_controls": { + "missing_program_refused": true, + "failed_bind_refused": true + }, + "rows": [ + { + "name": "unconfined", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": true, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": true, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 8, + "refused": 0, + "swaps": 17, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "dgram_sendto": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "dgram_sendmsg": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "dgram_alias_connect": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "dgram_alias_sendto": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": true, + "acknowledged": true + }, + "direct": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "hardlink": { + "connected": true, + "sent": true, + "acknowledged": true + }, + "symlink": { + "connected": true, + "sent": true, + "acknowledged": true + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 3, + "owner_received_fixture": true, + "datagram_receipts": 15, + "owner_datagram_received_fixture": true + }, + { + "name": "r0w0s0", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r0w0s1", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r0w1s0", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r0w1s1", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w0s0", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w0s1", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w1s0", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + }, + { + "name": "r1w1s1", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observed": { + "started": true, + "private_unix": [ + true, + true + ], + "private_peer_checks": 8, + "private_peer_matches": true, + "hardlink_created": false, + "symlink_created": true, + "private_aliases": [ + true, + true + ], + "rights": { + "sent": true, + "original_closed": true, + "token": true, + "truncated": false, + "received": true, + "same_inode": true, + "readable": true, + "written": true, + "cloexec": true + }, + "rights_path_replaced": true, + "private_datagram": [ + true, + true, + true + ], + "datagram_symlink_created": true, + "datagram_race": { + "private_control": true, + "host_control": false, + "settled": true, + "failed": false, + "attempts": 16, + "private_acks": 8, + "host_acks": 0, + "refused": 8, + "swaps": 16, + "failure_stage": "", + "failure_errno": 0 + }, + "dgram_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_connect": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendto": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "dgram_alias_sendmsg": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "direct": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "hardlink": { + "connected": false, + "sent": false, + "acknowledged": false + }, + "symlink": { + "connected": false, + "sent": false, + "acknowledged": false + } + }, + "rights_payload": "AB", + "rights_link_count": 0, + "owner_receipts": 0, + "owner_received_fixture": false, + "datagram_receipts": 0, + "owner_datagram_received_fixture": false + } + ], + "scope": "Experimental pre-runtime native UNIX stream/datagram/descriptor controls; complete IPC/proxy/ownership and App acceptance remain required." +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-datagram-bind-failure.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-datagram-bind-failure.log new file mode 100644 index 000000000..413915cd3 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-datagram-bind-failure.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: private datagram race control failed: {"name":"unconfined","flags":{"read":true,"write":true,"shell":true,"unrestricted":true},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":true,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"private_datagram":[true,true,true],"datagram_symlink_created":true,"datagram_race":{"private_control":false,"host_control":false,"settled":false,"failed":false,"attempts":0,"private_acks":0,"host_acks":0,"refused":0,"swaps":0,"failure_stage":"client_bind","failure_errno":48},"dgram_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_alias_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":true,"sent":true,"acknowledged":true},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"AB","rights_link_count":0,"owner_receipts":3,"owner_received_fixture":true,"datagram_receipts":6,"owner_datagram_received_fixture":true} + +false !== true + + at check (file:///private/tmp/cyber-datagram-steps-pjrlzna8/macos-datagram-bind-failure/macos_private_ipc.mts:138:10) + at file:///private/tmp/cyber-datagram-steps-pjrlzna8/macos-datagram-bind-failure/macos_private_ipc.mts:194:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: false, + expected: true, + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-dropped-rights.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-dropped-rights.log new file mode 100644 index 000000000..f8b2120e1 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-dropped-rights.log @@ -0,0 +1,56 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: private SCM_RIGHTS exchange failed: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":false,"same_inode":false,"readable":false,"written":false,"cloexec":false},"rights_path_replaced":true,"private_datagram":[true,true,true],"datagram_symlink_created":true,"datagram_race":{"private_control":true,"host_control":false,"settled":true,"failed":false,"attempts":16,"private_acks":8,"host_acks":0,"refused":8,"swaps":16,"failure_stage":"","failure_errno":0},"dgram_connect":{"connected":false,"sent":false,"acknowledged":false},"dgram_sendto":{"connected":false,"sent":false,"acknowledged":false},"dgram_sendmsg":{"connected":false,"sent":false,"acknowledged":false},"dgram_alias_connect":{"connected":false,"sent":false,"acknowledged":false},"dgram_alias_sendto":{"connected":false,"sent":false,"acknowledged":false},"dgram_alias_sendmsg":{"connected":false,"sent":false,"acknowledged":false},"direct":{"connected":false,"sent":false,"acknowledged":false},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":false,"sent":false,"acknowledged":false}},"rights_payload":"A","rights_link_count":0,"owner_receipts":0,"owner_received_fixture":false,"datagram_receipts":0,"owner_datagram_received_fixture":false} ++ actual - expected + + { ++ cloexec: false, +- cloexec: true, + original_closed: true, ++ readable: false, ++ received: false, ++ same_inode: false, +- readable: true, +- received: true, +- same_inode: true, + sent: true, + token: true, + truncated: false, ++ written: false +- written: true + } + + at check (file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:130:10) + at file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:194:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: { + sent: true, + original_closed: true, + token: true, + truncated: false, + received: false, + same_inode: false, + readable: false, + written: false, + cloexec: false + }, + expected: { + sent: true, + original_closed: true, + token: true, + truncated: false, + received: true, + same_inode: true, + readable: true, + written: true, + cloexec: true + }, + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-missing-scope.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-missing-scope.log new file mode 100644 index 000000000..2321a679e --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-missing-scope.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: macOS datagram endpoint escaped scratch: {"name":"r0w0s0","flags":{"read":false,"write":false,"shell":false},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"private_datagram":[true,true,true],"datagram_symlink_created":true,"datagram_race":{"private_control":true,"host_control":true,"settled":true,"failed":false,"attempts":16,"private_acks":8,"host_acks":8,"refused":0,"swaps":16,"failure_stage":"","failure_errno":0},"dgram_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_alias_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"AB","rights_link_count":0,"owner_receipts":2,"owner_received_fixture":true,"datagram_receipts":15,"owner_datagram_received_fixture":true} + +15 !== 0 + + at check (file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:146:10) + at file:///Users/edvane/work/cybercode-plugin-native-host-admission/scripts/probes/plugin-confinement/macos_private_ipc.mts:194:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 15, + expected: 0, + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-rights-path-reader.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-rights-path-reader.log new file mode 100644 index 000000000..5e09c289e --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-diagnostic-local/unix-rights-path-reader.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: received descriptor file effect: {"name":"unconfined","flags":{"read":true,"write":true,"shell":true,"unrestricted":true},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":true,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"private_datagram":[true,true,true],"datagram_symlink_created":true,"datagram_race":{"private_control":true,"host_control":true,"settled":true,"failed":false,"attempts":16,"private_acks":8,"host_acks":8,"refused":0,"swaps":17,"failure_stage":"","failure_errno":0},"dgram_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_connect":{"connected":true,"sent":true,"acknowledged":true},"dgram_alias_sendto":{"connected":false,"sent":true,"acknowledged":true},"dgram_alias_sendmsg":{"connected":false,"sent":true,"acknowledged":true},"direct":{"connected":true,"sent":true,"acknowledged":true},"hardlink":{"connected":true,"sent":true,"acknowledged":true},"symlink":{"connected":true,"sent":true,"acknowledged":true}},"rights_payload":"XX","rights_link_count":0,"owner_receipts":3,"owner_received_fixture":true,"datagram_receipts":15,"owner_datagram_received_fixture":true} + +'XX' !== 'AB' + + at check (file:///private/tmp/cyber-datagram-steps-pjrlzna8/macos-rights-path-reader/macos_private_ipc.mts:134:10) + at file:///private/tmp/cyber-datagram-steps-pjrlzna8/macos-rights-path-reader/macos_private_ipc.mts:194:5 + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: 'XX', + expected: 'AB', + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.20.0 diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/exec.json b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/exec.json new file mode 100644 index 000000000..eb7b1c720 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/exec.json @@ -0,0 +1,82 @@ +{ + "recorded_at": "2026-10-30T22:03:11.803Z", + "platform": "darwin", + "architecture": "x64", + "kernel_release": "24.6.0", + "sources": [ + "macos_signing_exec.mts", + "macos_exec.c", + "fixture_exec.c", + "macos_signature.c", + "macos_fds.c" + ], + "source_sha256": "7a06af58c27b8b134dd4833f6947b1a27623c4c3ef34c74542528d05ae284723", + "signing_identifier": "com.cyberdyne.probe.helperX.9f24ebd7-aee7-4ad0-a270-9941db5afee4", + "signature": { + "status": 0, + "signal": null, + "stdout": "", + "stderr": "" + }, + "native_control": { + "initial_exec": true, + "self_exec": true + }, + "native": { + "initial_exec": true, + "self_exec": false + }, + "original_platform_image": { + "path": "/bin/bash", + "sha256": "c372d1d6d4f07e0a917f3660aa79df00cbb50323972c22c3d90ec17d2096d039", + "control": { + "status": 0, + "signal": null, + "stdout": "initial-admitted\nself-exec", + "stderr": "" + }, + "restricted": { + "status": 1, + "signal": null, + "stdout": "initial-admitted\n", + "stderr": "/bin/bash: /bin/bash: Operation not permitted\n/bin/bash: /bin/bash: Undefined error: 0\n" + } + }, + "same_identifier_counterexample": { + "initial_exec": true, + "self_exec": true + }, + "detached_signature": { + "control": [ + { + "initial_exec": true, + "add_signature_result": 0, + "add_signature_errno": 0 + }, + { + "self_exec": true + } + ], + "restricted": [ + { + "initial_exec": true, + "add_signature_result": 0, + "add_signature_errno": 0 + }, + { + "self_exec": false, + "exec_errno": 1 + } + ], + "original_image_unchanged": true + }, + "inherited_above_soft_limit": { + "control": { + "inherited_descriptor": true + }, + "launcher": { + "inherited_descriptor": false + } + }, + "limitation": "Experimental exec-only candidate. Identifier collision is an observed bypass. Immutable package/helper identity admission across all slices, other kernel mutation interfaces, packaging and owner integration remain unproved; no production support change." +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/exec.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/exec.log new file mode 100644 index 000000000..eb7b1c720 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/exec.log @@ -0,0 +1,82 @@ +{ + "recorded_at": "2026-10-30T22:03:11.803Z", + "platform": "darwin", + "architecture": "x64", + "kernel_release": "24.6.0", + "sources": [ + "macos_signing_exec.mts", + "macos_exec.c", + "fixture_exec.c", + "macos_signature.c", + "macos_fds.c" + ], + "source_sha256": "7a06af58c27b8b134dd4833f6947b1a27623c4c3ef34c74542528d05ae284723", + "signing_identifier": "com.cyberdyne.probe.helperX.9f24ebd7-aee7-4ad0-a270-9941db5afee4", + "signature": { + "status": 0, + "signal": null, + "stdout": "", + "stderr": "" + }, + "native_control": { + "initial_exec": true, + "self_exec": true + }, + "native": { + "initial_exec": true, + "self_exec": false + }, + "original_platform_image": { + "path": "/bin/bash", + "sha256": "c372d1d6d4f07e0a917f3660aa79df00cbb50323972c22c3d90ec17d2096d039", + "control": { + "status": 0, + "signal": null, + "stdout": "initial-admitted\nself-exec", + "stderr": "" + }, + "restricted": { + "status": 1, + "signal": null, + "stdout": "initial-admitted\n", + "stderr": "/bin/bash: /bin/bash: Operation not permitted\n/bin/bash: /bin/bash: Undefined error: 0\n" + } + }, + "same_identifier_counterexample": { + "initial_exec": true, + "self_exec": true + }, + "detached_signature": { + "control": [ + { + "initial_exec": true, + "add_signature_result": 0, + "add_signature_errno": 0 + }, + { + "self_exec": true + } + ], + "restricted": [ + { + "initial_exec": true, + "add_signature_result": 0, + "add_signature_errno": 0 + }, + { + "self_exec": false, + "exec_errno": 1 + } + ], + "original_image_unchanged": true + }, + "inherited_above_soft_limit": { + "control": { + "inherited_descriptor": true + }, + "launcher": { + "inherited_descriptor": false + } + }, + "limitation": "Experimental exec-only candidate. Identifier collision is an observed bypass. Immutable package/helper identity admission across all slices, other kernel mutation interfaces, packaging and owner integration remain unproved; no production support change." +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/job.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/job.log new file mode 100644 index 000000000..a1a93ff61 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/job.log @@ -0,0 +1,312 @@ +2026-10-30T22:02:52.4207790Z Current runner version: '2.338.2' +2026-10-30T22:02:52.4261020Z ##[group]Runner Image Provisioner +2026-10-30T22:02:52.4263560Z Hosted Compute Agent +2026-10-30T22:02:52.4265550Z Version: 20260819.586 +2026-10-30T22:02:52.4267570Z Commit: 3cc4a88dfa507ef76119ad1bb3eccc6378bb2b76 +2026-10-30T22:02:52.4269720Z Build Date: 2026-08-18T23:20:18Z +2026-10-30T22:02:52.4271680Z Worker ID: {78a93ab6-de64-4a5f-9755-c10aa5fb6d89} +2026-10-30T22:02:52.4273710Z Azure Region: westus +2026-10-30T22:02:52.4275550Z ##[endgroup] +2026-10-30T22:02:52.4280750Z ##[group]Operating System +2026-10-30T22:02:52.4282650Z macOS +2026-10-30T22:02:52.4284200Z 15.7.9 +2026-10-30T22:02:52.4286160Z 24G830 +2026-10-30T22:02:52.4287830Z ##[endgroup] +2026-10-30T22:02:52.4289490Z ##[group]Runner Image +2026-10-30T22:02:52.4291380Z Image: macos-15 +2026-10-30T22:02:52.4293130Z Version: 20260824.0482.1 +2026-10-30T22:02:52.4296880Z Included Software: https://github.com/actions/runner-images/blob/macos-15/20260824.0482/images/macos/macos-15-Readme.md +2026-10-30T22:02:52.4303330Z Image Release: https://github.com/actions/runner-images/releases/tag/macos-15%2F20260824.0482 +2026-10-30T22:02:52.4305670Z ##[endgroup] +2026-10-30T22:02:52.4309950Z ##[group]GITHUB_TOKEN Permissions +2026-10-30T22:02:52.4314100Z Contents: read +2026-10-30T22:02:52.4315420Z Metadata: read +2026-10-30T22:02:52.4316970Z ##[endgroup] +2026-10-30T22:02:52.4320420Z Secret source: Actions +2026-10-30T22:02:52.4322380Z Cache mode: write +2026-10-30T22:02:52.4323940Z Prepare workflow directory +2026-10-30T22:02:52.5002820Z Prepare all required actions +2026-10-30T22:02:52.5090780Z Getting action download info +2026-10-30T22:02:52.9880850Z Download action repository 'actions/checkout@v4' (SHA:11d5960a326750d5838078e36cf38b85af677262) +2026-10-30T22:02:53.3184690Z Download action repository 'actions/setup-node@v4' (SHA:49933ea5288caeca8642d1e84afbd3f7d6820020) +2026-10-30T22:02:53.4948170Z Download action repository 'actions/upload-artifact@v4' (SHA:ea165f8d65b6e75b540449e92b4886f43607fa02) +2026-10-30T22:02:53.8757040Z Complete job name: Native signing-identity candidate (macos-15-intel) +2026-10-30T22:02:54.1005950Z ##[group]Run actions/checkout@v4 +2026-10-30T22:02:54.1007930Z with: +2026-10-30T22:02:54.1008790Z repository: CyberdyneCorp/cybercode-cli +2026-10-30T22:02:54.1018430Z token: *** +2026-10-30T22:02:54.1019400Z ssh-strict: true +2026-10-30T22:02:54.1020320Z ssh-user: git +2026-10-30T22:02:54.1021250Z persist-credentials: true +2026-10-30T22:02:54.1022570Z clean: true +2026-10-30T22:02:54.1023790Z sparse-checkout-cone-mode: true +2026-10-30T22:02:54.1024870Z fetch-depth: 1 +2026-10-30T22:02:54.1025680Z fetch-tags: false +2026-10-30T22:02:54.1026830Z show-progress: true +2026-10-30T22:02:54.1028050Z lfs: false +2026-10-30T22:02:54.1029090Z submodules: false +2026-10-30T22:02:54.1030110Z set-safe-directory: true +2026-10-30T22:02:54.1031190Z allow-unsafe-pr-checkout: false +2026-10-30T22:02:54.1033740Z ##[endgroup] +2026-10-30T22:02:54.5415550Z Syncing repository: CyberdyneCorp/cybercode-cli +2026-10-30T22:02:54.5419500Z ##[group]Getting Git version info +2026-10-30T22:02:54.5421360Z Working directory is '/Users/runner/work/cybercode-cli/cybercode-cli' +2026-10-30T22:02:54.5423700Z [command]/usr/local/bin/git version +2026-10-30T22:02:54.5424940Z git version 2.55.0 +2026-10-30T22:02:54.5429510Z ##[endgroup] +2026-10-30T22:02:54.6630550Z Copying '/Users/runner/.gitconfig' to '/Users/runner/work/_temp/7276f405-808a-4a73-9337-6d175d301f21/.gitconfig' +2026-10-30T22:02:54.6666430Z Temporarily overriding HOME='/Users/runner/work/_temp/7276f405-808a-4a73-9337-6d175d301f21' before making global git config changes +2026-10-30T22:02:54.6700040Z Adding repository directory to the temporary git global config as a safe directory +2026-10-30T22:02:54.6721060Z [command]/usr/local/bin/git config --global --add safe.directory /Users/runner/work/cybercode-cli/cybercode-cli +2026-10-30T22:02:54.6753860Z Deleting the contents of '/Users/runner/work/cybercode-cli/cybercode-cli' +2026-10-30T22:02:54.6770210Z ##[group]Initializing the repository +2026-10-30T22:02:54.6784270Z [command]/usr/local/bin/git init /Users/runner/work/cybercode-cli/cybercode-cli +2026-10-30T22:02:54.6806950Z hint: Using 'master' as the name for the initial branch. This default branch name +2026-10-30T22:02:54.6813550Z hint: will change to "main" in Git 3.0. To configure the initial branch name +2026-10-30T22:02:54.6846850Z hint: to use in all of your new repositories, which will suppress this warning, +2026-10-30T22:02:54.6877320Z hint: call: +2026-10-30T22:02:54.6924440Z hint: +2026-10-30T22:02:54.6941600Z hint: git config --global init.defaultBranch +2026-10-30T22:02:54.6963530Z hint: +2026-10-30T22:02:54.6980480Z hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and +2026-10-30T22:02:54.6990490Z hint: 'development'. The just-created branch can be renamed via this command: +2026-10-30T22:02:54.7000650Z hint: +2026-10-30T22:02:54.7026320Z hint: git branch -m +2026-10-30T22:02:54.7041100Z hint: +2026-10-30T22:02:54.7079000Z hint: Disable this message with "git config set advice.defaultBranchName false" +2026-10-30T22:02:54.7093370Z Initialized empty Git repository in /Users/runner/work/cybercode-cli/cybercode-cli/.git/ +2026-10-30T22:02:54.7150160Z [command]/usr/local/bin/git remote add origin https://github.com/CyberdyneCorp/cybercode-cli +2026-10-30T22:02:54.7188700Z ##[endgroup] +2026-10-30T22:02:54.7200910Z ##[group]Disabling automatic garbage collection +2026-10-30T22:02:54.7219510Z [command]/usr/local/bin/git config --local gc.auto 0 +2026-10-30T22:02:54.7254060Z ##[endgroup] +2026-10-30T22:02:54.7267110Z ##[group]Setting up auth +2026-10-30T22:02:54.7284540Z [command]/usr/local/bin/git config --local --name-only --get-regexp core\.sshCommand +2026-10-30T22:02:54.7338040Z [command]/usr/local/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :" +2026-10-30T22:02:54.9302530Z [command]/usr/local/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader +2026-10-30T22:02:54.9389790Z [command]/usr/local/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :" +2026-10-30T22:02:55.2295340Z [command]/usr/local/bin/git config --local --name-only --get-regexp ^includeIf\.gitdir: +2026-10-30T22:02:55.2392070Z [command]/usr/local/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url +2026-10-30T22:02:55.3536620Z [command]/usr/local/bin/git config --local http.https://github.com/.extraheader AUTHORIZATION: basic *** +2026-10-30T22:02:55.3726000Z ##[endgroup] +2026-10-30T22:02:55.3730720Z ##[group]Fetching the repository +2026-10-30T22:02:55.3757050Z [command]/usr/local/bin/git -c protocol.version=2 fetch --no-tags --prune --no-recurse-submodules --depth=1 origin +ebdb3f33d47590f23511be698fe84068b338e1ce:refs/remotes/pull/80/merge +2026-10-30T22:02:57.2707900Z From https://github.com/CyberdyneCorp/cybercode-cli +2026-10-30T22:02:57.3713030Z * [new ref] ebdb3f33d47590f23511be698fe84068b338e1ce -> pull/80/merge +2026-10-30T22:02:57.5664140Z ##[endgroup] +2026-10-30T22:02:57.6669960Z ##[group]Determining the checkout info +2026-10-30T22:02:57.7674810Z ##[endgroup] +2026-10-30T22:02:57.8344680Z [command]/usr/local/bin/git sparse-checkout disable +2026-10-30T22:02:57.8677960Z [command]/usr/local/bin/git config --local --unset-all extensions.worktreeConfig +2026-10-30T22:02:57.8982970Z ##[group]Checking out the ref +2026-10-30T22:02:57.9034020Z [command]/usr/local/bin/git checkout --progress --force refs/remotes/pull/80/merge +2026-10-30T22:02:58.3234470Z Updating files: 31% (1223/3889) +2026-10-30T22:02:58.4473870Z Updating files: 32% (1245/3889) +2026-10-30T22:02:58.4889580Z Updating files: 33% (1284/3889) +2026-10-30T22:02:58.5127090Z Updating files: 34% (1323/3889) +2026-10-30T22:02:58.5270100Z Updating files: 35% (1362/3889) +2026-10-30T22:02:58.5402470Z Updating files: 36% (1401/3889) +2026-10-30T22:02:58.5543400Z Updating files: 37% (1439/3889) +2026-10-30T22:02:58.5736600Z Updating files: 38% (1478/3889) +2026-10-30T22:02:58.5952840Z Updating files: 39% (1517/3889) +2026-10-30T22:02:58.6810570Z Updating files: 40% (1556/3889) +2026-10-30T22:02:58.7415050Z Updating files: 41% (1595/3889) +2026-10-30T22:02:58.8452710Z Updating files: 42% (1634/3889) +2026-10-30T22:02:58.9496200Z Updating files: 43% (1673/3889) +2026-10-30T22:02:58.9801790Z Updating files: 44% (1712/3889) +2026-10-30T22:02:58.9838970Z Updating files: 45% (1751/3889) +2026-10-30T22:02:59.0012020Z Updating files: 46% (1789/3889) +2026-10-30T22:02:59.0147800Z Updating files: 47% (1828/3889) +2026-10-30T22:02:59.0387500Z Updating files: 48% (1867/3889) +2026-10-30T22:02:59.0487830Z Updating files: 49% (1906/3889) +2026-10-30T22:02:59.0904590Z Updating files: 50% (1945/3889) +2026-10-30T22:02:59.1665480Z Updating files: 51% (1984/3889) +2026-10-30T22:02:59.1959940Z Updating files: 52% (2023/3889) +2026-10-30T22:02:59.2146500Z Updating files: 53% (2062/3889) +2026-10-30T22:02:59.2329570Z Updating files: 54% (2101/3889) +2026-10-30T22:02:59.2895150Z Updating files: 55% (2139/3889) +2026-10-30T22:02:59.3088030Z Updating files: 56% (2178/3889) +2026-10-30T22:02:59.3602210Z Updating files: 56% (2184/3889) +2026-10-30T22:02:59.4308920Z Updating files: 57% (2217/3889) +2026-10-30T22:02:59.4403820Z Updating files: 58% (2256/3889) +2026-10-30T22:02:59.4511850Z Updating files: 59% (2295/3889) +2026-10-30T22:02:59.4642320Z Updating files: 60% (2334/3889) +2026-10-30T22:02:59.4744350Z Updating files: 61% (2373/3889) +2026-10-30T22:02:59.4885800Z Updating files: 62% (2412/3889) +2026-10-30T22:02:59.4975980Z Updating files: 63% (2451/3889) +2026-10-30T22:02:59.5148630Z Updating files: 64% (2489/3889) +2026-10-30T22:02:59.5249000Z Updating files: 65% (2528/3889) +2026-10-30T22:02:59.5388920Z Updating files: 66% (2567/3889) +2026-10-30T22:02:59.5560970Z Updating files: 67% (2606/3889) +2026-10-30T22:02:59.5744160Z Updating files: 68% (2645/3889) +2026-10-30T22:02:59.5985320Z Updating files: 69% (2684/3889) +2026-10-30T22:02:59.6133470Z Updating files: 70% (2723/3889) +2026-10-30T22:02:59.6344040Z Updating files: 71% (2762/3889) +2026-10-30T22:02:59.6753840Z Updating files: 72% (2801/3889) +2026-10-30T22:02:59.8594970Z Updating files: 73% (2839/3889) +2026-10-30T22:02:59.9599380Z Updating files: 74% (2878/3889) +2026-10-30T22:03:00.0191470Z Updating files: 75% (2917/3889) +2026-10-30T22:03:00.0427880Z Updating files: 76% (2956/3889) +2026-10-30T22:03:00.0520500Z Updating files: 77% (2995/3889) +2026-10-30T22:03:00.1692540Z Updating files: 78% (3034/3889) +2026-10-30T22:03:00.2658800Z Updating files: 79% (3073/3889) +2026-10-30T22:03:00.3749530Z Updating files: 80% (3112/3889) +2026-10-30T22:03:00.4089120Z Updating files: 80% (3123/3889) +2026-10-30T22:03:00.4157810Z Updating files: 81% (3151/3889) +2026-10-30T22:03:00.4218560Z Updating files: 82% (3189/3889) +2026-10-30T22:03:00.4314050Z Updating files: 83% (3228/3889) +2026-10-30T22:03:00.4369100Z Updating files: 84% (3267/3889) +2026-10-30T22:03:00.4514160Z Updating files: 85% (3306/3889) +2026-10-30T22:03:00.5071250Z Updating files: 86% (3345/3889) +2026-10-30T22:03:00.5352090Z Updating files: 87% (3384/3889) +2026-10-30T22:03:00.5758250Z Updating files: 88% (3423/3889) +2026-10-30T22:03:00.5913980Z Updating files: 89% (3462/3889) +2026-10-30T22:03:00.6061880Z Updating files: 90% (3501/3889) +2026-10-30T22:03:00.6217930Z Updating files: 91% (3539/3889) +2026-10-30T22:03:00.6368330Z Updating files: 92% (3578/3889) +2026-10-30T22:03:00.6527850Z Updating files: 93% (3617/3889) +2026-10-30T22:03:00.6726630Z Updating files: 94% (3656/3889) +2026-10-30T22:03:00.6870680Z Updating files: 95% (3695/3889) +2026-10-30T22:03:00.7042960Z Updating files: 96% (3734/3889) +2026-10-30T22:03:00.7305810Z Updating files: 97% (3773/3889) +2026-10-30T22:03:00.7567200Z Updating files: 98% (3812/3889) +2026-10-30T22:03:00.7880660Z Updating files: 99% (3851/3889) +2026-10-30T22:03:00.7911050Z Updating files: 100% (3889/3889) +2026-10-30T22:03:00.7940340Z Updating files: 100% (3889/3889), done. +2026-10-30T22:03:00.8165490Z HEAD is now at ebdb3f3 Merge 08ee6fe6eb932a3926470f3c113257b97aa26b2d into ec31ff9fc7627a3a9262d99f0fc0606394368423 +2026-10-30T22:03:00.8295060Z ##[endgroup] +2026-10-30T22:03:00.8467400Z [command]/usr/local/bin/git log -1 --format=%H +2026-10-30T22:03:00.8605330Z ebdb3f33d47590f23511be698fe84068b338e1ce +2026-10-30T22:03:00.9213530Z ##[group]Run actions/setup-node@v4 +2026-10-30T22:03:00.9214240Z with: +2026-10-30T22:03:00.9214710Z node-version: 22 +2026-10-30T22:03:00.9215260Z always-auth: false +2026-10-30T22:03:00.9215810Z check-latest: false +2026-10-30T22:03:00.9223930Z token: *** +2026-10-30T22:03:00.9224460Z ##[endgroup] +2026-10-30T22:03:01.2868930Z (node:2328) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead. +2026-10-30T22:03:01.2918540Z (Use `node --trace-deprecation ...` to show where the warning was created) +2026-10-30T22:03:01.3597040Z Found in cache @ /Users/runner/hostedtoolcache/node/22.23.2/x64 +2026-10-30T22:03:01.3712780Z ##[group]Environment details +2026-10-30T22:03:04.8035020Z node: v22.23.2 +2026-10-30T22:03:04.8116560Z npm: 10.9.8 +2026-10-30T22:03:04.8145750Z yarn: 1.22.22 +2026-10-30T22:03:04.8190740Z ##[endgroup] +2026-10-30T22:03:04.8486660Z ##[group]Run set -euo pipefail +2026-10-30T22:03:04.8489510Z set -euo pipefail +2026-10-30T22:03:04.8490780Z # Acceptance requires original-image positive startup, denied self-exec, +2026-10-30T22:03:04.8492460Z # matching-identity counterexamples and descriptor isolation. +2026-10-30T22:03:04.8493980Z # The historical re-signing experiment remains an opt-in diagnostic; +2026-10-30T22:03:04.8495980Z # its failed startup control is never counted as confinement. +2026-10-30T22:03:04.8499290Z node --experimental-strip-types scripts/probes/plugin-confinement/run.mts --runtime native --macos-signing-native --macos-private-unix --report "$RUNNER_TEMP/matrix.json" > "$RUNNER_TEMP/matrix.log" 2>&1 +2026-10-30T22:03:04.8503530Z node --experimental-strip-types scripts/probes/plugin-confinement/macos_signing_exec.mts --report "$RUNNER_TEMP/exec.json" > "$RUNNER_TEMP/exec.log" 2>&1 +2026-10-30T22:03:04.8678340Z shell: /bin/bash --noprofile --norc -e -o pipefail {0} +2026-10-30T22:03:04.8679730Z ##[endgroup] +2026-10-30T22:03:11.8817160Z ##[group]Run set -euo pipefail +2026-10-30T22:03:11.8818170Z set -euo pipefail +2026-10-30T22:03:11.8819260Z control="$RUNNER_TEMP/macos-private-unix-missing-grant" +2026-10-30T22:03:11.8820920Z python3 - "$control" <<'PYCONTROL' +2026-10-30T22:03:11.8821570Z from pathlib import Path +2026-10-30T22:03:11.8822140Z import shutil, sys +2026-10-30T22:03:11.8822660Z target = Path(sys.argv[1]) +2026-10-30T22:03:11.8824220Z shutil.copytree('scripts/probes/plugin-confinement', target, ignore=shutil.ignore_patterns('evidence', '__pycache__')) +2026-10-30T22:03:11.8825670Z driver = target / 'macos_policy.mts' +2026-10-30T22:03:11.8826310Z text = driver.read_text() +2026-10-30T22:03:11.8826880Z before = ' if (privateUnix) {' +2026-10-30T22:03:11.8827480Z assert text.count(before) == 1 +2026-10-30T22:03:11.8828690Z driver.write_text(text.replace(before, ' if (false) { // Missing scratch UNIX grant control.')) +2026-10-30T22:03:11.8829740Z PYCONTROL +2026-10-30T22:03:11.8830330Z log="$RUNNER_TEMP/private-unix-missing-grant.log" +2026-10-30T22:03:11.8832140Z if node --experimental-strip-types "$control/run.mts" --runtime native --macos-signing-native --macos-private-unix --report "$control/result.json" > "$log" 2>&1; then +2026-10-30T22:03:11.8834020Z  echo 'Missing private UNIX policy unexpectedly passed' >&2 +2026-10-30T22:03:11.8834800Z  exit 1 +2026-10-30T22:03:11.8835210Z fi +2026-10-30T22:03:11.8836320Z python3 - "$log" <<'PYCONTROL' +2026-10-30T22:03:11.8836920Z from pathlib import Path +2026-10-30T22:03:11.8837460Z import sys +2026-10-30T22:03:11.8837950Z text = Path(sys.argv[1]).read_text() +2026-10-30T22:03:11.8839020Z assert 'no-capabilities: private UNIX runtime exchange failed: [false,false]' in text, text +2026-10-30T22:03:11.8840270Z PYCONTROL +2026-10-30T22:03:11.8917690Z shell: /bin/bash --noprofile --norc -e -o pipefail {0} +2026-10-30T22:03:11.8918390Z ##[endgroup] +2026-10-30T22:03:13.1878030Z ##[group]Run set -euo pipefail +2026-10-30T22:03:13.1878740Z set -euo pipefail +2026-10-30T22:03:13.1880400Z node --experimental-strip-types scripts/probes/plugin-confinement/macos_private_ipc.mts --report "$RUNNER_TEMP/unix-boundary.json" > "$RUNNER_TEMP/unix-boundary.log" 2>&1 +2026-10-30T22:03:13.1882280Z log="$RUNNER_TEMP/unix-missing-scope.log" +2026-10-30T22:03:13.1883730Z if node --experimental-strip-types scripts/probes/plugin-confinement/macos_private_ipc.mts --missing-scope > "$log" 2>&1; then +2026-10-30T22:03:13.1885380Z  echo 'Missing UNIX outbound scope unexpectedly passed' >&2 +2026-10-30T22:03:13.1886150Z  exit 1 +2026-10-30T22:03:13.1886560Z fi +2026-10-30T22:03:13.1886990Z python3 - "$log" <<'PYCONTROL' +2026-10-30T22:03:13.1887600Z from pathlib import Path +2026-10-30T22:03:13.1888130Z import sys +2026-10-30T22:03:13.1888730Z text = Path(sys.argv[1]).read_text() +2026-10-30T22:03:13.1889580Z assert 'macOS datagram endpoint escaped scratch:' in text, text +2026-10-30T22:03:13.1890400Z import json, re +2026-10-30T22:03:13.1891220Z match = re.search(r'macOS datagram endpoint escaped scratch: (\{[^\n]+\})', text) +2026-10-30T22:03:13.1892180Z assert match, text +2026-10-30T22:03:13.1892670Z entry = json.loads(match[1]) +2026-10-30T22:03:13.1893310Z race = entry['observed']['datagram_race'] +2026-10-30T22:03:13.1894300Z assert race['host_control'] and race['settled'] and not race['failed'], entry +2026-10-30T22:03:13.1895440Z assert entry['datagram_receipts'] == 7 + race['host_acks'], entry +2026-10-30T22:03:13.1896500Z for token in ['"owner_received_fixture":true', '"acknowledged":true', +2026-10-30T22:03:13.1897740Z  '"owner_datagram_received_fixture":true', '"private_datagram":[true,true,true]', +2026-10-30T22:03:13.1898980Z  '"private_aliases":[true,true]', '"private_peer_matches":true']: +2026-10-30T22:03:13.1899860Z  assert token in text, text +2026-10-30T22:03:13.1900430Z PYCONTROL +2026-10-30T22:03:13.1965520Z shell: /bin/bash --noprofile --norc -e -o pipefail {0} +2026-10-30T22:03:13.1966210Z ##[endgroup] +2026-10-30T22:03:14.0614850Z ##[error]Process completed with exit code 1. +2026-10-30T22:03:14.1217420Z ##[group]Run actions/upload-artifact@v4 +2026-10-30T22:03:14.1218270Z with: +2026-10-30T22:03:14.1218750Z name: native-signing-candidate-macos-15-intel +2026-10-30T22:03:14.1222920Z path: /Users/runner/work/_temp/matrix.json +/Users/runner/work/_temp/matrix.log +/Users/runner/work/_temp/private-unix-missing-grant.log +/Users/runner/work/_temp/unix-boundary.json +/Users/runner/work/_temp/unix-boundary.log +/Users/runner/work/_temp/unix-missing-scope.log +/Users/runner/work/_temp/unix-dropped-rights.log +/Users/runner/work/_temp/unix-rights-path-reader.log +/Users/runner/work/_temp/exec.json +/Users/runner/work/_temp/exec.log + +2026-10-30T22:03:14.1227660Z if-no-files-found: error +2026-10-30T22:03:14.1228150Z retention-days: 14 +2026-10-30T22:03:14.1228650Z compression-level: 6 +2026-10-30T22:03:14.1229130Z overwrite: false +2026-10-30T22:03:14.1229750Z include-hidden-files: false +2026-10-30T22:03:14.1230260Z ##[endgroup] +2026-10-30T22:03:14.4570960Z (node:2666) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead. +2026-10-30T22:03:14.4588150Z (Use `node --trace-deprecation ...` to show where the warning was created) +2026-10-30T22:03:14.5147660Z Multiple search paths detected. Calculating the least common ancestor of all paths +2026-10-30T22:03:14.5271620Z The least common ancestor is /Users/runner/work/_temp. This will be the root directory of the artifact +2026-10-30T22:03:14.5277540Z With the provided path, there will be 6 files uploaded +2026-10-30T22:03:14.5291390Z Artifact name is valid! +2026-10-30T22:03:14.5292350Z Root directory input is valid! +2026-10-30T22:03:14.9570430Z Beginning upload of artifact content to blob storage +2026-10-30T22:03:15.0371100Z (node:2666) [DEP0169] DeprecationWarning: `url.parse()` behavior is not standardized and prone to errors that have security implications. Use the WHATWG URL API instead. CVEs are not issued for `url.parse()` vulnerabilities. +2026-10-30T22:03:15.3337580Z Uploaded bytes 6355 +2026-10-30T22:03:15.4144990Z Finished uploading artifact content to blob storage! +2026-10-30T22:03:15.4155660Z SHA256 digest of uploaded artifact zip is 24c3a99bbff97fba00dd1a977ceb5fc6ebd14b3110f6ec9b4a3cc3e807a0f654 +2026-10-30T22:03:15.4157170Z Finalizing artifact upload +2026-10-30T22:03:15.9749220Z Artifact native-signing-candidate-macos-15-intel.zip successfully finalized. Artifact ID 13015572224 +2026-10-30T22:03:15.9758930Z Artifact native-signing-candidate-macos-15-intel has been successfully uploaded! Final size is 6355 bytes. Artifact ID is 13015572224 +2026-10-30T22:03:15.9865070Z Artifact download URL: https://github.com/CyberdyneCorp/cybercode-cli/actions/runs/41119882444/artifacts/13015572224 +2026-10-30T22:03:16.1055130Z Post job cleanup. +2026-10-30T22:03:16.3043530Z [command]/usr/local/bin/git version +2026-10-30T22:03:16.3142540Z git version 2.55.0 +2026-10-30T22:03:16.3179840Z Copying '/Users/runner/.gitconfig' to '/Users/runner/work/_temp/0eca3df1-d668-4cfa-af87-84ed0402681e/.gitconfig' +2026-10-30T22:03:16.3196120Z Temporarily overriding HOME='/Users/runner/work/_temp/0eca3df1-d668-4cfa-af87-84ed0402681e' before making global git config changes +2026-10-30T22:03:16.3198500Z Adding repository directory to the temporary git global config as a safe directory +2026-10-30T22:03:16.3204890Z [command]/usr/local/bin/git config --global --add safe.directory /Users/runner/work/cybercode-cli/cybercode-cli +2026-10-30T22:03:16.3322400Z [command]/usr/local/bin/git config --local --name-only --get-regexp core\.sshCommand +2026-10-30T22:03:16.3413040Z [command]/usr/local/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :" +2026-10-30T22:03:16.4658730Z [command]/usr/local/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader +2026-10-30T22:03:16.4741020Z http.https://github.com/.extraheader +2026-10-30T22:03:16.4753800Z [command]/usr/local/bin/git config --local --unset-all http.https://github.com/.extraheader +2026-10-30T22:03:16.4855350Z [command]/usr/local/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :" +2026-10-30T22:03:16.6374730Z [command]/usr/local/bin/git config --local --name-only --get-regexp ^includeIf\.gitdir: +2026-10-30T22:03:16.6466020Z [command]/usr/local/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url +2026-10-30T22:03:16.7771960Z Cleaning up orphan processes +2026-10-30T22:03:16.9305080Z ##[warning]Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@v4, actions/setup-node@v4, actions/upload-artifact@v4. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/ diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/matrix.json b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/matrix.json new file mode 100644 index 000000000..02f9e4fa4 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/matrix.json @@ -0,0 +1,547 @@ +{ + "recorded_at": "2026-10-30T22:03:10.478Z", + "kernel_release": "24.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_datagram.h", + "macos_datagram_race.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "05c2c5808004a944c2582857a16df3f4a2266abbe5911d68886c36aeebd3b5ad", + "platform": "darwin", + "architecture": "x64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.9d8b4362-0ff6-4247-826b-f9a60dc2219a", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/matrix.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/matrix.log new file mode 100644 index 000000000..02f9e4fa4 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/matrix.log @@ -0,0 +1,547 @@ +{ + "recorded_at": "2026-10-30T22:03:10.478Z", + "kernel_release": "24.6.0", + "sources": [ + "run.mts", + "macos_policy.mts", + "macos_rights.h", + "macos_datagram.h", + "macos_datagram_race.h", + "macos_python.c", + "macos_node.c", + "native_exec.c", + "node_bootstrap.cjs", + "fixture.py", + "fixture.cjs", + "private_unix.cjs", + "process_policy.h", + "linux_filter.h", + "linux_exec.c", + "linux_initial_exec.h", + "fixture_native.c", + "macos_exec.c", + "macos_stage.mts" + ], + "source_sha256": "05c2c5808004a944c2582857a16df3f4a2266abbe5911d68886c36aeebd3b5ad", + "platform": "darwin", + "architecture": "x64", + "runtime": "native", + "version": "fixture-v2", + "signing_identifier": "com.cyberdyne.probe.bootstrap.9d8b4362-0ff6-4247-826b-f9a60dc2219a", + "socket_broker_candidate": false, + "private_stream_candidate": false, + "macos_private_unix_candidate": true, + "mechanism": "fresh signing identifier on trusted launcher + exact-target Seatbelt exec rule before any runtime instruction; target signature unchanged; experimental subject-identity candidate", + "limitation": "experimental native mechanisms; macOS uses deprecated Seatbelt API; not production packaging or Windows acceptance", + "unsupported_cases": [], + "rows": [ + { + "name": "unconfined-control", + "flags": { + "read": true, + "write": true, + "shell": true, + "unrestricted": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": true, + "private_list": true, + "private_write": true, + "protected_read": true, + "protected_write": true, + "symlink_private_read": true, + "hardlink_private": true, + "project_rename": true, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": true, + "package_alias_write": true, + "thread_reads": [ + true, + true + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + true + ], + "native_child_reads": [ + true, + true + ], + "cannot_relax": null, + "constructor_private_read": true, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "no-capabilities", + "flags": { + "read": false, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-only", + "flags": { + "read": true, + "write": false, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "write-without-read", + "flags": { + "read": false, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "shell-without-read", + "flags": { + "read": false, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "read-write-without-shell", + "flags": { + "read": true, + "write": true, + "shell": false + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": false, + "shell": false, + "native_fork": false, + "child_reads": null, + "native_child_reads": null, + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": false, + "native_spawn": false, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": false, + "constructor_self_exec": false, + "constructor_spawn": false + }, + { + "name": "read-shell-without-write", + "flags": { + "read": true, + "write": false, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": false, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "write-shell-without-read", + "flags": { + "read": false, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": false, + "project_list": false, + "project_write": true, + "written_project_read": false, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + false, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + false, + false + ], + "native_child_reads": [ + false, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + }, + { + "name": "declared-read-write-shell", + "flags": { + "read": true, + "write": true, + "shell": true + }, + "observations": { + "stdio_tool": true, + "package_read": true, + "scratch_write": true, + "scratch_read": true, + "project_read": true, + "project_list": true, + "project_write": true, + "written_project_read": true, + "private_read": false, + "private_list": false, + "private_write": false, + "protected_read": false, + "protected_write": false, + "symlink_private_read": false, + "hardlink_private": false, + "project_rename": false, + "inherited_descriptor": false, + "thread": true, + "package_hardlink": false, + "package_alias_write": false, + "thread_reads": [ + true, + false + ], + "thread_shell": true, + "shell": true, + "native_fork": true, + "child_reads": [ + true, + false + ], + "native_child_reads": [ + true, + false + ], + "cannot_relax": true, + "constructor_private_read": false, + "constructor_fork": true, + "native_spawn": true, + "platform_status_known": true, + "platform_before": false, + "platform_after_set": false, + "private_unix": [ + true, + true + ] + }, + "self_exec": true, + "constructor_self_exec": true, + "constructor_spawn": true + } + ] +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/private-unix-missing-grant.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/private-unix-missing-grant.log new file mode 100644 index 000000000..fa1873517 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/private-unix-missing-grant.log @@ -0,0 +1,31 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: no-capabilities: private UNIX runtime exchange failed: [false,false] ++ actual - expected + + [ ++ false, ++ false +- true, +- true + ] + + at check (file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:298:12) + at file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:402:31 + at Array.map () + at main (file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:402:8) + at file:///Users/runner/work/_temp/macos-private-unix-missing-grant/run.mts:425:1 + at ModuleJob.run (node:internal/modules/esm/module_job:343:25) + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:681:26) + at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:117:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: [ false, false ], + expected: [ true, true ], + operator: 'deepStrictEqual', + diff: 'simple' +} + +Node.js v22.23.2 diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/source-binding.json b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/source-binding.json new file mode 100644 index 000000000..bb46eb055 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/source-binding.json @@ -0,0 +1,21 @@ +{ + "run_id": 41119882444, + "job_id": 124283606909, + "artifact_id": 13015572224, + "artifact_sha256": "24c3a99bbff97fba00dd1a977ceb5fc6ebd14b3110f6ec9b4a3cc3e807a0f654", + "head": "08ee6fe6eb932a3926470f3c113257b97aa26b2d", + "tested_merge": "ebdb3f33d47590f23511be698fe84068b338e1ce", + "base": "ec31ff9fc7627a3a9262d99f0fc0606394368423", + "tree": "b10649b8f6ca411a8506705bbe88f8bc9d5ca44b", + "result": "failure", + "scope": "Intel Darwin native datagram race; incomplete row is a failure, not denial evidence.", + "files": { + "exec.json": "54c4668f40492f18c104a4f5beecdabcac14b9507bd2da9d3e09b008399a1efe", + "exec.log": "54c4668f40492f18c104a4f5beecdabcac14b9507bd2da9d3e09b008399a1efe", + "job.log": "a54d7bbc34b920a0c788cb1b4a5a79025b0e827d074bd94e84833f3901ffb298", + "matrix.json": "df65e1d727190e5dc6c7d778eecb450cd6f63c05b2859332c4977a2a403cf0b7", + "matrix.log": "df65e1d727190e5dc6c7d778eecb450cd6f63c05b2859332c4977a2a403cf0b7", + "private-unix-missing-grant.log": "f803d3e97f09d5b75b95e7d4c1d32ca7590328132d3e29e2bbfd11647fbdf278", + "unix-boundary.log": "3b5bba5357500a5f04e83e986676632e739a46f178b52114b7aae3f535eba14e" + } +} diff --git a/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/unix-boundary.log b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/unix-boundary.log new file mode 100644 index 000000000..b42aa5c56 --- /dev/null +++ b/scripts/probes/plugin-confinement/evidence/macos-datagram-intel-08ee6fe6/unix-boundary.log @@ -0,0 +1,20 @@ +node:internal/modules/run_main:123 + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: datagram mutation failed: {"name":"r0w1s1","flags":{"read":false,"write":true,"shell":true},"observed":{"started":true,"private_unix":[true,true],"private_peer_checks":8,"private_peer_matches":true,"hardlink_created":false,"symlink_created":true,"private_aliases":[true,true],"rights":{"sent":true,"original_closed":true,"token":true,"truncated":false,"received":true,"same_inode":true,"readable":true,"written":true,"cloexec":true},"rights_path_replaced":true,"private_datagram":[true,true,true],"datagram_symlink_created":true,"datagram_race":{"private_control":true,"host_control":false,"settled":true,"failed":true,"attempts":3,"private_acks":1,"host_acks":0,"refused":1,"swaps":4},"dgram_connect":{"connected":false,"sent":false,"acknowledged":false},"dgram_sendto":{"connected":false,"sent":false,"acknowledged":false},"dgram_sendmsg":{"connected":false,"sent":false,"acknowledged":false},"dgram_alias_connect":{"connected":false,"sent":false,"acknowledged":false},"dgram_alias_sendto":{"connected":false,"sent":false,"acknowledged":false},"dgram_alias_sendmsg":{"connected":false,"sent":false,"acknowledged":false},"direct":{"connected":false,"sent":false,"acknowledged":false},"hardlink":{"connected":false,"sent":false,"acknowledged":false},"symlink":{"connected":false,"sent":false,"acknowledged":false}},"rights_payload":"AB","rights_link_count":0,"owner_receipts":0,"owner_received_fixture":false,"datagram_receipts":0,"owner_datagram_received_fixture":false} + +true !== false + + at check (file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:140:10) + at file:///Users/runner/work/cybercode-cli/cybercode-cli/scripts/probes/plugin-confinement/macos_private_ipc.mts:192:5 + at process.processTicksAndRejections (node:internal/process/task_queues:103:5) { + generatedMessage: false, + code: 'ERR_ASSERTION', + actual: true, + expected: false, + operator: 'strictEqual', + diff: 'simple' +} + +Node.js v22.23.2 diff --git a/scripts/probes/plugin-confinement/macos_datagram_race.h b/scripts/probes/plugin-confinement/macos_datagram_race.h index b29b25f61..69341f4ea 100644 --- a/scripts/probes/plugin-confinement/macos_datagram_race.h +++ b/scripts/probes/plugin-confinement/macos_datagram_race.h @@ -6,7 +6,7 @@ struct datagram_mutator { const char *alias, *temporary, *private_path, *host; - atomic_int stop, failed; + atomic_int stop, failed, error; atomic_uint swaps; }; @@ -16,6 +16,7 @@ static void *replace_datagram_alias(void *value) { for (unsigned i = 0; i < 4096 && !atomic_load(&state->stop); ++i) { const char *target = i % 2 ? state->private_path : state->host; if (symlink(target, state->temporary) != 0 || rename(state->temporary, state->alias) != 0) { + atomic_store(&state->error, errno); atomic_store(&state->failed, 1); break; } atomic_fetch_add(&state->swaps, 1); @@ -35,24 +36,41 @@ static int await_datagram_swap(struct datagram_mutator *state, unsigned previous return 1; } +struct datagram_failure { const char *stage; int error; }; + +static char datagram_failed(struct datagram_failure *failure, const char *stage, int error) { + if (!failure->stage) { failure->stage = stage; failure->error = error; } + return 'E'; +} + /* Returns P for an actual private acknowledgement, A for the owned host, * D for a policy refusal and E for any invalid/unknown exchange. */ -static char datagram_race_exchange(int server, const char *scratch, const char *alias, int method) { +static char datagram_race_exchange(int server, const char *scratch, const char *alias, int method, + struct datagram_failure *failure) { char client_path[PATH_MAX], token[13], ack = 0; - if (!joined(client_path, scratch, "dgram-client.sock")) return 'E'; + if (!joined(client_path, scratch, "dgram-client.sock")) return datagram_failed(failure, "client_path", ENAMETOOLONG); int client = datagram_socket(client_path); - if (client < 0) return 'E'; + if (client < 0) return datagram_failed(failure, "client_bind", errno); struct unix_attempt sent = datagram_send(client, alias, method); int send_error = errno; if (!sent.sent) { - ack = send_error == EACCES || send_error == EPERM ? 'D' : 'E'; + ack = send_error == EACCES || send_error == EPERM ? 'D' : datagram_failed(failure, "send", send_error); } else { ssize_t size = recv(server, token, sizeof(token), MSG_DONTWAIT); if (size == 12 && memcmp(token, "fixture-only", 12) == 0) { struct sockaddr_un reply; - if (!datagram_address(client_path, &reply) || sendto(server, "P", 1, 0, (struct sockaddr *)&reply, sizeof(reply)) != 1) goto done; - } else if (size >= 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) goto done; - if (recv(client, &ack, 1, 0) != 1 || (ack != 'P' && ack != 'A')) ack = 'E'; + if (!datagram_address(client_path, &reply)) { + ack = datagram_failed(failure, "private_reply_path", ENAMETOOLONG); goto done; + } + if (sendto(server, "P", 1, 0, (struct sockaddr *)&reply, sizeof(reply)) != 1) { + ack = datagram_failed(failure, "private_reply", errno); goto done; + } + } else if (size >= 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) { + ack = datagram_failed(failure, "private_receive", size < 0 ? errno : EPROTO); goto done; + } + ssize_t received = recv(client, &ack, 1, 0); + if (received != 1 || (ack != 'P' && ack != 'A')) + ack = datagram_failed(failure, "ack_receive", received < 0 ? errno : EPROTO); } done: close(client); unlink(client_path); @@ -62,24 +80,32 @@ static char datagram_race_exchange(int server, const char *scratch, const char * struct datagram_race_result { int private_control, host_control, settled, failed, attempts, private_acks, host_acks, refused; unsigned swaps; + struct datagram_failure failure; }; static struct datagram_race_result datagram_race(const char *scratch, const char *host) { struct datagram_race_result result = {0}; char server_path[PATH_MAX], alias[PATH_MAX], temporary[PATH_MAX]; if (!joined(server_path, scratch, "dgram-race-private.sock") || !joined(alias, scratch, "dgram-race.sock") || - !joined(temporary, scratch, "dgram-race-next.sock")) return result; + !joined(temporary, scratch, "dgram-race-next.sock")) { + datagram_failed(&result.failure, "server_paths", ENAMETOOLONG); return result; + } int server = datagram_socket(server_path); - if (server < 0) return result; - if (symlink(server_path, alias) != 0) goto done; - result.private_control = datagram_race_exchange(server, scratch, alias, 1) == 'P'; + if (server < 0) { datagram_failed(&result.failure, "server_bind", errno); return result; } + if (symlink(server_path, alias) != 0) { datagram_failed(&result.failure, "private_alias", errno); goto done; } + result.private_control = datagram_race_exchange(server, scratch, alias, 1, &result.failure) == 'P'; if (!result.private_control) goto done; struct datagram_mutator state = { .alias = alias, .temporary = temporary, .private_path = server_path, .host = host }; - atomic_init(&state.stop, 0); atomic_init(&state.failed, 0); atomic_init(&state.swaps, 0); + atomic_init(&state.stop, 0); atomic_init(&state.failed, 0); atomic_init(&state.error, 0); atomic_init(&state.swaps, 0); pthread_t thread; - if (pthread_create(&thread, NULL, replace_datagram_alias, &state) != 0) goto done; + int started = pthread_create(&thread, NULL, replace_datagram_alias, &state); + if (started != 0) { datagram_failed(&result.failure, "mutator_start", started); goto done; } for (int i = 0; i < 16; ++i) { - if (!await_datagram_swap(&state, atomic_load(&state.swaps))) { result.failed = 1; break; } - char ack = datagram_race_exchange(server, scratch, alias, 1 + i % 2); + if (!await_datagram_swap(&state, atomic_load(&state.swaps))) { + datagram_failed(&result.failure, atomic_load(&state.failed) ? "alias_replace" : "await_swap", + atomic_load(&state.failed) ? atomic_load(&state.error) : ETIMEDOUT); + result.failed = 1; break; + } + char ack = datagram_race_exchange(server, scratch, alias, 1 + i % 2, &result.failure); result.attempts++; if (ack == 'P') result.private_acks++; else if (ack == 'A') result.host_acks++; @@ -89,10 +115,13 @@ static struct datagram_race_result datagram_race(const char *scratch, const char atomic_store(&state.stop, 1); result.settled = pthread_join(thread, NULL) == 0; result.failed |= atomic_load(&state.failed); + if (atomic_load(&state.failed)) datagram_failed(&result.failure, "alias_replace", atomic_load(&state.error)); result.swaps = atomic_load(&state.swaps); if (!result.settled) _exit(2); /* Do not release stack/path ownership under a live thread. */ - if (symlink(host, temporary) != 0 || rename(temporary, alias) != 0) { result.failed = 1; goto done; } - char ack = datagram_race_exchange(server, scratch, alias, 2); + if (symlink(host, temporary) != 0 || rename(temporary, alias) != 0) { + datagram_failed(&result.failure, "host_alias", errno); result.failed = 1; goto done; + } + char ack = datagram_race_exchange(server, scratch, alias, 2, &result.failure); result.host_control = ack == 'A'; if (ack != 'A' && ack != 'D') result.failed = 1; done: @@ -102,8 +131,10 @@ static struct datagram_race_result datagram_race(const char *scratch, const char static void print_datagram_race(struct datagram_race_result result) { printf(",\"datagram_race\":{\"private_control\":%s,\"host_control\":%s,\"settled\":%s,\"failed\":%s," - "\"attempts\":%d,\"private_acks\":%d,\"host_acks\":%d,\"refused\":%d,\"swaps\":%u}", + "\"attempts\":%d,\"private_acks\":%d,\"host_acks\":%d,\"refused\":%d,\"swaps\":%u," + "\"failure_stage\":\"%s\",\"failure_errno\":%d}", truth(result.private_control), truth(result.host_control), truth(result.settled), truth(result.failed), - result.attempts, result.private_acks, result.host_acks, result.refused, result.swaps); + result.attempts, result.private_acks, result.host_acks, result.refused, result.swaps, + result.failure.stage ? result.failure.stage : "", result.failure.error); } #endif diff --git a/scripts/probes/plugin-confinement/macos_private_ipc.mts b/scripts/probes/plugin-confinement/macos_private_ipc.mts index 0582c29ca..589c2f2c7 100644 --- a/scripts/probes/plugin-confinement/macos_private_ipc.mts +++ b/scripts/probes/plugin-confinement/macos_private_ipc.mts @@ -135,9 +135,11 @@ function check(entry: Awaited>) { assert.deepEqual(entry.observed.private_datagram, [true, true, true], `private datagram exchange: ${JSON.stringify(entry)}`); assert.equal(entry.observed.datagram_symlink_created, true); const race = entry.observed.datagram_race; - assert.equal(race.private_control, true); - assert.equal(race.settled, true); + assert.equal(race.private_control, true, `private datagram race control failed: ${JSON.stringify(entry)}`); + assert.equal(race.settled, true, `datagram mutator did not settle: ${JSON.stringify(entry)}`); assert.equal(race.failed, false, `datagram mutation failed: ${JSON.stringify(entry)}`); + assert.equal(race.failure_stage, ""); + assert.equal(race.failure_errno, 0); assert.equal(race.attempts, 16); assert(race.swaps >= race.attempts && race.swaps <= 4096); assert.equal(race.private_acks + race.host_acks + race.refused, race.attempts); From c9196d62675a93b21665905c27c28cd6294a43f2 Mon Sep 17 00:00:00 2001 From: Edvane Cristina Santos Daltro Date: Fri, 30 Oct 2026 19:27:41 -0400 Subject: [PATCH 20/21] Reconcile hook producer status and observation limits --- ROADMAP.md | 2 +- docs/features.md | 4 ++-- docs/local-core-guide.md | 6 ++++++ .../file-observation-implementation.md | 19 +++++++++++++------ 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index 65c2da81e..a6c1b4745 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -62,7 +62,7 @@ The first release prioritizes reliable editing, recovery and measurable coding q **Milestones** 1. **M1.1 Sandbox + modes:** **Status: in progress** (change `implement-m1-1-sandbox-modes`; implementation authorized while P0 local-model validation continues). **Acceptance (2026-10-18):** 15 of 18 P1 requirements done locally ([acceptance plan](docs/implementation/p1-acceptance-plan.md): 15 a, 2 c, 1 e; reclassified 2026-10-23). Increments 6 and 8 (profiles, environment policy, escalation, excluded commands, `sandbox.*` events, container detection, the `bypass` gate, the sandbox CLI, rule dry run, org `modes.disable`, the mode rows and the tool catalog) were demonstrated on macOS in batch B, including the escape exit criterion; Increment 15 (2026-10-18) routes Windows production dispatch through `cyber-sandbox-exec --appcontainer` (recursive roots with exclusions, grants inherited by new files, `internetClient` only for `network: on`) and finishes the PowerShell analysis (startup and parameter abbreviations, aliases, more mutating cmdlets and .NET file members); Windows enforcement and the `powershell` tool are partial (c): the AppContainer launch, ACL and isolation layers pass native Windows CI, but PowerShell 7 and Git Bash cannot start inside the AppContainer ([issue #9](https://github.com/CyberdyneCorp/cybercode-cli/issues/9)), so their native shell tests are ignored on Windows, and the Windows allowlist proxy is still open (`proxy` confines like `off`). The live auto classifier (external evidence) remains. The automated suites run on Linux (bubblewrap, including the escape exit criterion) and on native Windows in main CI ([evidence pass](docs/implementation/p1-signoff-plan.md), 2026-10-23); the manual batch scenarios ran on macOS only. The history below predates that sign-off. Extend the P0 Seatbelt / bubblewrap baseline with Windows restricted tokens and Windows network enforcement through the existing allowlist proxy; mode cycling; the auto-mode classifier backed by `model_roles.evaluator`. The evaluator foundation, Bash and initial Python/JavaScript removal guards and four-mode TUI/effective-mode state are implemented; Production auto-mode tool dispatch is implemented locally with durable allow/block/fallback decisions and preserved manual ceilings; Validated trusted auto-mode rules/policy/read-only/fallback controls are implemented locally with project trust gating and durable policy decisions; Checkout-scoped statistics/reset, confirmed one-shot replay and ancestor auto block ceilings are implemented locally. Ancestor classifier/config gates are implemented locally with parent-specific context and child billing. Literal filesystem path analysis covers file operands, directory copies/moves and implicit destinations locally, including descendant, alias and inventory checks; native acceptance and remaining option/context semantics remain open. Native AppContainer asynchronous streams and the foreground process adapter pass at `fcebb4f`; remaining interpreter proofs and complete Windows enforcement remain open. 2. **M1.2 Subagents done right:** **Status: in progress** (change `implement-m1-2-subagents-worktrees`). **Acceptance (2026-10-18):** 41 of 41 P1 requirements done locally (41 a): all 14 agents-subagents and all 9 worktrees rows, demonstrated on the real binary and server in batch A, and all 15 background-tasks rows (process Jobs, monitor, PTY, notify, send file), the `monitor` tool and the TUI tasks view and side chat (increments 7–9), demonstrated on macOS in batch B. The automated suites run on Linux and native Windows in main CI (2026-10-23 [evidence pass](docs/implementation/p1-signoff-plan.md): long-root worktree inspection and creation/reuse and cyclic-graph deletion now pass natively); the PTY tools are Unix-only and isolated-child shells on Windows are blocked by issue #9, so the milestone is not signed off natively. The history below predates that sign-off. Durable child result ownership is exclusive across runtimes and retains original target boundaries through callback and writer admission. Owned local subtree stop and idle-native cancellation are implemented with bounded acknowledgement and durable Unknown reports; Matched reopening is implemented locally with native acceptance pending; reviewed recovery, complete cross-process actor cancellation and client adoption remain open. Managed creation/reuse, primary-checkout inclusion, repository locking and journaled setup preserve user edits and interruption evidence. TUI/exec `--worktree` and API POST start fresh Sessions with live setup output. `cyber worktree list`, API GET and SDK listing report verified Git status and associated Sessions, with pending/invalid recovery diagnostics. Session creation, Drains, user shell, rewind, compaction, context repair and Session setup now claim cross-process checkout leases and persist exact creation bindings; crashed/disposed work retains unknown activity. Native Windows startup admission, runtime capability verification and low-level LPAC launch/isolation steps pass at `44f95be`; complete enforced execution remains unaccepted. Windows long-root status, summaries and ignored enumeration route through an owned read-only helper; repository, helper and actual isolated-child native steps and the full CI matrix pass at 3d2ea39. Completed Windows CI at `af9d018` passes the corrected shell fixture and model-selection coverage and fails only the mandatory long-root status assertion. All other jobs pass; newer Mode/step and foreground/structured child work still requires native acceptance. Agent model/variant defaults, starting Mode, step limits and identity pinning through preparation/tool settlement are implemented locally; fresh foreground and background children now execute with permission-before-creation, cancellation ownership, depth checks and in-process FIFO admission, including schema-governed results with one correction attempt. Foreground/background children share durable parent-scoped names. Background tasks have durable records, restart interruption, queue handback and API/SDK/TUI listing/stop controls; local children can resume by name/ID with exclusive result ownership and fresh structured attempts. Local forked children inherit history, Epoch and task context without copied execution ownership, and /fork creates an independent top-level Session. The /subtask command and authenticated API/SDK start explicit user-requested background forks while keeping the parent open. The endpoint also accepts visible named subagent profiles for fresh background children; leading TUI @mentions and agent/file completion use it. Exec leading mentions now use typed delegation with attachments, profile-capped step limits, durable child history, terminal Job following and owned cancellation. Caller-owned runtime cancellation preserves queued noninterference and settles a racing owned Job handoff. An input-bound durable admission ledger now exposes authenticated API/SDK start, lookup and stop, with pre-submission tombstones, a pre-effect launch marker and fenced unknown outcomes. Exec now retains a client request ID before submission, recovers lost responses through scoped lookup and applies its timeout/interruption to queued admission; 815 local Rust tests and workspace Clippy pass. The TUI now saves request IDs before submission, restores lookup on reconnect and offers pending-request cancellation through Esc and `/admissions`; local validation passes 57 TUI tests and workspace Clippy. Explicit cancellation now resolves abandoned reserved admissions through the durable launch fence and preserves tombstones against late host errors; 835 local Rust test executions and workspace Clippy pass, including abrupt owner-death coverage. Complete native-effect reconciliation remains required. Descendant billing now persists nested and hidden usage separately from own totals, retains surviving ancestor charges after child deletion and discloses incomplete historical backfill. Local validation passes 843 Rust executions and workspace Clippy; native acceptance is pending. Delegated exec now checks combined own/descendant cost and tokens at the recorded limit, negotiates billing capability before submission and preserves separate totals in JSON; 52 CLI test executions and workspace Clippy pass locally. Soft Session budgets now persist trusted creation defaults, activation and warning/exhaustion markers; visible and hidden provider calls, retries and web summaries check every ancestor against durable own/descendant spending. Local validation passes 870 Rust executions, followed by 57 budget/compaction/HTTP tests and workspace Clippy after error/type refinements, plus 47 SDK tests and strict specs. Native acceptance is pending. Typed budget/storage refusals now survive compaction preparation and retries; two unchanged-main regressions and all 59 focused tests plus workspace Clippy pass locally. Background Job settlement now includes durable descendant deltas with resume baselines and legacy uncertainty; 65 focused tests and workspace Clippy pass locally. Ordinary exec now observes durable subtree deltas, excludes prior history, reports attribution uncertainty and bounds interruption acknowledgement; 59 CLI tests and workspace Clippy pass locally. Descendant token-class receipts now survive deletion and expose separate class completeness in the API/SDK; 88 focused server/storage tests and workspace Clippy pass locally, with native acceptance and full cost presentation pending. TUI `/cost` now displays a refreshable subtree snapshot with token classes, cache hit rate and attribution uncertainty; all 61 TUI tests and workspace Clippy pass locally. The Session usage API and SDK now read own/descendant/combined billing from one SQL snapshot with corruption refusal and completeness flags; 43 focused server tests and 48 SDK tests pass locally. TUI cost refresh now uses the atomic usage API with strict report validation and stale-response fencing; 64 TUI tests and workspace Clippy pass locally. Completed native diagnostic CI at `553f718` still fails mandatory long-root status: staged diff succeeds, while unstaged/untracked controls fail, so a composed-command replacement is not accepted. A test-only library status candidate now covers long roots and read-only repository evidence; native results and owned sandbox integration remain pending, with production status unchanged. Generic durable prompt admission, explicit subtree cancellation with racing-admission fences, complete live client monitoring and queued/held delegation remain open. Reserved all-scope request budgets and daily accounting are now implemented for bounded official OpenAI Responses requests; see [current bounds and limits](docs/reserved-budgets.md). Fresh isolated foreground/background children, including forks and structured results, now use durable managed bindings, separate branches, source-authorized setup and file/diff summaries. Clean child removal uses checkout activity fencing; edits, ahead commits, keep policies and failed/cancelled work are retained. Retained children resume by identity after restart. Cleanup confirmation now uses child-owned routed requests, with late-policy/edit checks and cancellation cleanup. Explicit user isolated profiles now create and set up checkouts in all six Modes without widening child tool permissions; source/ancestor denies and read-only sandbox policy still refuse creation. Git-valid child names use the Session naming limit independently of storage names. Acknowledged clean removals now recreate with a new durable child binding and setup-ready gate, preserving the original base, history and branch; missing/foreign/force/incomplete evidence refuses recreation. Existing primary forks and user subtasks resume without granting fresh primary spawning. Parent-scoped API/SDK setup inspection and explicit retry now preserve successful steps, require a reviewed journal revision/recipe and fence late acknowledgements; completed journals can reconcile missing readiness without inference. Verified pre-launch preparation failures are recorded distinctly and support reviewed retry; generic/launch errors and missing acknowledgements remain unknown. Session/history streams now follow the durable Location timeline; old/new listeners receive rebound notices and the TUI applies the new action scope without allowing stale snapshots to restore the old path. Native acceptance, unknown-outcome recovery resolution and full profile configuration snapshots remain open. Child-thread API/SDK listing and TUI `/agent`/`/subagents` browsing now have local pagination, status, parent navigation and active-child steer coverage; idle child prompts now reset structured attempts atomically under exclusive execution ownership, with result-owner refusal and replay coverage; public continuation now recreates acknowledged clean removals, gates inference on source setup and owns cleanup/reporting through approval, interruption and shutdown. Local tests cover all Modes, denies, read-only refusal, edit preservation and durable unknown-settlement refusal. Explicit child inbox wake and held release now prepare verified checkouts and reset attempts atomically while preserving original input identity, edits and queue order; API/SDK wake is available. Requested child input now hands off between structured attempts after foreground collection or durable Job result/billing settlement; interruption pauses automatic intent without deleting rows. Existing-child preparation is now owned through cancellation and admission, with a durable interruption boundary, no late input/release and replay refusal for unacknowledged effects; native tests cover interrupt, disposal and shutdown locally. Fresh child launches now capture source/ancestor authority before approval/FIFO, verify native creation retries and recheck durable bindings in the writer; source interruption and explicit ancestor fences reject stale creation without child history. Delegation and owned child-preparation callbacks now retain captured authority through native awaits; writer fences cover reservation/launch, scoped input/reset and Job handoff, including request cancellation during Location admission. Missing owners cannot advance Reserved launch markers, and registered Jobs preserve ordinary parent-interrupt independence. Direct subtask callbacks now share tracked durable ownership, retain native cancellation acknowledgement after caller disposal and require reply acceptance before transferring Job ownership. Rejected handoffs stop verified Jobs; missing cancellation ownership records durable Unknown and refuses successful cancellation. Durable scope closure now refuses fresh capture and unbound writer admission across closed source/target ancestry, survives restart and later generation fences, and gates native Location waits while preserving terminal Job and shell receipts. The complete bounded actor sweep, tracked idle-native cancellation, matched reopening, detached/cross-process ownership, generic prompt admission, recovery resolution and native acceptance remain open. Public removal/prune, client attachment and process-death recovery, automatic cleanup, snapshot-safe enter/exit, recovery resolution, TUI output/artifacts and complete subagent thread continuation remain open. -3. **M1.3 Extensibility:** **Status: in progress** (change `implement-m1-3-extensibility`). **Acceptance (2026-10-18):** 48 of 53 P1 requirements done locally (48 a, 3 c, 2 e): every hooks row except Supported events, MCP (OAuth needs only native keyring evidence), SDK hook callbacks, org MCP controls, skills and commands, and VCS text, demonstrated on the real binary, server and SDK in batch A; since increment 12 the declarative plugin foundation (manifest, discovery defaults, scopes and lockfile, path/git/npm sources, `cyber plugins`, `/plugins`, digest trust, `--pure`) and the plugin hook scope; since increment 13 the sandboxed JSON-RPC plugin host (forwarded and deferred tools, crash isolation and backoff, scoped registrations, network and write capabilities, validated settings with keyring secrets) and the `@cyber-code/plugin` TypeScript kit; since increment 15 command-hook sandboxing (project and plugin hooks write only inside the workspace). Increments 12, 13 and 15 were demonstrated on macOS in batch C (real binary, `cyber serve`, Python and Node plugin hosts, local git and npm sources, TUI `/plugins`). Host-protocol hooks, providers and `session/prompt`, `fs.read`/`shell` enforcement, native keyring evidence for plugin secrets and the missing hook events remain; the Windows hook sandbox test is ignored on Windows because PowerShell 7 cannot start inside the AppContainer (issue #9); the remote MCP suites now pass on native Windows, while the local stdio MCP cases are Unix-only (2026-10-23 [evidence pass](docs/implementation/p1-signoff-plan.md)). The history below predates that sign-off. Typed hook configuration/event/handler validation is implemented locally with selector, timeout and checkout-trust tests. Loaded global/project/local hook groups now accumulate at top level and within selected profiles, retaining indexed file origins; managed/plugin collection, final execution scope order and managed-only authority remain open. Canonical handler digests, separate durable approvals in the shared checkout trust store and temporary invocation approval sets are implemented locally with cross-process storage tests. The scope-aware catalog orders resolved contributions and exposes uncached trust/sandbox requirements; CLI list/trust/untrust supports exact-digest review and obsolete revocation. Compiled subject/path/condition selectors, event-aware ordered decision parsing/merging and immutable envelope assembly are implemented locally; built-in tool command dispatch now captures invocation identity, chains rewrites and validates final input before permissions. Remaining lifecycle identity/emission, full target extraction, effectful scheduling and other handler types remain open. Owned command stream capture now supports event stdin, bounded output and explicit stop acknowledgement locally. Command result interpretation has local contract and real-process tests for JSON decisions, exit codes, timeout policy and unknown termination; Noninteractive Unix command launch has local trust-revocation, event-input/environment, mandatory sandbox and scratch-ownership tests. Recorded Unix command execution now has local durable admission/receipt, privacy and tracked subtree cancellation tests. Unix built-in PreToolUse/PostToolUse/PostToolUseFailure command dispatch now has local denial, rewrite, permission, trust and receipt tests, plus transient TUI/exec notices. Command PermissionRequest hooks now answer individual asks without saved approvals and retain hard denials/Mode limits. Fixed-input request/post events now use bounded command concurrency with immediate slot reuse, declared-order merging and acknowledged sibling cancellation; rewrite-dependent pre-tool scheduling remains open. Command once-per-Session claims now persist atomically with receipt admission and survive concurrent runtimes, restart and unknown settlement; status/completion messages are user-only notices. Authenticated Session receipt pagination, generated SDK access, direct-store CLI history and TUI receipt history now expose durable outcomes, pinned IO policy and optional call/tool correlation without claiming unresolved processes are live. Eligible global Windows full-access hooks now have a parent-owned event-input route with native acceptance pending. Required Windows hook confinement, other lifecycle/remote-tool dispatch, recovery reconciliation and complete client observability remain open. Authenticated Location definition catalog access and generated SDK `hook.list` now provide fresh trust metadata with redacted credentials and original digests. TUI loaded-definition and exact trust review now have local render/state/authenticated HTTP tests. Raw withheld top-level/profile section review is implemented without substitution or handler interpretation across API/SDK/CLI/TUI. Exact effective-digest/event/scope checkout last-run summaries are implemented across API/SDK/CLI/TUI without raw IO or recovery effects. Independent durable synthetic receipts and protected event construction are implemented without Session effects. Synthetic object payloads cannot replace the generated invocation identity or trusted envelope fields. Owned command test execution now uses independent receipts and receipt-specific managed checkout leases, with once skipping, acknowledged cancellation, unknown disposal fencing and optional bounded IO; `cyber hooks test [--payload FILE]` now exercises command handlers through bounded payload validation, event selectors, rewrite chaining, fixed-event concurrency/deduplication and ordered decisions without Session startup. Synchronous HTTP POST hooks now share durable Session/synthetic ownership, strict bounded decisions, scoped network policy and acknowledged local proxy shutdown; Prompt handlers now use tool-free evaluator/small-model judgement and hidden Session/ancestor billing; Native HTTP provider adapters now acknowledge owned local proxy shutdown and honor nonblocking/fail-closed timeout policy; remote processing/final billing remain unverified and custom-adapter/native acceptance remain open. Configured local MCP launch and initial paginated discovery are implemented locally, with stable names, filters, exposed dispatch and explicit stale-tool refresh. Independent durable MCP ownership and the owned local adapter now retain complete managed checkout pins, unresolved disposal evidence and retryable database settlement. Shared concurrent local startup, runtime tool registration/permissions/hooks and shutdown are now implemented locally, including exact registration identities and managed checkout pins. Application client tools now share schema, permission, hook and bounded output settlement with MCP, and public tool listing matches scoped runtime visibility. Location-scoped host close now fences admission, settles retained native owners and permits fresh registration only after verified closure; unknown startup remains fenced. Authenticated HTTP and generated SDK close are now implemented with scoped replay identity and actual-process tests. Committed local status events now reach the instance stream with independent connection identity and redacted SDK payloads. Authenticated configured status snapshots now combine fresh definitions and retained observations without startup; stored owners are not adopted as live actors. Retained idle monitors now detect local leader exit and ready stdio EOF, remove discovery and explicitly settle native ownership. Bounded local notification processing and authorized list-change refresh are implemented locally, with metadata-bound stale registrations and retained cancellation cleanup. Owned startup failures now distinguish complete retry-safe settlement from native acknowledgement, with explicit prepared-proxy cleanup; retained local reconnect now uses fresh authorization/identities, cancellable 1–60 second backoff with ten-attempt limits and no call replay. The read-only wait_for_mcp tool now waits up to sixty seconds for named connecting servers through normal permission/hook/cancellation boundaries, with golden and actual delayed-startup coverage. Explicit registration scopes and a shared deferred-catalog materializer now validate the sole threshold, preserve client precedence and separate schema-free summaries; Session-persistent tool_search and runtime schema projection are now implemented locally, with unloaded refusal, durable replay/compaction and real MCP search/use coverage; plugin delivery and native acceptance remain open. Captured local roots now advertise the Location and configured writable paths with bounded roots/list callbacks during initialization, calls and idle processing; sampling remains open. Local server instructions now enter the scoped mcp/instructions Context Source, with registration-aware filtering, client shadowing and explicit replacement/withdrawal system messages; remote/native acceptance remains open. Required local servers now gate the first Turn before prompt promotion with named errors and retryable inbox inputs; cancellation preserves startup ownership, and replay/rewind preserve first-Turn completion. Graceful POSIX Location/runtime close now retains group identity through SIGTERM and five seconds before SIGKILL; interrupted close retains its deadline, while failed startup/cancelled calls keep immediate cleanup. Explicit call-timeout overrides now use approval-bound presence and global fallback; only valid advancing progress extends request inactivity. Per-server estimated output caps and side-effect-free cyber mcp get resolved review are implemented locally; dynamic header commands/refresh and remote/native acceptance remain open. Withheld definitions and remaining status transitions, CLI/TUI close, reconfiguration, remote reconnect and MCP transport and async scheduling remain incomplete; complete pre-event scheduling, other transports and native acceptance remain open. Exec trust integration, all remaining lifecycle events and client controls, JSON-RPC plugin host + `@cyber-code/plugin`, MCP OAuth and complete native acceptance remain open. Local stdio form elicitation now has call-owned typed questions and explicit consent with cancellation/revocation tests; 229 local Rust cases, workspace Clippy and SDK/spec checks pass. Remote/URL elicitation and native acceptance remain pending. Opt-in local sampling now uses small-model permission/budget gates and server-attributed usage, with actual native-provider timeout/close and budget tests; full platform and remote acceptance remain open. Synchronous local MCP-tool hooks now own dedicated connections through fresh trust, filtered/schema-checked calls, absolute deadlines, cancellation and durable receipt cleanup. Actual callback and CLI tests pass; remote hooks, async scheduling and full platform acceptance remain open. +3. **M1.3 Extensibility:** **Status: in progress** (change `implement-m1-3-extensibility`). **Acceptance (2026-10-18):** 48 of 53 P1 requirements done locally (48 a, 3 c, 2 e): every hooks row except Supported events, MCP (OAuth needs only native keyring evidence), SDK hook callbacks, org MCP controls, skills and commands, and VCS text, demonstrated on the real binary, server and SDK in batch A; since increment 12 the declarative plugin foundation (manifest, discovery defaults, scopes and lockfile, path/git/npm sources, `cyber plugins`, `/plugins`, digest trust, `--pure`) and the plugin hook scope; since increment 13 the sandboxed JSON-RPC plugin host (forwarded and deferred tools, crash isolation and backoff, scoped registrations, network and write capabilities, validated settings with keyring secrets) and the `@cyber-code/plugin` TypeScript kit; since increment 15 command-hook sandboxing (project and plugin hooks write only inside the workspace). Increments 12, 13 and 15 were demonstrated on macOS in batch C (real binary, `cyber serve`, Python and Node plugin hosts, local git and npm sources, TUI `/plugins`). Host-protocol hooks, providers, catalog transforms and `session/prompt`, `fs.read`/`shell` enforcement, native keyring evidence for plugin secrets, `DirectoryAdded`, explicit `Setup` initialization/marker semantics and combined hook-producer acceptance remain. Committed `CwdChanged` and bounded `FileChanged` observation have producers; FileChanged resource/lifecycle acceptance remains open; the Windows hook sandbox test is ignored on Windows because PowerShell 7 cannot start inside the AppContainer (issue #9); the remote MCP suites now pass on native Windows, while the local stdio MCP cases are Unix-only (2026-10-23 [evidence pass](docs/implementation/p1-signoff-plan.md)). The history below predates that sign-off. Typed hook configuration/event/handler validation is implemented locally with selector, timeout and checkout-trust tests. Loaded global/project/local hook groups now accumulate at top level and within selected profiles, retaining indexed file origins; managed/plugin collection, final execution scope order and managed-only authority remain open. Canonical handler digests, separate durable approvals in the shared checkout trust store and temporary invocation approval sets are implemented locally with cross-process storage tests. The scope-aware catalog orders resolved contributions and exposes uncached trust/sandbox requirements; CLI list/trust/untrust supports exact-digest review and obsolete revocation. Compiled subject/path/condition selectors, event-aware ordered decision parsing/merging and immutable envelope assembly are implemented locally; built-in tool command dispatch now captures invocation identity, chains rewrites and validates final input before permissions. Remaining lifecycle identity/emission, full target extraction, effectful scheduling and other handler types remain open. Owned command stream capture now supports event stdin, bounded output and explicit stop acknowledgement locally. Command result interpretation has local contract and real-process tests for JSON decisions, exit codes, timeout policy and unknown termination; Noninteractive Unix command launch has local trust-revocation, event-input/environment, mandatory sandbox and scratch-ownership tests. Recorded Unix command execution now has local durable admission/receipt, privacy and tracked subtree cancellation tests. Unix built-in PreToolUse/PostToolUse/PostToolUseFailure command dispatch now has local denial, rewrite, permission, trust and receipt tests, plus transient TUI/exec notices. Command PermissionRequest hooks now answer individual asks without saved approvals and retain hard denials/Mode limits. Fixed-input request/post events now use bounded command concurrency with immediate slot reuse, declared-order merging and acknowledged sibling cancellation; rewrite-dependent pre-tool scheduling remains open. Command once-per-Session claims now persist atomically with receipt admission and survive concurrent runtimes, restart and unknown settlement; status/completion messages are user-only notices. Authenticated Session receipt pagination, generated SDK access, direct-store CLI history and TUI receipt history now expose durable outcomes, pinned IO policy and optional call/tool correlation without claiming unresolved processes are live. Eligible global Windows full-access hooks now have a parent-owned event-input route with native acceptance pending. Required Windows hook confinement, other lifecycle/remote-tool dispatch, recovery reconciliation and complete client observability remain open. Authenticated Location definition catalog access and generated SDK `hook.list` now provide fresh trust metadata with redacted credentials and original digests. TUI loaded-definition and exact trust review now have local render/state/authenticated HTTP tests. Raw withheld top-level/profile section review is implemented without substitution or handler interpretation across API/SDK/CLI/TUI. Exact effective-digest/event/scope checkout last-run summaries are implemented across API/SDK/CLI/TUI without raw IO or recovery effects. Independent durable synthetic receipts and protected event construction are implemented without Session effects. Synthetic object payloads cannot replace the generated invocation identity or trusted envelope fields. Owned command test execution now uses independent receipts and receipt-specific managed checkout leases, with once skipping, acknowledged cancellation, unknown disposal fencing and optional bounded IO; `cyber hooks test [--payload FILE]` now exercises command handlers through bounded payload validation, event selectors, rewrite chaining, fixed-event concurrency/deduplication and ordered decisions without Session startup. Synchronous HTTP POST hooks now share durable Session/synthetic ownership, strict bounded decisions, scoped network policy and acknowledged local proxy shutdown; Prompt handlers now use tool-free evaluator/small-model judgement and hidden Session/ancestor billing; Native HTTP provider adapters now acknowledge owned local proxy shutdown and honor nonblocking/fail-closed timeout policy; remote processing/final billing remain unverified and custom-adapter/native acceptance remain open. Configured local MCP launch and initial paginated discovery are implemented locally, with stable names, filters, exposed dispatch and explicit stale-tool refresh. Independent durable MCP ownership and the owned local adapter now retain complete managed checkout pins, unresolved disposal evidence and retryable database settlement. Shared concurrent local startup, runtime tool registration/permissions/hooks and shutdown are now implemented locally, including exact registration identities and managed checkout pins. Application client tools now share schema, permission, hook and bounded output settlement with MCP, and public tool listing matches scoped runtime visibility. Location-scoped host close now fences admission, settles retained native owners and permits fresh registration only after verified closure; unknown startup remains fenced. Authenticated HTTP and generated SDK close are now implemented with scoped replay identity and actual-process tests. Committed local status events now reach the instance stream with independent connection identity and redacted SDK payloads. Authenticated configured status snapshots now combine fresh definitions and retained observations without startup; stored owners are not adopted as live actors. Retained idle monitors now detect local leader exit and ready stdio EOF, remove discovery and explicitly settle native ownership. Bounded local notification processing and authorized list-change refresh are implemented locally, with metadata-bound stale registrations and retained cancellation cleanup. Owned startup failures now distinguish complete retry-safe settlement from native acknowledgement, with explicit prepared-proxy cleanup; retained local reconnect now uses fresh authorization/identities, cancellable 1–60 second backoff with ten-attempt limits and no call replay. The read-only wait_for_mcp tool now waits up to sixty seconds for named connecting servers through normal permission/hook/cancellation boundaries, with golden and actual delayed-startup coverage. Explicit registration scopes and a shared deferred-catalog materializer now validate the sole threshold, preserve client precedence and separate schema-free summaries; Session-persistent tool_search and runtime schema projection are now implemented locally, with unloaded refusal, durable replay/compaction and real MCP search/use coverage; plugin delivery and native acceptance remain open. Captured local roots now advertise the Location and configured writable paths with bounded roots/list callbacks during initialization, calls and idle processing; sampling remains open. Local server instructions now enter the scoped mcp/instructions Context Source, with registration-aware filtering, client shadowing and explicit replacement/withdrawal system messages; remote/native acceptance remains open. Required local servers now gate the first Turn before prompt promotion with named errors and retryable inbox inputs; cancellation preserves startup ownership, and replay/rewind preserve first-Turn completion. Graceful POSIX Location/runtime close now retains group identity through SIGTERM and five seconds before SIGKILL; interrupted close retains its deadline, while failed startup/cancelled calls keep immediate cleanup. Explicit call-timeout overrides now use approval-bound presence and global fallback; only valid advancing progress extends request inactivity. Per-server estimated output caps and side-effect-free cyber mcp get resolved review are implemented locally; dynamic header commands/refresh and remote/native acceptance remain open. Withheld definitions and remaining status transitions, CLI/TUI close, reconfiguration, remote reconnect and MCP transport and async scheduling remain incomplete; complete pre-event scheduling, other transports and native acceptance remain open. Exec trust integration, all remaining lifecycle events and client controls, JSON-RPC plugin host + `@cyber-code/plugin`, MCP OAuth and complete native acceptance remain open. Local stdio form elicitation now has call-owned typed questions and explicit consent with cancellation/revocation tests; 229 local Rust cases, workspace Clippy and SDK/spec checks pass. Remote/URL elicitation and native acceptance remain pending. Opt-in local sampling now uses small-model permission/budget gates and server-attributed usage, with actual native-provider timeout/close and budget tests; full platform and remote acceptance remain open. Synchronous local MCP-tool hooks now own dedicated connections through fresh trust, filtered/schema-checked calls, absolute deadlines, cancellation and durable receipt cleanup. Actual callback and CLI tests pass; remote hooks, async scheduling and full platform acceptance remain open. 4. **M1.4 Memory & intelligence:** **Status: in progress** (change `implement-m1-4-memory-intelligence`). **Acceptance (2026-10-18):** 28 of 28 P1 requirements done locally (28 a): every memory and code-intelligence row, demonstrated on the real binary, server and TUI in batch A, and since increment 14 browser verification (`cyber mcp browser install|health|cleanup`, a pinned browser MCP server run per Session with a fresh profile, trust, permission and network gating, hashed evidence with staleness, dev servers as `bash` `ready_url` Jobs, Session-end cleanup), demonstrated on macOS in batch C with a fake browser MCP server standing in for the pinned package. One real-browser run against the pinned package stays class (e) evidence. The memory, CLI-memory and intelligence suites run on native Windows in main CI, and read-only memory recovery is accepted natively (2026-10-23 [evidence pass](docs/implementation/p1-signoff-plan.md)); the `cyber-app` browser suite is Unix-only (`browser_cli` runs on Windows). The history below predates that sign-off and its "no M1.4 contract is fully accepted" is superseded. Shared memory document/write validation, deterministic indexes, bounded snapshots, typed settings, directory-bound read/scope ownership and Unix journaled mutation/explicit recovery and built-in memory tool admission and core/memory baseline/Safe Boundary updates and CLI review/edit/delete controls and fingerprint-bound local recovery with pending-database fences and authenticated HTTP/SDK CRUD and durable change receipts and shared-runtime reviewed reconciliation and authenticated HTTP/SDK controls and durable keyed receipt lookup for pinned journals and explicit CLI reconciliation through a running server and TUI note review/deletion/paired recovery and reviewed multiline editing with private Unix draft/request checkpoints, review-free restoration, exact request outcome reconciliation and confirmed retained-record forgetting are implemented locally. Windows private recoverable storage and legacy unknown-effect recovery, multi-client retention and complete client/native mutation acceptance, LSP diagnostics feedback, formatters and isolated browser verification with revision-linked artifacts remain required; no M1.4 contract is fully accepted. 5. **M1.5 Migration path:** `cyber import claude|codex|opencode`. **Acceptance (2026-10-18):** 6 of 10 P1 requirements done locally (6 a, 4 c). Increment 10 added reviewed writes, reports and idempotent annotations; increment 11 added the Claude, Codex and OpenCode source adapters, the read-time skill precedence and runtime `.mcp.json` loading; both were demonstrated on macOS in batch C, and the exit criterion below holds locally. Open: the keyring credential branch, OpenCode SQLite session counts, Claude `apiKeyHelper` and `.claude/rules`, and the TUI approval prompt for `.mcp.json` servers. ACP and the VS Code extension moved to P3 (change `defer-editor-integration`). diff --git a/docs/features.md b/docs/features.md index b1cc548bf..8184c6bc1 100644 --- a/docs/features.md +++ b/docs/features.md @@ -1,6 +1,6 @@ # Feature reference -Implemented behavior and remaining scope, reviewed on **2026-10-16** (Cross-session messaging, Direct peers and Feature flags on 2026-10-19; Agent teams, Models and Sessions on 2026-10-20; Goals, Loops and budget wording reconciled on 2026-10-22; experimental Project collaboration on 2026-10-24). Start with the [README](../README.md); use the [P1 status](implementation/p1-status.md) and [acceptance audit](implementation/p1-acceptance-audit.md) for detailed evidence. +Implemented behavior and remaining scope, reviewed on **2026-10-16** (Cross-session messaging, Direct peers and Feature flags on 2026-10-19; Agent teams, Models and Sessions on 2026-10-20; Goals, Loops and budget wording reconciled on 2026-10-22; experimental Project collaboration on 2026-10-24; hook producers on 2026-10-30). Start with the [README](../README.md); use the [P1 status](implementation/p1-status.md) and [acceptance audit](implementation/p1-acceptance-audit.md) for detailed evidence. “Available” describes implemented local-core behavior. “Partial P1” means working pieces exist and the full contract still needs implementation or acceptance. @@ -33,7 +33,7 @@ Implemented behavior and remaining scope, reviewed on **2026-10-16** (Cross-sess | Cancellation | Durable admission closure, exclusive child result ownership, bounded stop reports and matched reopening | Partial P1; unknown-effect recovery, cross-process actor cancellation and exec/TUI adoption remain | | Spending | Durable own/descendant billing, the usage step ledger, the atomic usage API with per-model, duration, code-change and Budget breakdown, the TUI Usage tab (`/usage`, `/cost`) with Budget meters, usage statistics (`GET /api/v1/usage/stats`: local-day activity, streaks and per-model totals) shown by the TUI Stats tab (`/stats`, heatmap and Models) and `cyber stats`, usage insights (`GET /api/v1/usage/insights`: subagent-heavy, long-running and large-context shares plus subagent groups) shown in the Usage tab, provider-reported plan and rate-limit windows (`GET /api/v1/usage/limits`, read from provider response headers, never estimated) shown as Usage tab meters, Session recaps (`GET|POST /api/v1/sessions/:id/recap`, `small` model, cached by `through_seq`) shown at the top of the TUI transcript, and soft Session budgets | Partial P1; reservations, daily cap enforcement and complete enforcement remain | | Plugins | Declarative plugins (`cyber-plugin.json`): skills, commands, agents, hooks, `.mcp.json` servers and TUI themes, namespaced `:` on a collision; user, project (with `.cyber/plugins.lock`) and local scopes plus managed `policy.plugins.disabled`; path, git (pinned commit) and npm (`--ignore-scripts`) sources cached at `/plugins//-/` (content-addressed, shared by every scope and checkout); trust bound to name, version and content digest with a review prompt for project plugins; `cyber plugins install/list/info/update/remove/enable/disable/validate`, `GET /api/v1/plugins`, TUI `/plugins` and `/reload-plugins`; `--pure`/`CYBER_PURE=1`; plugin host processes for `main` (JSON-RPC 2.0 over stdio, always sandboxed with the declared `network` and `fs.write` capabilities, `network` never wider than the resolved sandbox network and its denylist; plugin `http`, `prompt` and `mcp_tool` hooks load only within the declared capabilities, and plugin command hooks run with the plugin's network, contributed tools with crash isolation, restart backoff and crash-loop disable, validated `userConfig` with keyring secrets, `cyber plugins configure`) and the `@cyber-code/plugin` TypeScript kit | Partial P1; host-protocol hooks, providers, catalog transforms and `session/prompt`, `fs.read`/`shell` enforcement, plugin hosts on Windows, mods, marketplaces and signature verification remain | -| Hooks | Command (Unix shell, Windows PowerShell), HTTP, prompt and MCP-tool handlers; managed, global, project, local and invocation scopes with managed-only policy; exact handler trust with `--trust-project-hooks` for one exec run; tool and lifecycle events, context, in-process SDK handlers (`client.hooks.on`, scope `client`, run after every configured handler), `continue: false`, async handlers and durable receipts; CLI/TUI/API review and `cyber hooks test` | Partial P1; plugin hooks run last in scope `plugin`; sandboxed hook scopes on Windows and the events without a producer (`DirectoryAdded`, `FileChanged`, `CwdChanged`) remain | +| Hooks | Command (Unix shell, Windows PowerShell), HTTP, prompt and MCP-tool handlers; managed, global, project, local and invocation scopes with managed-only policy; exact handler trust with `--trust-project-hooks` for one exec run; tool and lifecycle events, context, in-process SDK handlers (`client.hooks.on`, scope `client`, run after every configured handler), `continue: false`, async handlers and durable receipts; CLI/TUI/API review and `cyber hooks test`; committed worktree Location changes produce `CwdChanged`, and bounded metadata observation produces `FileChanged` for tool, formatter, shell/background and external edits ([guide](local-core-guide.md#hook-configuration-and-trust-review)) | Partial P1; plugin hooks run last in scope `plugin`; sandboxed hook scopes on Windows, `DirectoryAdded`, explicit `Setup` initialization/marker semantics and combined producer acceptance remain. FileChanged resource/lifecycle acceptance is still open | | MCP | Local approvals, shared tools/status, startup waiting, schema search and bounded reconnect; remote servers over Streamable HTTP with legacy SSE fallback, `needs_auth` reporting, header commands and policy-checked networking; OAuth sign-in with `cyber mcp auth`/`logout`, token refresh, scope step-up and reconnect, with credentials in the macOS Keychain or Windows Credential Manager (owner-only file on Linux); resource tools and `@server:uri` mentions; server prompts as `/:` commands; form elicitation for local and remote servers (declined when unattended, URL mode refused, never opens links); `roots/list` with the Location and writable roots, reconnecting when they change; tools/prompts/resources `list_changed` refresh with `mcp.tools.changed.1`; `notifications/cancelled` on interrupt or timeout; sampling by `model_roles.small` for local and remote servers when `mcp.sampling.enabled`; organization `policy.mcp` allow/deny patterns (name, command, URL) and managed servers for every Location (blocked servers report `blocked by organization policy` and are never contacted); annotations drive modes (destructive tools always classified in `auto`, open-world tools ask `network` when the sandbox network is off) and reach hook envelopes as `tool_annotations` | Partial P1; prompt argument completion, blobs beyond 1 MiB, remote token revocation and native acceptance (including a real Keychain and Credential Manager round trip) remain | | MCP serve | `cyber mcp serve` exposes Sessions to other agents as trusted local clients: a stdio bridge to the shared server or loopback Streamable HTTP at `/api/v1/mcp/serve` (Unix socket or local password; loopback peers and `Host` only). Tools create, list, read and page Sessions, send literal prompts through the user path (`UserPromptSubmit` hooks run) with a wait or a receipt, re-attach with `cyber_prompt_wait` (also after a restart) and interrupt, and list, send and read cross-session messages (as the calling Session when known, else as the MCP client `mcp: