mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-14 16:10:59 -07:00
feat(core): address review comments and fix strict sandbox shell selection
This commit is contained in:
@@ -273,7 +273,12 @@ public class GeminiSandbox {
|
||||
si.hStdOutput = GetStdHandle(-11);
|
||||
si.hStdError = GetStdHandle(-12);
|
||||
|
||||
string commandLine = string.Join(" ", args, 2, args.Length - 2);
|
||||
List<string> quotedArgs = new List<string>();
|
||||
for (int i = 2; i < args.Length; i++) {
|
||||
quotedArgs.Add(QuoteArgument(args[i]));
|
||||
}
|
||||
string commandLine = string.Join(" ", quotedArgs.ToArray());
|
||||
|
||||
PROCESS_INFORMATION pi;
|
||||
if (!CreateProcessAsUser(hRestrictedToken, null, commandLine, IntPtr.Zero, IntPtr.Zero, true, CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT, IntPtr.Zero, cwd, ref si, out pi)) {
|
||||
Console.Error.WriteLine("Failed to create process. Error: " + Marshal.GetLastWin32Error());
|
||||
@@ -299,6 +304,14 @@ public class GeminiSandbox {
|
||||
return (int)exitCode;
|
||||
}
|
||||
|
||||
private static string QuoteArgument(string arg) {
|
||||
if (string.IsNullOrEmpty(arg)) return "\"\"";
|
||||
if (arg.IndexOfAny(new char[] { ' ', '\t', '\n', '\v', '\"' }) == -1) return arg;
|
||||
|
||||
string escaped = arg.Replace("\"", "\\\"");
|
||||
return "\"" + escaped + "\"";
|
||||
}
|
||||
|
||||
private static int RunInImpersonation(IntPtr hToken, Func<int> action) {
|
||||
using (WindowsIdentity.Impersonate(hToken)) {
|
||||
return action();
|
||||
|
||||
@@ -279,6 +279,14 @@ export class ShellExecutionService {
|
||||
): Promise<ShellExecutionHandle> {
|
||||
const sandboxManager =
|
||||
shellExecutionConfig.sandboxManager ?? new NoopSandboxManager();
|
||||
|
||||
// Strict sandbox on Windows (network disabled) requires cmd.exe
|
||||
const isStrictSandbox =
|
||||
os.platform() === 'win32' &&
|
||||
shellExecutionConfig.sandboxConfig?.enabled &&
|
||||
shellExecutionConfig.sandboxConfig?.command === 'windows-native' &&
|
||||
!shellExecutionConfig.sandboxConfig?.networkAccess;
|
||||
|
||||
const { env: sanitizedEnv } = await sandboxManager.prepareCommand({
|
||||
command: commandToExecute,
|
||||
args: [],
|
||||
@@ -302,6 +310,7 @@ export class ShellExecutionService {
|
||||
shellExecutionConfig,
|
||||
ptyInfo,
|
||||
sanitizedEnv,
|
||||
isStrictSandbox,
|
||||
);
|
||||
} catch (_e) {
|
||||
// Fallback to child_process
|
||||
@@ -316,6 +325,7 @@ export class ShellExecutionService {
|
||||
abortSignal,
|
||||
shellExecutionConfig.sanitizationConfig,
|
||||
shouldUseNodePty,
|
||||
isStrictSandbox,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -356,10 +366,18 @@ export class ShellExecutionService {
|
||||
abortSignal: AbortSignal,
|
||||
sanitizationConfig: EnvironmentSanitizationConfig,
|
||||
isInteractive: boolean,
|
||||
isStrictSandbox?: boolean,
|
||||
): ShellExecutionHandle {
|
||||
try {
|
||||
const isWindows = os.platform() === 'win32';
|
||||
const { executable, argsPrefix, shell } = getShellConfiguration();
|
||||
let { executable, argsPrefix, shell } = getShellConfiguration();
|
||||
|
||||
if (isStrictSandbox) {
|
||||
shell = 'cmd';
|
||||
argsPrefix = ['/c'];
|
||||
executable = 'cmd.exe';
|
||||
}
|
||||
|
||||
const guardedCommand = ensurePromptvarsDisabled(commandToExecute, shell);
|
||||
const spawnArgs = [...argsPrefix, guardedCommand];
|
||||
|
||||
@@ -690,6 +708,7 @@ export class ShellExecutionService {
|
||||
shellExecutionConfig: ShellExecutionConfig,
|
||||
ptyInfo: PtyImplementation,
|
||||
sanitizedEnv: Record<string, string | undefined>,
|
||||
isStrictSandbox?: boolean,
|
||||
): Promise<ShellExecutionHandle> {
|
||||
if (!ptyInfo) {
|
||||
// This should not happen, but as a safeguard...
|
||||
@@ -700,7 +719,13 @@ export class ShellExecutionService {
|
||||
try {
|
||||
const cols = shellExecutionConfig.terminalWidth ?? 80;
|
||||
const rows = shellExecutionConfig.terminalHeight ?? 30;
|
||||
const { executable, argsPrefix, shell } = getShellConfiguration();
|
||||
let { executable, argsPrefix, shell } = getShellConfiguration();
|
||||
|
||||
if (isStrictSandbox) {
|
||||
shell = 'cmd';
|
||||
argsPrefix = ['/c'];
|
||||
executable = 'cmd.exe';
|
||||
}
|
||||
|
||||
const resolvedExecutable = await resolveExecutable(executable);
|
||||
if (!resolvedExecutable) {
|
||||
|
||||
Reference in New Issue
Block a user