test(sandbox): cover POSIX no-shebang fallback

This commit is contained in:
Hypatia May
2026-08-04 17:10:42 +08:00
parent 666690afe9
commit c4e9893a87

View File

@@ -132,27 +132,52 @@ describe('partial Landlock runner-failure classification', () => {
})
})
it('keeps a real malformed executable ENOEXEC as an ordinary spawn failure', async () => {
it('keeps a real malformed executable ordinary across no-shebang spawn behavior', async () => {
const dir = await mkdtemp(join(tmpdir(), 'dsh-malformed-sandbox-runner-'))
tempDirs.push(dir)
const runner = join(dir, 'malformed-runner')
await writeFile(runner, 'not a native executable or shebang script\n', { mode: 0o755 })
const bash = await setupConfiguredRunner(runner)
const request = { command: 'true' }
const foreground = await bash.run(bash.resolve({ command: 'true' })).catch((value: unknown) => value)
expect(foreground).toMatchObject({ code: 'ENOEXEC', syscall: 'spawn' })
expect((foreground as { path?: unknown }).path).toBeUndefined()
// Node/libuv may expose execve's ENOEXEC directly (Darwin) or retry a
// no-shebang executable through /bin/sh (Linux). Neither path supplies the
// provenanced ENOENT/EACCES evidence required for runner attribution.
const foreground = await bash.run(bash.resolve(request)).catch((value: unknown) => value)
expect(foreground).not.toBeInstanceOf(SandboxUnavailableError)
let background: unknown
try {
bash.start(bash.resolve({ command: 'true' }))
} catch (error) {
background = error
if (foreground instanceof Error) {
expect(foreground).toMatchObject({ code: 'ENOEXEC', syscall: 'spawn' })
expect((foreground as { path?: unknown }).path).toBeUndefined()
let background: unknown
try {
bash.start(bash.resolve(request))
} catch (error) {
background = error
}
expect(background).toMatchObject({ code: 'ENOEXEC', syscall: 'spawn' })
expect((background as { path?: unknown }).path).toBeUndefined()
expect(background).not.toBeInstanceOf(SandboxUnavailableError)
} else {
expect(foreground).toMatchObject({
exitCode: 127,
signal: null,
sandbox: { mode: 'read-only', denied: false, enforcement: 'full' },
})
expect((foreground as { stderr: { text: string } }).stderr.text).toMatch(/not.*not found/)
const background = bash.start(bash.resolve(request))
await background.done
expect(background.status).toBe('completed')
expect(background.exitCode).toBe(127)
expect(background.signal).toBeNull()
expect(background.sandbox).toEqual({ mode: 'read-only', denied: false, enforcement: 'full' })
const output = background.readOutput().delta
expect(output).toMatch(/\[stderr\]\n[\s\S]*not.*not found/)
expect(output).not.toContain('spawn failed:')
}
expect(background).toMatchObject({ code: 'ENOEXEC', syscall: 'spawn' })
expect((background as { path?: unknown }).path).toBeUndefined()
expect(background).not.toBeInstanceOf(SandboxUnavailableError)
const accounting = (bash as unknown as { processFacts: Map<unknown, unknown> }).processFacts
expect(accounting.size).toBe(0)
})