Skip to content

Commit dc22c2e

Browse files
committed
fix(buddy): 缩短沙箱私有目录以适配 macOS socket 限制
1 parent 59d205b commit dc22c2e

4 files changed

Lines changed: 32 additions & 11 deletions

File tree

‎apps/buddy/electron/main/sandbox/registerSandboxHostRpc.ts‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import type { RuntimeRpcPeerContract } from '../../../shared/runtime/rpcPeer'
2-
import { mkdir, mkdtemp, realpath, rm } from 'node:fs/promises'
3-
import { homedir, tmpdir } from 'node:os'
4-
import { join } from 'node:path'
2+
import { rm } from 'node:fs/promises'
3+
import { homedir } from 'node:os'
54
import process from 'node:process'
65
import { utilityProcess } from 'electron'
76
import { createProxyEnvironment } from '../../../platform/process/proxyEnvironment'
7+
import { createSandboxDirectory } from '../../../platform/process/sandboxDirectory'
88
import { createSandboxEnvironment } from '../../../platform/process/sandboxEnvironment'
99
import { resolveWindowsSandbox } from '../../../platform/process/windowsSandbox'
1010
import sandboxProcessPath from '../../../service/src/sandbox/sandboxProcess?modulePath'
@@ -61,8 +61,7 @@ export function registerSandboxHostRpc(peer: RuntimeRpcPeerContract, options: Sa
6161
return { ok: false, code: 'SANDBOX_UNAVAILABLE' }
6262
if (isLinux(process.platform) && !options.sandboxDirectory)
6363
return { ok: false, code: 'SANDBOX_UNAVAILABLE' }
64-
directory = await realpath(await mkdtemp(join(tmpdir(), 'lexora-shell-')))
65-
await Promise.all(['home', 'tmp'].map(path => mkdir(join(directory!, path), { mode: 0o700 })))
64+
directory = await createSandboxDirectory()
6665
controller.signal.throwIfAborted()
6766
child = utilityProcess.fork(sandboxProcessPath, [], {
6867
cwd: directory,
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { mkdir, mkdtemp, realpath, rm } from 'node:fs/promises'
2+
import { tmpdir } from 'node:os'
3+
import { join } from 'node:path'
4+
import process from 'node:process'
5+
import { isWindows } from '../../shared/platform/identifiers'
6+
7+
export async function createSandboxDirectory(): Promise<string> {
8+
const directory = await mkdtemp(join(isWindows(process.platform) ? tmpdir() : '/tmp', 'lexora-shell-'))
9+
try {
10+
const canonical = await realpath(directory)
11+
await Promise.all(['home', 'tmp'].map(path => mkdir(join(canonical, path), { mode: 0o700 })))
12+
return canonical
13+
}
14+
catch (error) {
15+
await rm(directory, { recursive: true, force: true })
16+
throw error
17+
}
18+
}

‎apps/buddy/service/src/sandbox/__tests__/macosSandbox.spec.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { join, resolve } from 'node:path'
88
import process from 'node:process'
99
import { setTimeout } from 'node:timers/promises'
1010
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
11+
import { createSandboxDirectory } from '../../../../platform/process/sandboxDirectory'
1112
import { createSandboxEnvironment } from '../../../../platform/process/sandboxEnvironment'
1213
import { runSrtSandbox } from '../backends/srt/runSrtSandbox'
1314
import { runSandboxCommand } from '../runSandboxCommand'
@@ -21,14 +22,15 @@ describe.skipIf(process.platform !== 'darwin' || process.arch !== 'arm64')('macO
2122
let directory: string
2223
let workspace: string
2324
let outside: string
25+
let privateRoot: string
2426
let input: SandboxProcessInput
2527

2628
beforeEach(async () => {
2729
directory = await realpath(await mkdtemp(join(tmpdir(), 'lexora-macos-sandbox-')))
2830
workspace = join(directory, 'workspace')
2931
outside = join(directory, 'outside')
30-
const privateRoot = join(directory, 'private')
31-
await Promise.all([workspace, outside, join(privateRoot, 'home'), join(privateRoot, 'tmp')].map(path => mkdir(path, { recursive: true })))
32+
privateRoot = await createSandboxDirectory()
33+
await Promise.all([workspace, outside].map(path => mkdir(path, { recursive: true })))
3234
await writeFile(join(outside, 'preserved'), 'outside-preserved')
3335
const isolatedEnvironment = createSandboxEnvironment(environment, privateRoot)
3436
for (const key of new Set([...Object.keys(process.env), ...Object.keys(isolatedEnvironment)]))
@@ -56,7 +58,7 @@ describe.skipIf(process.platform !== 'darwin' || process.arch !== 'arm64')('macO
5658
afterEach(async () => {
5759
process.chdir(buddyRoot)
5860
vi.unstubAllEnvs()
59-
await rm(directory, { recursive: true, force: true })
61+
await Promise.all([directory, privateRoot].map(path => rm(path, { recursive: true, force: true })))
6062
})
6163

6264
async function execute(command: string, overrides: Partial<SandboxProcessInput> = {}, options: Partial<Parameters<typeof runSandboxCommand>[1]> = {}) {

‎apps/buddy/service/src/sandbox/__tests__/shellSandbox.spec.ts‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { join, resolve } from 'node:path'
88
import process from 'node:process'
99
import { setTimeout } from 'node:timers/promises'
1010
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
11+
import { createSandboxDirectory } from '../../../../platform/process/sandboxDirectory'
1112
import { createSandboxEnvironment } from '../../../../platform/process/sandboxEnvironment'
1213
import { runSandboxCommand } from '../runSandboxCommand'
1314

@@ -20,14 +21,15 @@ describe.skipIf(process.platform !== 'linux')('linux shell enforcement', () => {
2021
let directory: string
2122
let workspace: string
2223
let outside: string
24+
let privateRoot: string
2325
let input: SandboxProcessInput
2426

2527
beforeEach(async () => {
2628
directory = await mkdtemp(join(tmpdir(), 'lexora-sandbox-test-'))
2729
workspace = join(directory, 'workspace')
2830
outside = join(directory, 'outside')
29-
const privateRoot = join(directory, 'private')
30-
await Promise.all([workspace, outside, join(privateRoot, 'home'), join(privateRoot, 'tmp')].map(path => mkdir(path, { recursive: true })))
31+
privateRoot = await createSandboxDirectory()
32+
await Promise.all([workspace, outside].map(path => mkdir(path, { recursive: true })))
3133
await writeFile(join(outside, 'preserved'), 'outside-preserved')
3234
const environment = createSandboxEnvironment(originalEnvironment, privateRoot)
3335
for (const key of new Set([...Object.keys(process.env), ...Object.keys(environment)]))
@@ -55,7 +57,7 @@ describe.skipIf(process.platform !== 'linux')('linux shell enforcement', () => {
5557
afterEach(async () => {
5658
process.chdir(buddyRoot)
5759
vi.unstubAllEnvs()
58-
await rm(directory, { force: true, recursive: true })
60+
await Promise.all([directory, privateRoot].map(path => rm(path, { force: true, recursive: true })))
5961
})
6062

6163
async function execute(command: string, options: Partial<Parameters<typeof runSandboxCommand>[1]> = {}, overrides: Partial<SandboxProcessInput> = {}) {

0 commit comments

Comments
 (0)