Make it so CONFIG_DIR is not in the list of writable roots by default (#419)

To play it safe, let's keep `CONFIG_DIR` out of the default list of
writable roots.

This also fixes an issue where `execWithSeatbelt()` was modifying
`writableRoots` instead of creating a new array.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/419).
* #423
* #420
* __->__ #419
This commit is contained in:
Michael Bolin
2025-04-20 09:37:07 -07:00
committed by GitHub
parent 425430debb
commit e372e4667b
2 changed files with 8 additions and 9 deletions

View File

@@ -3,11 +3,9 @@ import type { SpawnOptions } from "child_process";
import { exec } from "./raw-exec.js";
import { log } from "../log.js";
import { CONFIG_DIR } from "src/utils/config.js";
function getCommonRoots() {
return [
CONFIG_DIR,
// Without this root, it'll cause:
// pyenv: cannot rehash: $HOME/.pyenv/shims isn't writable
`${process.env["HOME"]}/.pyenv`,
@@ -17,16 +15,17 @@ function getCommonRoots() {
export function execWithSeatbelt(
cmd: Array<string>,
opts: SpawnOptions,
writableRoots: Array<string>,
writableRoots: ReadonlyArray<string>,
abortSignal?: AbortSignal,
): Promise<ExecResult> {
let scopedWritePolicy: string;
let policyTemplateParams: Array<string>;
if (writableRoots.length > 0) {
// Add `~/.codex` to the list of writable roots
// (if there's any already, not in read-only mode)
getCommonRoots().map((root) => writableRoots.push(root));
const { policies, params } = writableRoots
const fullWritableRoots = [...writableRoots, ...getCommonRoots()];
// In practice, fullWritableRoots will be non-empty, but we check just in
// case the logic to build up fullWritableRoots changes.
if (fullWritableRoots.length > 0) {
const { policies, params } = fullWritableRoots
.map((root, index) => ({
policy: `(subpath (param "WRITABLE_ROOT_${index}"))`,
param: `-DWRITABLE_ROOT_${index}=${root}`,

View File

@@ -21,7 +21,7 @@ const MAX_BUFFER = 1024 * 100; // 100 KB
export function exec(
command: Array<string>,
options: SpawnOptions,
_writableRoots: Array<string>,
_writableRoots: ReadonlyArray<string>,
abortSignal?: AbortSignal,
): Promise<ExecResult> {
// Adapt command for the current platform (e.g., convert 'ls' to 'dir' on Windows)