mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-12 12:54:07 -07:00
feat(core): refactor SandboxManager to a stateless architecture and introduce explicit Deny interface (#23141)
This commit is contained in:
@@ -4,18 +4,19 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { join } from 'node:path';
|
||||
import { join, normalize } from 'node:path';
|
||||
import { writeFileSync } from 'node:fs';
|
||||
import os from 'node:os';
|
||||
import {
|
||||
type SandboxManager,
|
||||
type GlobalSandboxOptions,
|
||||
type SandboxRequest,
|
||||
type SandboxedCommand,
|
||||
sanitizePaths,
|
||||
} from '../../services/sandboxManager.js';
|
||||
import {
|
||||
sanitizeEnvironment,
|
||||
getSecureSanitizationConfig,
|
||||
type EnvironmentSanitizationConfig,
|
||||
} from '../../services/environmentSanitization.js';
|
||||
|
||||
let cachedBpfPath: string | undefined;
|
||||
@@ -76,28 +77,15 @@ function getSeccompBpfPath(): string {
|
||||
return bpfPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for configuring the LinuxSandboxManager.
|
||||
*/
|
||||
export interface LinuxSandboxOptions {
|
||||
/** The primary workspace path to bind into the sandbox. */
|
||||
workspace: string;
|
||||
/** Additional paths to bind into the sandbox. */
|
||||
allowedPaths?: string[];
|
||||
/** Optional base sanitization config. */
|
||||
sanitizationConfig?: EnvironmentSanitizationConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* A SandboxManager implementation for Linux that uses Bubblewrap (bwrap).
|
||||
*/
|
||||
export class LinuxSandboxManager implements SandboxManager {
|
||||
constructor(private readonly options: LinuxSandboxOptions) {}
|
||||
constructor(private readonly options: GlobalSandboxOptions) {}
|
||||
|
||||
async prepareCommand(req: SandboxRequest): Promise<SandboxedCommand> {
|
||||
const sanitizationConfig = getSecureSanitizationConfig(
|
||||
req.config?.sanitizationConfig,
|
||||
this.options.sanitizationConfig,
|
||||
req.policy?.sanitizationConfig,
|
||||
);
|
||||
|
||||
const sanitizedEnv = sanitizeEnvironment(req.env, sanitizationConfig);
|
||||
@@ -121,13 +109,20 @@ export class LinuxSandboxManager implements SandboxManager {
|
||||
this.options.workspace,
|
||||
];
|
||||
|
||||
const allowedPaths = this.options.allowedPaths ?? [];
|
||||
for (const path of allowedPaths) {
|
||||
if (path !== this.options.workspace) {
|
||||
bwrapArgs.push('--bind', path, path);
|
||||
const allowedPaths = sanitizePaths(req.policy?.allowedPaths) || [];
|
||||
const normalizedWorkspace = normalize(this.options.workspace).replace(
|
||||
/\/$/,
|
||||
'',
|
||||
);
|
||||
for (const allowedPath of allowedPaths) {
|
||||
const normalizedAllowedPath = normalize(allowedPath).replace(/\/$/, '');
|
||||
if (normalizedAllowedPath !== normalizedWorkspace) {
|
||||
bwrapArgs.push('--bind-try', allowedPath, allowedPath);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: handle forbidden paths
|
||||
|
||||
const bpfPath = getSeccompBpfPath();
|
||||
|
||||
bwrapArgs.push('--seccomp', '9');
|
||||
|
||||
Reference in New Issue
Block a user