Files
gemini-cli/packages/core/src/sandbox/linux/LinuxSandboxManager.test.ts
T

109 lines
2.7 KiB
TypeScript
Raw Normal View History

2026-03-16 21:34:48 +00:00
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, it, expect, beforeEach } from 'vitest';
2026-03-16 21:34:48 +00:00
import { LinuxSandboxManager } from './LinuxSandboxManager.js';
import type { SandboxRequest } from '../../services/sandboxManager.js';
describe('LinuxSandboxManager', () => {
const workspace = '/home/user/workspace';
let manager: LinuxSandboxManager;
2026-03-16 21:34:48 +00:00
beforeEach(() => {
manager = new LinuxSandboxManager({ workspace });
});
2026-03-16 21:34:48 +00:00
const getBwrapArgs = async (req: SandboxRequest) => {
2026-03-16 21:34:48 +00:00
const result = await manager.prepareCommand(req);
2026-03-17 20:29:13 +00:00
expect(result.program).toBe('sh');
expect(result.args[0]).toBe('-c');
expect(result.args[1]).toBe(
'bpf_path="$1"; shift; exec bwrap "$@" 9< "$bpf_path"',
);
expect(result.args[2]).toBe('_');
expect(result.args[3]).toMatch(/gemini-cli-seccomp-.*\.bpf$/);
return result.args.slice(4);
};
it('correctly outputs bwrap as the program with appropriate isolation flags', async () => {
const bwrapArgs = await getBwrapArgs({
command: 'ls',
args: ['-la'],
cwd: workspace,
env: {},
});
2026-03-17 20:29:13 +00:00
expect(bwrapArgs).toEqual([
2026-03-16 21:34:48 +00:00
'--unshare-all',
'--new-session',
'--die-with-parent',
'--ro-bind',
'/',
'/',
'--dev',
'/dev',
'--proc',
'/proc',
'--tmpfs',
'/tmp',
'--bind',
workspace,
workspace,
2026-03-17 20:29:13 +00:00
'--seccomp',
'9',
2026-03-16 21:34:48 +00:00
'--',
'ls',
'-la',
]);
});
it('maps allowedPaths to bwrap binds', async () => {
const bwrapArgs = await getBwrapArgs({
2026-03-16 21:34:48 +00:00
command: 'node',
args: ['script.js'],
cwd: workspace,
env: {},
policy: {
allowedPaths: ['/tmp/cache', '/opt/tools', workspace],
},
});
2026-03-16 21:34:48 +00:00
// Verify the specific bindings were added correctly
const bindsIndex = bwrapArgs.indexOf('--seccomp');
const binds = bwrapArgs.slice(bwrapArgs.indexOf('--bind'), bindsIndex);
2026-03-16 21:34:48 +00:00
expect(binds).toEqual([
2026-03-16 21:34:48 +00:00
'--bind',
workspace,
workspace,
'--bind-try',
2026-03-16 21:34:48 +00:00
'/tmp/cache',
'/tmp/cache',
'--bind-try',
2026-03-16 21:34:48 +00:00
'/opt/tools',
'/opt/tools',
]);
});
it('should not bind the workspace twice even if it has a trailing slash in allowedPaths', async () => {
const bwrapArgs = await getBwrapArgs({
command: 'ls',
args: ['-la'],
cwd: workspace,
env: {},
policy: {
allowedPaths: [workspace + '/'],
},
});
const bindsIndex = bwrapArgs.indexOf('--seccomp');
const binds = bwrapArgs.slice(bwrapArgs.indexOf('--bind'), bindsIndex);
// Should only contain the primary workspace bind, not the second one with a trailing slash
expect(binds).toEqual(['--bind', workspace, workspace]);
});
2026-03-16 21:34:48 +00:00
});