Skip to content

fix(core): stop VMs on a shared sidecar answering each other's callbacks - #2089

Merged
eersnington merged 2 commits into
mainfrom
fix/shared-sidecar-callbacks
Nov 3, 2026
Merged

eersnington merged 2 commits into
mainfrom
fix/shared-sidecar-callbacks

Conversation

@eersnington

Copy link
Copy Markdown
Member

VMs that share a sidecar can answer each other's callbacks. A guest in one VM can run a sibling VM's host function and get the sibling's result. The same bug reaches JS filesystem mounts and agentos registry commands.

 guest in VM a calls agentos-t who
   sidecar sends a callback with vm_id = a
-  client runs its one handler, which belongs to the last VM created
-  VM a gets VM b's result
+  client runs the handler for vm_id = a
+  no handler for that VM: error response, no fallback
+  VM a gets its own result
  • TypeScript: the client had one handler slot, and each new VM overwrote it. SidecarProcess now keeps one handler per VM, set with setVmSidecarRequestHandler. Requests with connection or session ownership still use setSidecarRequestHandler.
  • Rust: the callback maps are process-global and keyed by VM ID, but every sidecar process numbers its VMs from vm-1. Two sidecars in one process ran each other's host functions. The keys now include a per-transport ID.
  • Dispose: a VM's handler is removed after the sidecar disposes the VM, so teardown callbacks still work.
  • Limits: the handler map has one entry per admitted VM, so this adds no new limit.
Before After
a calls a function that b also has b answers a answers
a calls it after b.dispose() b answers a answers
a calls it, last sibling has no host functions Unknown host function a answers
Guest in a reads /mnt/x/secret.txt secret of b secret of a
Second VM mounts under a JS mount during create mkdir on the sibling's driver EIO, sibling untouched
Rust VM on a second sidecar calls its function first sidecar's function runs its own function runs
  • Behavior change: a VM that mounts under a JS mount now fails at create with EIO. A lone VM already fails this way on main. A later VM only appeared to work because it used a sibling's driver.
  • Security: guest-triggered host callbacks now reach only the VM that owns the guest.

Related: #2029 proposed routing by VM ownership at the transport layer. Origin: #1531.

@railway-app

railway-app Bot commented Nov 2, 2026

Copy link
Copy Markdown

This PR was not deployed automatically as @eersnington does not have access to the Railway project.

In order to get automatic PR deploys, please add @eersnington to your workspace on Railway.

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

📟 Pip-Boy · 87c1b2f

📦 Packages · fresh npm install resolve, no lockfile · this PR vs base

No notable install size, dependency, or entrypoint changes across 6 packages.

All 6 packages · linux-x64-gnu
package (linux-x64-gnu) @latest base this PR Δ vs base packages
@rivet-dev/agentos-core 326.2 MB 326.3 MB 326.3 MB +2.0 KB (+0.0%) 10 (0)
@rivet-dev/agentos-node-pty 7.6 KB 18.0 KB 18.0 KB 0 1 (0)
@rivet-dev/agentos-posix 254.0 MB 254.0 MB 254.0 MB +1.6 KB (+0.0%) 7 (0)
@rivet-dev/agentos-runtime-core 254.0 MB 254.0 MB 254.0 MB +1.6 KB (+0.0%) 6 (0)
@rivet-dev/agentos-sandbox 363.9 MB 363.9 MB 364.0 MB +2.0 KB (+0.0%) 85 (0)
@rivet-dev/agentos-toolchain 130.8 KB 141.2 KB 141.2 KB 0 2 (0)

🧹 Rust dependencies · cargo deny + cargo shear

check new in this PR fixed existing on base
advisories ✅ 0 0 28
licenses ✅ 0 0 0
sources ✅ 0 0 0
bans ✅ 0 0 0
unused ✅ 0 0 16

🦀 Binaries · publish Dockerfiles, --release

Base: main@c746292, the merge base.

artifact npm @latest base this PR Δ vs base
agentos-native-sidecar linux-x64-gnu 144.0 MB 144.0 MB 144.0 MB −16 B (−0.0%)

⏱ Timing

job wall time slowest step
zizmor 9s checkout · 3s
changes 34s checkout · 29s
native · linux-x64-gnu 10m03s Build with the publish Dockerfile · 9m30s
footprint 2m17s Pack this commit · 44s
hygiene 57s checkout · 24s
⏭ self-test — skipped
report 17s setup-node · 4s
🔭 Full CI trace for this commit

One OpenTelemetry trace of CI and Pip-Boy for 87c1b2f: every job and step, with the sizes above attached. Run after CI finishes.

pnpm install --frozen-lockfile --filter 'pipboy...'
pnpm --filter pipboy pipboy trace --sha 87c1b2f0c75c2e57e0ba48ded3299a59d4a3e4ad

Add --otlp <url> to send it to any OTLP/HTTP collector.

Agent instruction: From a rivet-dev/agentos checkout, run the commands above, then read the trace file the last command prints. List the slowest jobs and steps and explain where CI time went.

@eersnington
eersnington merged commit a4c049b into main Nov 3, 2026
14 of 15 checks passed
@eersnington
eersnington deleted the fix/shared-sidecar-callbacks branch November 3, 2026 00:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant