mirror of
https://github.com/stablyai/orca.git
synced 2026-10-24 00:04:01 +00:00
fix(codex): verify reconstructed WSL homes
This commit is contained in:
@@ -152,7 +152,7 @@ describe('agent hooks CLI handler', () => {
|
||||
expect(callMock).toHaveBeenCalledExactlyOnceWith(
|
||||
'agentHooks.prepareCodexForWslPane',
|
||||
{ codexHome: home, orcaCodexHome: home, wslDistro: 'Ubuntu-24.04' },
|
||||
{ timeoutMs: 40_000 }
|
||||
{ timeoutMs: 50_000 }
|
||||
)
|
||||
expect(prepareManagedCodexHomeBeforeShellLaunchMock).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
@@ -28,8 +28,8 @@ type AgentHookCommandResult = {
|
||||
statuses: AgentHookInstallStatus[]
|
||||
}
|
||||
|
||||
// Covers the 5s WSL identity probe, 30s trust grant, and bounded app-server reap.
|
||||
const WSL_CODEX_PREPARE_TIMEOUT_MS = 40_000
|
||||
// Covers managed-home verification, WSL identity, trust grant, and bounded app-server reap.
|
||||
const WSL_CODEX_PREPARE_TIMEOUT_MS = 50_000
|
||||
|
||||
function getDataPath(): string {
|
||||
const userDataPath = getDefaultUserDataPath()
|
||||
|
||||
@@ -2,6 +2,13 @@ import { mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from 'node
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
const { wslRealpathMock } = vi.hoisted(() => ({
|
||||
wslRealpathMock: vi.fn(async (path: string) => path)
|
||||
}))
|
||||
|
||||
vi.mock('node:fs/promises', () => ({ realpath: wslRealpathMock }))
|
||||
|
||||
import {
|
||||
prepareManagedCodexHomeBeforeShellLaunch,
|
||||
resolveManagedCodexShellPreflightHome
|
||||
@@ -24,6 +31,7 @@ function makeRoot(): string {
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
wslRealpathMock.mockClear()
|
||||
managedWslHomeRegistryInternals.clearRecordedManagedWslCodexHomes()
|
||||
for (const root of roots.splice(0)) {
|
||||
rmSync(root, { recursive: true, force: true })
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { realpath } from 'node:fs/promises'
|
||||
import type { AgentHookInstallStatus } from '../../shared/agent-hook-types'
|
||||
import { withTimeout } from '../../shared/promise-timeout-fallback'
|
||||
import type { CodexWslRuntimeHookTarget } from './codex-wsl-hook-install-plan'
|
||||
import { codexHookService } from './hook-service'
|
||||
import {
|
||||
isAbsolutePosixPathWithoutDotSegments,
|
||||
resolveManagedWslCodexHome
|
||||
resolveManagedWslCodexHome,
|
||||
wslRuntimeHomePathsEqual
|
||||
} from './managed-wsl-codex-home-registry'
|
||||
|
||||
type WslShellPreflightEnvironment = {
|
||||
@@ -12,6 +15,8 @@ type WslShellPreflightEnvironment = {
|
||||
WSL_DISTRO_NAME?: string
|
||||
}
|
||||
|
||||
const WSL_MANAGED_HOME_REALPATH_TIMEOUT_MS = 5_000
|
||||
|
||||
export type ManagedWslCodexShellPreflightTarget = {
|
||||
runtimeHomePath: string
|
||||
wslDistro: string
|
||||
@@ -51,6 +56,14 @@ export async function prepareManagedWslCodexHomeBeforeShellLaunch(args: {
|
||||
if (!target) {
|
||||
return null
|
||||
}
|
||||
const realHome = await withTimeout(
|
||||
realpath(target.runtimeHomePath),
|
||||
WSL_MANAGED_HOME_REALPATH_TIMEOUT_MS,
|
||||
null
|
||||
)
|
||||
if (!realHome || !wslRuntimeHomePathsEqual(realHome, target.runtimeHomePath)) {
|
||||
return null
|
||||
}
|
||||
const install =
|
||||
args.install ??
|
||||
((home: string, hookTarget: CodexWslRuntimeHookTarget) =>
|
||||
|
||||
@@ -2,13 +2,15 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { OrcaRuntimeService } from '../../orca-runtime'
|
||||
import { isStreamingMethod, type RpcContext } from '../core'
|
||||
|
||||
const { installForRuntimeHomeSerializedMock } = vi.hoisted(() => ({
|
||||
installForRuntimeHomeSerializedMock: vi.fn()
|
||||
const { installForRuntimeHomeSerializedMock, realpathMock } = vi.hoisted(() => ({
|
||||
installForRuntimeHomeSerializedMock: vi.fn(),
|
||||
realpathMock: vi.fn()
|
||||
}))
|
||||
|
||||
vi.mock('../../../codex/hook-service', () => ({
|
||||
codexHookService: { installForRuntimeHomeSerialized: installForRuntimeHomeSerializedMock }
|
||||
}))
|
||||
vi.mock('node:fs/promises', () => ({ realpath: realpathMock }))
|
||||
|
||||
import { AGENT_HOOK_METHODS } from './agent-hooks'
|
||||
import {
|
||||
@@ -42,6 +44,8 @@ function runtimeWithSettings(enabled = true, disabledTuiAgents: string[] = []):
|
||||
describe('agent hook RPC methods', () => {
|
||||
beforeEach(() => {
|
||||
installForRuntimeHomeSerializedMock.mockReset()
|
||||
realpathMock.mockReset()
|
||||
realpathMock.mockImplementation(async (path: string) => path)
|
||||
managedWslHomeRegistryInternals.clearRecordedManagedWslCodexHomes()
|
||||
recordManagedWslCodexHome('Ubuntu-24.04', RUNTIME_HOME)
|
||||
})
|
||||
@@ -112,6 +116,21 @@ describe('agent hook RPC methods', () => {
|
||||
expect(installForRuntimeHomeSerializedMock).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('rejects a managed-looking home that resolves through a symlink', async () => {
|
||||
realpathMock.mockResolvedValue(
|
||||
'\\\\wsl.localhost\\Ubuntu-24.04\\home\\jin\\outside-managed-home'
|
||||
)
|
||||
const method = prepareMethod()
|
||||
const params = method.params!.parse({
|
||||
codexHome: LINUX_HOME,
|
||||
orcaCodexHome: LINUX_HOME,
|
||||
wslDistro: 'Ubuntu-24.04'
|
||||
})
|
||||
|
||||
await expect(method.handler(params, { runtime: runtimeWithSettings() })).resolves.toBeNull()
|
||||
expect(installForRuntimeHomeSerializedMock).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('rejects malformed distro names at the RPC schema', () => {
|
||||
const method = prepareMethod()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user