fix(e2b): close remaining remote lifecycle races

This commit is contained in:
Tianyi Cui
2026-07-28 19:21:39 +08:00
parent 64b4669a74
commit 97496c3d00
26 changed files with 193 additions and 1498 deletions

View File

@@ -147,18 +147,23 @@ try {
workspaceRoot: process.cwd(),
})
const swappedSource = await ctx.fs.resolve('swapped-source.ts')
const swappedSourcePath = posix.join(process.cwd(), 'swapped-source.ts')
await ctx.fs.writeText(swappedSource, 'const safe = true\n', { kind: 'createIfAbsent' })
const swappedParentPath = posix.join(process.cwd(), 'swapped-parent')
const swappedSourcePath = posix.join(swappedParentPath, 'source.ts')
const swappedOutsidePath = '/tmp/dsh-e2b-lsp-outside'
await sandbox.commands.run(
`mkdir -p -- ${quoteE2BShellArg(swappedParentPath)} ${quoteE2BShellArg(swappedOutsidePath)} && printf 'const safe = true\\n' > ${quoteE2BShellArg(swappedSourcePath)} && printf 'const outside = true\\n' > ${quoteE2BShellArg(posix.join(swappedOutsidePath, 'source.ts'))}`,
)
const remoteCommands = sandbox.commands as unknown as {
run(command: string, options?: unknown): Promise<{ exitCode: number; stdout: string; stderr: string }>
}
const runRemoteCommand = remoteCommands.run.bind(sandbox.commands)
let containmentFaultInjected = false
remoteCommands.run = async (command, options) => {
if (!containmentFaultInjected && command.includes('dsh-e2b-source-reader') && command.includes('swapped-source.ts')) {
if (!containmentFaultInjected && command.includes('dsh-e2b-source-reader') && command.includes('swapped-parent/source.ts')) {
containmentFaultInjected = true
await runRemoteCommand(`rm -f -- ${quoteE2BShellArg(swappedSourcePath)} && ln -s -- /etc/hosts ${quoteE2BShellArg(swappedSourcePath)}`)
await runRemoteCommand(
`rm -rf -- ${quoteE2BShellArg(swappedParentPath)} && ln -s -- ${quoteE2BShellArg(swappedOutsidePath)} ${quoteE2BShellArg(swappedParentPath)}`,
)
}
return await runRemoteCommand(command, options)
}
@@ -166,7 +171,7 @@ try {
try {
await ctx.lsp.query({
operation: 'hover',
filePath: 'swapped-source.ts',
filePath: 'swapped-parent/source.ts',
position: { line: 0, character: 1 },
workspaceRoot: process.cwd(),
})
@@ -200,8 +205,28 @@ try {
text: "printf 'PTY-你好\\n'",
submit: true,
}).done
const foregroundLookup = Promise.withResolvers<undefined>()
let delayedForegroundLookup = false
remoteCommands.run = async (command, options) => {
if (!delayedForegroundLookup && command.startsWith('ps -o tpgid=')) {
delayedForegroundLookup = true
await foregroundLookup.promise
}
return await runRemoteCommand(command, options)
}
const staleInterrupt = ctx.pty.startSend(owner, terminal.sessionId, { text: 'sleep 0.2', submit: true })
if (!staleInterrupt.cancel()) throw new Error('E2B PTY refused the stale-interrupt probe cancellation')
await staleInterrupt.done
const sleeping = ctx.pty.startSend(owner, terminal.sessionId, { text: 'sleep 30', submit: true })
await new Promise(resolveDelay => setTimeout(resolveDelay, 150))
foregroundLookup.resolve(undefined)
const interruptIdentitySafe = await Promise.race([
sleeping.done.then(() => false),
new Promise<true>(resolveDelay => setTimeout(() => { resolveDelay(true) }, 300)),
])
remoteCommands.run = runRemoteCommand
if (!delayedForegroundLookup || !interruptIdentitySafe) {
throw new Error('E2B PTY stale interrupt affected its successor send')
}
const terminalSignal = await ctx.pty.signal(owner, terminal.sessionId, 'SIGINT')
const interrupted = await sleeping.done
const stubborn = await ctx.pty.startSend(owner, terminal.sessionId, {
@@ -296,6 +321,23 @@ try {
`,
bindings: [],
})
const descendantPipe = await ctx.codeRuntime.run({
program: `
const childProcess = await import('node:child_process')
const child = childProcess.spawn(
process.execPath,
['-e', 'setInterval(() => {}, 1000)', 'dsh-code-runtime-descendant'],
{ stdio: ['ignore', 'inherit', 'inherit'] },
)
return child.pid > 0
`,
bindings: [],
})
const descendantProcesses = await sandbox.commands.list()
const descendantCleanup = !descendantProcesses.some(processInfo =>
JSON.stringify([processInfo.cmd, processInfo.args]).includes('dsh-code-runtime-descendant'),
)
if (!descendantCleanup) throw new Error('E2B Code Runtime left a pipe-holding descendant alive')
const timedOut = await ctx.codeRuntime.run({
program: 'await new Promise(() => {})',
bindings: [],
@@ -340,6 +382,7 @@ try {
echo: terminalEcho,
signal: terminalSignal,
interrupted,
interruptIdentitySafe,
treeCleanup: terminalTreeCleanup,
scrollback: terminalScrollback.text,
},
@@ -348,6 +391,8 @@ try {
nativeOutput,
descriptorOutput,
inheritedOutput,
descendantPipe,
descendantCleanup,
timedOut,
aborted,
oversizedBoot,