fix(cso): pass native release gates

Co-Authored-By: OpenAI Codex <noreply@openai.com>
This commit is contained in:
Garry TanandOpenAI Codex committed 2026-09-11 18:08:53 +00:00
1 parent 99b00422a8
commit 9fda83eacc
15 files changed
+134 -31

No files matched your search

+8 -1
View File
@@ -34,11 +34,18 @@ RUN printf 'Acquire::Retries "5";\nAcquire::http::Timeout "30";\nAcquire::https:
# poppler-utils: make-pdf's e2e gates hard-require pdftotext/pdffonts/pdfinfo in CI.
RUN for i in 1 2 3; do \
apt-get update && apt-get install -y --no-install-recommends \
git curl unzip xz-utils ca-certificates jq bc gpg python3 file poppler-utils && break || \
git curl unzip xz-utils ca-certificates jq bc gpg python3 file poppler-utils gcc libc6-dev && break || \
(echo "apt retry $i/3 after failure"; sleep 10); \
done \
&& rm -rf /var/lib/apt/lists/*
# Direct builds produce the trusted CSO launcher and watchdog. Check the exact
# static-C capability here so the cached eval image cannot reach a slice without it.
RUN printf 'int main(void) { return 0; }\n' > /tmp/gstack-cso-cc-probe.c \
&& cc -std=c11 -static /tmp/gstack-cso-cc-probe.c -o /tmp/gstack-cso-cc-probe \
&& /tmp/gstack-cso-cc-probe \
&& rm -f /tmp/gstack-cso-cc-probe.c /tmp/gstack-cso-cc-probe
# GitHub CLI
RUN curl --retry 5 --retry-delay 5 --retry-connrefused -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
| gpg --dearmor -o /usr/share/keyrings/githubcli-archive-keyring.gpg \
+3
View File
@@ -1,6 +1,9 @@
/* Minimal trusted CSO launcher. Linux builds are static so LD_PRELOAD cannot
* execute before the environment is replaced. macOS builds are signed with
* the hardened runtime by build/setup before use. */
#ifdef __APPLE__
#define _DARWIN_C_SOURCE 1
#endif
#define _POSIX_C_SOURCE 200809L
#define _XOPEN_SOURCE 700
#include <errno.h>
+4 -1
View File
@@ -68,7 +68,7 @@ int wmain(int argc, wchar_t **argv) {
if (!job || !SetInformationJobObject(job, JobObjectExtendedLimitInformation, &limits, (DWORD)sizeof(limits))) return 69;
STARTUPINFOW startup = {0}; PROCESS_INFORMATION child = {0}; startup.cb = (DWORD)sizeof(startup);
if (!CreateProcessW(argv[2], command, NULL, NULL, TRUE, CREATE_SUSPENDED, NULL, NULL, &startup, &child)) {
fputs("gstack-cso: publication command could not start\n", stderr); return 69;
fwprintf(stderr, L"gstack-cso: publication command could not start (Windows error %lu)\n", (unsigned long)GetLastError()); return 69;
}
if (!AssignProcessToJobObject(job, child.hProcess) || ResumeThread(child.hThread) == (DWORD)-1) {
TerminateProcess(child.hProcess, 69); CloseHandle(child.hThread); CloseHandle(child.hProcess); return 69;
@@ -80,6 +80,9 @@ int wmain(int argc, wchar_t **argv) {
return (int)code;
}
#else
#ifdef __APPLE__
#define _DARWIN_C_SOURCE 1
#endif
#define _POSIX_C_SOURCE 200809L
#include <errno.h>
#include <fcntl.h>
+1 -1
View File
@@ -30,7 +30,7 @@ export class VerificationAttemptError extends CsoError {
constructor(public causeError:CsoError,public attempt:FailedVerificationAttempt){super(causeError.code,`${causeError.message}; before-phase evidence retained as attempt ${attempt.id}`);this.name='VerificationAttemptError';}
}
async function attemptGuard(runDir:string,work:string,watchdog:string,deadline:number):Promise<()=>Promise<void>>{
const control=secureDirectory(join(runDir,'supervision',work.slice(work.lastIndexOf('/')+1)));secureDirectory(work);const ready=join(control,'attempt.ready'),terminal=join(control,'attempt.terminal'),stopped=join(control,'attempt.stopped');
const control=secureDirectory(join(runDir,'supervision',basename(work)));secureDirectory(work);const ready=join(control,'attempt.ready'),terminal=join(control,'attempt.terminal'),stopped=join(control,'attempt.stopped');
const child=spawn(watchdog,['--attempt-owner',String(process.pid),'--deadline',String(Math.ceil(deadline/1000)),'--control-dir',control,'--work-root',work,'--run-root',runDir],{cwd:control,env:{PATH:'/usr/bin:/bin'},detached:true,stdio:'ignore'});let failed=false;child.once('error',()=>{failed=true;});child.unref();for(let i=0;i<100&&!failed&&!fs.existsSync(ready);i++)await new Promise(resolve=>setTimeout(resolve,10));let alive=false;try{if(child.pid){process.kill(child.pid,0);alive=true;}}catch{}if(failed||!alive||!fs.existsSync(ready)){try{if(child.pid)process.kill(child.pid,'SIGKILL');}catch{}fs.rmSync(work,{recursive:true,force:true});throw new CsoError('ISOLATION_FAILED','Attempt execution-copy watchdog failed its startup handshake');}
return async()=>{fs.rmSync(work,{recursive:true,force:true});fs.writeFileSync(terminal,'normal cleanup complete\n',{mode:0o600,flag:'wx'});for(let i=0;i<100&&!fs.existsSync(stopped);i++)await new Promise(resolve=>setTimeout(resolve,10));if(!fs.existsSync(stopped))throw new CsoError('ISOLATION_FAILED','Attempt watchdog did not acknowledge execution-copy cleanup');};
}
+9 -1
View File
@@ -1,4 +1,7 @@
/* Independent CSO lease watchdog. It accepts only exact journaled container IDs. */
#ifdef __APPLE__
#define _DARWIN_C_SOURCE 1
#endif
#define _XOPEN_SOURCE 700
#include <errno.h>
#include <dirent.h>
@@ -136,7 +139,12 @@ static void marker(const char *run_dir,const char *name,const char *value){
if(snprintf(path,sizeof path,"%s/%s",run_dir,name)>=(int)sizeof path)return;
if(snprintf(tmp,sizeof tmp,"%s/%s.tmp.%ld",run_dir,name,(long)getpid())>=(int)sizeof tmp)return;
int fd=open(tmp,O_WRONLY|O_CREAT|O_EXCL|O_NOFOLLOW,0600);if(fd<0)return;
(void)write(fd,value,strlen(value));(void)fsync(fd);close(fd);(void)rename(tmp,path);
size_t remaining=strlen(value);const char *cursor=value;int failed=0;
while(remaining){ssize_t written=write(fd,cursor,remaining);if(written>0){cursor+=written;remaining-=(size_t)written;continue;}if(written<0&&errno==EINTR)continue;failed=1;break;}
if(!failed&&fsync(fd))failed=1;
if(close(fd))failed=1;
if(!failed&&!rename(tmp,path))return;
(void)unlink(tmp);
}
static int descendant(const char *root,const char *path){size_t n=strlen(root);return n>1&&!strncmp(root,path,n)&&path[n]=='/';}
static int remove_tree(const char *path){
+6 -1
View File
@@ -283,5 +283,10 @@ cso_valid_generation "$CSO_STAGE_GENERATION"||{ echo 'Staged CSO generation mani
"$CSO_STAGE_LAUNCHER" --version >/dev/null
cso_checkpoint validated
case "${BASH:-}" in /*) CSO_PUBLISH_SHELL=$BASH;; *) echo 'CSO publication requires an absolute Bash executable.' >&2;exit 1;;esac
if [ -n "$CSO_EXE" ];then
[ -f /usr/bin/bash.exe ] || { echo 'CSO publication requires the Git Bash executable.' >&2;exit 1; }
CSO_PUBLISH_SHELL="$(cygpath -aw /usr/bin/bash.exe)"
else
case "${BASH:-}" in /*) CSO_PUBLISH_SHELL=$BASH;; *) echo 'CSO publication requires an absolute Bash executable.' >&2;exit 1;;esac
fi
exec "$CSO_STAGE_LOCKER" "$CSO_BUILD_ROOT/bin" "$CSO_PUBLISH_SHELL" "$CSO_BUILD_ROOT/scripts/build-cso.sh" __publish_locked "$CSO_STAGE"
+24
View File
@@ -252,6 +252,30 @@ export const KNOWN_WINDOWS_INCOMPATIBLE: Array<{ file: string; reason: string }>
file: 'browse/test/security-audit-r2.test.ts',
reason: 'symlink-attack fixtures (evil-link) need Developer Mode CI runners lack; expect(toThrow) fires unhandled on Windows',
},
// CSO comprehensive execution is qualified only for Linux containers behind
// the POSIX watchdog and Unix-domain registry broker. Keep the portable
// static/parser contracts in the Windows lane while leaving these exact
// containment suites to the Linux and macOS gates.
{
file: 'test/cso-preparation-adversarial.test.ts',
reason: 'exercises POSIX prepared-tree and archive-cache containment for qualified Linux Docker execution, which Windows does not admit',
},
{
file: 'test/cso-preparation-container.test.ts',
reason: 'asserts POSIX permission and symlink semantics for inert exports consumed by qualified Linux Docker execution',
},
{
file: 'test/cso-preparation-executor.test.ts',
reason: 'executes the Linux Docker acquisition path and its Unix-domain registry broker; comprehensive execution is unavailable on Windows',
},
{
file: 'test/cso-verification-cleanup.test.ts',
reason: 'spawns the POSIX detached watchdog used by contained repair verification, which Windows intentionally leaves unavailable',
},
{
file: 'test/cso-witness.test.ts',
reason: 'tests the contained repair witness with POSIX private-directory and compiled-helper assumptions; comprehensive execution is unavailable on Windows',
},
];
// Force-include overrides: files a WINDOWS_FRAGILE_PATTERNS regex excludes for
+18
View File
@@ -87,6 +87,24 @@ function reviewedInputs(): any {
}
describe('CSO build and distribution wiring', () => {
test('POSIX helpers expose Darwin no-follow flags before system headers', () => {
for (const relative of ['lib/cso/launcher.c', 'lib/cso/watchdog.c', 'lib/cso/publish-lock.c']) {
const source = readFileSync(join(ROOT, relative), 'utf8');
const darwinFeature = source.indexOf('#define _DARWIN_C_SOURCE 1');
const fileFlags = source.indexOf('#include <fcntl.h>');
expect(darwinFeature, relative).toBeGreaterThanOrEqual(0);
expect(fileFlags, relative).toBeGreaterThan(darwinFeature);
expect(source, relative).toContain('O_NOFOLLOW');
}
});
test('the cached eval image proves the static C toolchain required by direct builds', () => {
const dockerfile = readFileSync(join(ROOT, '.github/docker/Dockerfile.ci'), 'utf8');
expect(dockerfile).toMatch(/\bgcc libc6-dev\b/);
expect(dockerfile).toContain('cc -std=c11 -static /tmp/gstack-cso-cc-probe.c');
expect(dockerfile).toContain('/tmp/gstack-cso-cc-probe');
});
test.skipIf(process.platform === 'win32')('real build script supplies all startup-hardening flags and compiles its watchdog', () => {
const dir = buildFixture(), log = join(dir, 'compiler.log');
const r = fakeBuild(dir);
+1 -1
View File
@@ -5,7 +5,7 @@ const enabled=process.env.GSTACK_CSO_DOCKER_TESTS==='1',suite=enabled?describe:d
function exec(file:string,args:string[],env:Record<string,string>={}){const r=spawnSync(file,args,{encoding:'utf8',env:{PATH:'/usr/local/bin:/usr/bin:/bin',HOME:root,GSTACK_HOME:state,DOCKER_HOST:'unix:///var/run/docker.sock',...env},timeout:120_000});if(r.status!==0)throw new Error(`${file} failed: ${r.stderr}`);return r.stdout.trim();}
beforeAll(()=>{if(!enabled)return;root=fs.mkdtempSync(path.join(os.tmpdir(),'cso-docker-'));state=path.join(root,'state');process.env.GSTACK_HOME=state;watchdog=path.resolve(import.meta.dir,'../bin/gstack-cso-watchdog');if(!fs.existsSync(watchdog))throw new Error('GSTACK_CSO_DOCKER_TESTS=1 requires the compiled watchdog');
const source=`#include <arpa/inet.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <netdb.h>\n#include <netinet/in.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/socket.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <unistd.h>\nstatic int blocked4(const char *ip,int port){int s=socket(AF_INET,SOCK_STREAM,0);struct sockaddr_in a={.sin_family=AF_INET,.sin_port=htons(port)};inet_pton(AF_INET,ip,&a.sin_addr);int r=connect(s,(void*)&a,sizeof a);close(s);return r!=0;}\nstatic int blocked6(void){int s=socket(AF_INET6,SOCK_STREAM,0);struct sockaddr_in6 a={.sin6_family=AF_INET6,.sin6_port=htons(443)};inet_pton(AF_INET6,"2606:4700:4700::1111",&a.sin6_addr);int r=connect(s,(void*)&a,sizeof a);close(s);return r!=0;}\nint main(int argc,char**argv){if(strstr(argv[0],"entrypoint")){if(argc<2||argv[1][0]!='/')return 64;execv(argv[1],argv+1);return 69;}if(strstr(argv[0],"sleep")){for(;;)sleep(3600);}if(strstr(argv[0],"reader")){char a[16]={0},b[16]={0};FILE*x=fopen("/source/source.txt","r"),*y=fopen("/policy/verification.json","r");if(!x||!y||!fgets(a,sizeof a,x)||!fgets(b,sizeof b,y))return 12;fclose(x);fclose(y);if(strcmp(a,"source\\n")||strcmp(b,"policy\\n"))return 13;puts("INPUTS_OK");return 0;}if(strstr(argv[0],"server")){int s=socket(AF_INET,SOCK_STREAM,0),c;struct sockaddr_in a={.sin_family=AF_INET,.sin_port=htons(34567),.sin_addr.s_addr=htonl(INADDR_LOOPBACK)};int one=1;setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&one,sizeof one);if(bind(s,(void*)&a,sizeof a)||listen(s,2))return 2;for(;;){c=accept(s,0,0);if(c>=0){write(c,"ok",2);close(c);}}}int fd=open("/should-not-write",O_WRONLY|O_CREAT,0600);if(fd>=0)return 10;FILE*f=fopen("/proc/self/status","r");char line[256];int caps=1,nnp=0;while(f&&fgets(line,sizeof line,f)){if(!strncmp(line,"CapEff:",7))caps=strtoull(line+7,0,16)!=0;if(!strncmp(line,"NoNewPrivs:",11))nnp=atoi(line+11);}if(f)fclose(f);int s=socket(AF_INET,SOCK_STREAM,0);struct sockaddr_in a={.sin_family=AF_INET,.sin_port=htons(34567),.sin_addr.s_addr=htonl(INADDR_LOOPBACK)};int loop=connect(s,(void*)&a,sizeof a)==0;close(s);struct addrinfo*h=0;int dns=getaddrinfo("example.com",0,0,&h);if(h)freeaddrinfo(h);if(getuid()==0||caps||!nnp||!loop||!blocked4("8.8.8.8",443)||!blocked4("169.254.169.254",80)||!blocked6()||dns==0)return 11;puts("CONTAINMENT_OK");return 0;}\n`;
fs.writeFileSync(path.join(root,'probe.c'),source);exec('/usr/bin/cc',['-static','-O2',path.join(root,'probe.c'),'-o',path.join(root,'probe')]);exec('/usr/bin/cc',['-static','-O2',path.join(import.meta.dir,'fixtures/cso-http-smoke.c'),'-o',path.join(root,'http-server')]);fs.writeFileSync(path.join(root,'Dockerfile'),'FROM scratch\nCOPY probe /opt/cso/entrypoint\nCOPY probe /bin/sleep\nCOPY probe /server\nCOPY probe /client\nCOPY probe /reader\nCOPY probe /policy/.keep\nCOPY probe /source/.keep\nCOPY http-server /http-server\nUSER 10001:10001\nENTRYPOINT ["/opt/cso/entrypoint"]\n');const tag=`gstack-cso-fixture:${process.pid}`;exec('/usr/bin/docker',['--host','unix:///var/run/docker.sock','build','--network=none','--tag',tag,root]);image=exec('/usr/bin/docker',['--host','unix:///var/run/docker.sock','image','inspect','--format','{{.Id}}',tag]);fs.writeFileSync(path.join(root,'VolumeDockerfile'),`FROM ${image}\nVOLUME ["/unbounded"]\n`);const volumeTag=`gstack-cso-volume-fixture:${process.pid}`;exec('/usr/bin/docker',['--host','unix:///var/run/docker.sock','build','--network=none','--file',path.join(root,'VolumeDockerfile'),'--tag',volumeTag,root]);volumeImage=exec('/usr/bin/docker',['--host','unix:///var/run/docker.sock','image','inspect','--format','{{.Id}}',volumeTag]);});
fs.writeFileSync(path.join(root,'probe.c'),source);exec('/usr/bin/cc',['-static','-O2',path.join(root,'probe.c'),'-o',path.join(root,'probe')]);exec('/usr/bin/cc',['-static','-O2',path.join(import.meta.dir,'fixtures/cso-http-smoke.c'),'-o',path.join(root,'http-server')]);fs.writeFileSync(path.join(root,'Dockerfile'),'FROM scratch\nCOPY probe /opt/cso/entrypoint\nCOPY probe /bin/sleep\nCOPY probe /server\nCOPY probe /client\nCOPY probe /reader\nCOPY probe /policy/.keep\nCOPY probe /source/.keep\nCOPY http-server /http-server\nUSER 10001:10001\nENTRYPOINT ["/opt/cso/entrypoint"]\n');const tag=`gstack-cso-fixture:${process.pid}`;exec('/usr/bin/docker',['--host','unix:///var/run/docker.sock','build','--network=none','--tag',tag,root]);image=exec('/usr/bin/docker',['--host','unix:///var/run/docker.sock','image','inspect','--format','{{.Id}}',tag]);fs.writeFileSync(path.join(root,'VolumeDockerfile'),`FROM ${tag}\nVOLUME ["/unbounded"]\n`);const volumeTag=`gstack-cso-volume-fixture:${process.pid}`;exec('/usr/bin/docker',['--host','unix:///var/run/docker.sock','build','--network=none','--file',path.join(root,'VolumeDockerfile'),'--tag',volumeTag,root]);volumeImage=exec('/usr/bin/docker',['--host','unix:///var/run/docker.sock','image','inspect','--format','{{.Id}}',volumeTag]);});
afterAll(()=>{if(root){for(const candidate of [volumeImage,image])try{if(candidate)spawnSync('/usr/bin/docker',['--host','unix:///var/run/docker.sock','image','rm','--force',candidate],{stdio:'ignore',timeout:30_000});}catch{}fs.rmSync(root,{recursive:true,force:true});}delete process.env.GSTACK_HOME;});
suite('CSO Docker containment integration',()=>{
+2 -2
View File
@@ -143,7 +143,7 @@ describe('trusted CSO image provisioning',()=>{
await expect(openLocalCatalogImageSession({HOME:os.tmpdir(),DOCKER_HOST:'tcp://127.0.0.1:2375'})).rejects.toThrow('Remote TCP');
});
test('doctor and setup command contracts share exact local availability without doctor downloads',async()=>{
test.skipIf(process.platform==='win32')('doctor and setup command contracts share exact local availability without doctor downloads',async()=>{
const repo=nodeRepo(),runtimeCatalog=completeRuntimeCatalogFixture('doctor-cli-fixture'),scanners=scannerCatalog(),fake=session({present:()=>false}),dependencies:CsoCliDependencies={
runtimeCatalog,scannerCatalog:scanners,catalogImageSession:async()=>fake.value,watchdogPath:()=>'/trusted/watchdog',
};
@@ -163,7 +163,7 @@ describe('trusted CSO image provisioning',()=>{
await expect(dispatchCsoCommand('provision-images',['--per-image-seconds','301'],dependencies)).rejects.toThrow('5..300');
});
test('doctor includes the required PostgreSQL sidecar in Rails readiness without pulling',async()=>{
test.skipIf(process.platform==='win32')('doctor includes the required PostgreSQL sidecar in Rails readiness without pulling',async()=>{
const repo=railsPostgresRepo(),runtimeCatalog=completeRuntimeCatalogFixture('doctor-rails-postgresql-fixture'),fake=session({present:entry=>!entry.id.includes('postgresql')}),dependencies:CsoCliDependencies={
runtimeCatalog,scannerCatalog:scannerCatalog(),catalogImageSession:async()=>fake.value,watchdogPath:()=>'/trusted/watchdog',
};
+11 -2
View File
@@ -8,11 +8,20 @@ import { capture } from '../lib/cso/snapshot';
const roots:string[]=[];
afterEach(()=>{for(const root of roots.splice(0))fs.rmSync(root,{recursive:true,force:true});});
function trustedGit():string{
const executable=Bun.which('git');
if(!executable)throw new Error('git is required for the snapshot disappearance fixture');
return executable;
}
function gitEnvironment(home:string):NodeJS.ProcessEnv{
return{...process.env,HOME:home,GIT_CONFIG_NOSYSTEM:'1',GIT_CONFIG_GLOBAL:process.platform==='win32'?'NUL':'/dev/null',GIT_TERMINAL_PROMPT:'0'};
}
function fixture(){
const root=fs.mkdtempSync(path.join(os.tmpdir(),'cso-snapshot-disappearance-'));roots.push(root);
const repo=path.join(root,'repo'),runDir=path.join(root,'run');
fs.mkdirSync(repo);fs.mkdirSync(runDir,{mode:0o700});
const git=(...args:string[])=>{const result=spawnSync('/usr/bin/git',['-C',repo,...args],{encoding:'utf8',env:{HOME:root,PATH:'/usr/bin:/bin'},timeout:30_000});if(result.status)throw new Error(result.stderr);return result.stdout.trim();};
const git=(...args:string[])=>{const result=spawnSync(trustedGit(),['-C',repo,...args],{encoding:'utf8',env:gitEnvironment(root),timeout:30_000});if(result.status)throw new Error(result.stderr);return result.stdout.trim();};
git('init','-q');git('config','user.email','fixture@example.test');git('config','user.name','Fixture');
const tracked=path.join(repo,'tracked.txt');fs.writeFileSync(tracked,'security-relevant source\n');git('add','tracked.txt');git('commit','-qm','base');
return{repo,runDir,tracked,parked:path.join(repo,'.tracked.txt.parked')};
@@ -49,7 +58,7 @@ describe('CSO snapshot source-disappearance races',()=>{
});
test.skipIf(process.platform==='win32')('binds the audited repository root while source is copied',async()=>{
const root=fs.mkdtempSync(path.join(os.tmpdir(),'cso-snapshot-root-swap-'));roots.push(root);const repo=path.join(root,'repo'),parked=path.join(root,'parked'),decoy=path.join(root,'decoy'),gitDir=path.join(root,'gitdir'),runDir=path.join(root,'run'),tracked=path.join(repo,'tracked.txt');fs.mkdirSync(repo);fs.mkdirSync(runDir,{mode:0o700});
const run=(...args:string[])=>{const result=spawnSync('/usr/bin/git',args,{encoding:'utf8',env:{HOME:root,PATH:'/usr/bin:/bin'},timeout:30_000});if(result.status)throw new Error(result.stderr);};
const run=(...args:string[])=>{const result=spawnSync(trustedGit(),args,{encoding:'utf8',env:gitEnvironment(root),timeout:30_000});if(result.status)throw new Error(result.stderr);};
run('init','-q',`--separate-git-dir=${gitDir}`,repo);run('-C',repo,'config','user.email','fixture@example.test');run('-C',repo,'config','user.name','Fixture');fs.writeFileSync(tracked,'secure original source\n');run('-C',repo,'add','tracked.txt');run('-C',repo,'commit','-qm','base');fs.mkdirSync(decoy);fs.writeFileSync(path.join(decoy,'.git'),`gitdir: ${gitDir}\n`);fs.writeFileSync(path.join(decoy,'tracked.txt'),'vulnerable decoy source\n');
const lstat=fs.lstatSync;let seen=0,injected=false,failure:unknown;
const patched=spyOn(fs,'lstatSync').mockImplementation(((candidate:any,options?:any)=>{if(path.resolve(String(candidate))===tracked&&++seen===2){injected=true;fs.renameSync(repo,parked);fs.renameSync(decoy,repo);}return options===undefined?lstat(candidate):lstat(candidate,options);}) as typeof fs.lstatSync);
+4 -4
View File
@@ -126,14 +126,14 @@ describe('private state and process output',()=>{
expect(injected).toBe(true);expect(probes).toBe(532);expect(entered).toBe(false);expect(caught).toMatchObject({code:'INSUFFICIENT_CAPACITY'});expect(fs.existsSync(temporary)).toBe(false);expect(fs.readdirSync(leases)).toEqual([]);
});
test('a settled publication remains bound to the originally observed inode',()=>{
const dir=tmp(),token='4'.repeat(32),publisherPid=2147483647,target=path.join(dir,`${token}.json`),temporary=`${target}.tmp.${publisherPid}.abcdef12`,owner=JSON.stringify({pid:publisherPid,token,createdAt:0})+'\n';
const dir=tmp(),token='4'.repeat(32),publisherPid=2147483647,target=path.join(dir,`${token}.json`),temporary=`${target}.tmp.${publisherPid}.abcdef12`,parked=`${target}.replaced`,owner=JSON.stringify({pid:publisherPid,token,createdAt:0})+'\n';
fs.writeFileSync(temporary,owner,{mode:0o600,flag:'wx'});fs.linkSync(temporary,target);const original=fs.statSync(target).ino,lstat=fs.lstatSync;let targetReads=0,replaced=false,caught:unknown;
const reader=spyOn(fs,'lstatSync').mockImplementation(((file:any,options?:any)=>{
if(String(file)===target&&++targetReads===2){fs.unlinkSync(target);fs.unlinkSync(temporary);fs.writeFileSync(target,owner,{mode:0o600,flag:'wx'});replaced=true;}
if(String(file)===target&&++targetReads===2){fs.unlinkSync(target);fs.renameSync(temporary,parked);fs.writeFileSync(target,owner,{mode:0o600,flag:'wx'});replaced=true;}
return options===undefined?lstat(file):lstat(file,options);
}) as typeof fs.lstatSync);
try{discardAtomicNoReplaceTemp(temporary,publisherPid,{label:'Test publication',maxBytes:4096,validate:(value,pid)=>{expect((value as any).token).toBe(token);expect(pid).toBe(publisherPid);}});}catch(error){caught=error;}finally{reader.mockRestore();}
expect(replaced).toBe(true);expect(caught).toMatchObject({code:'UNSAFE_PATH'});expect(fs.statSync(target).ino).not.toBe(original);
expect(replaced).toBe(true);expect(caught).toMatchObject({code:'UNSAFE_PATH'});expect(fs.statSync(parked).ino).toBe(original);expect(fs.statSync(target).ino).not.toBe(original);
});
test('a link transition on an open inode cannot launder a replacement pathname',()=>{
const dir=tmp();expect(withLock(dir,()=>1)).toBe(1);
@@ -165,7 +165,7 @@ describe('private state and process output',()=>{
test('post-link verification failure cleans every recorded lease phase',()=>{const dir=tmp();expect(withLock(dir,()=>1)).toBe(1);const leases=path.join(dir,'.mutation-lock-leases'),fakeToken='f'.repeat(32),fakeTemp=path.join(leases,`${fakeToken}.json.tmp.${process.pid}.deadbeef`),link=fs.linkSync,injectedOwner=JSON.stringify({pid:process.pid,token:fakeToken,createdAt:Date.now()})+'\n';let injected=false,caught:unknown;const publisher=spyOn(fs,'linkSync').mockImplementation(((source:any,target:any)=>{const result=link(source,target);if(!injected&&String(target).includes('.active.')){injected=true;fs.writeFileSync(fakeTemp,injectedOwner,{mode:0o600,flag:'wx'});}return result;}) as typeof fs.linkSync);try{withLock(dir,()=>1);}catch(error){caught=error;}finally{publisher.mockRestore();}expect(injected).toBe(true);expect(caught).toMatchObject({code:'INSUFFICIENT_CAPACITY'});expect(fs.readdirSync(leases)).toEqual([path.basename(fakeTemp)]);fs.unlinkSync(fakeTemp);expect(withLock(dir,()=>2)).toBe(2);expect(fs.readdirSync(leases)).toEqual([]);});
test('an async callback retains its lease until settlement without blocking its own event loop',async()=>{const dir=tmp();let release!:()=>void;const pending=new Promise<void>(resolve=>{release=resolve;}),outer=withLock(dir,async()=>{await pending;return 7;}),started=Date.now();expect(()=>withLock(dir,()=>99)).toThrow('Another operation in this helper');expect(Date.now()-started).toBeLessThan(200);release();expect(await outer).toBe(7);expect(withLock(dir,()=>9)).toBe(9);});
test('a synchronous exact-release failure is attempted only once',()=>{const dir=tmp(),lstat=fs.lstatSync;let observed=0,reader:any;try{expect(()=>withLock(dir,()=>{const leases=path.join(dir,'.mutation-lock-leases'),names=fs.readdirSync(leases),candidate=path.join(leases,names.find(name=>name.endsWith('.json'))!),active=path.join(leases,names.find(name=>name.includes('.active.'))!),value=fs.readFileSync(active);fs.unlinkSync(active);fs.writeFileSync(active,value,{mode:0o600,flag:'wx'});reader=spyOn(fs,'lstatSync').mockImplementation(((file:any,options?:any)=>{if(String(file)===candidate)observed++;return options===undefined?lstat(file):lstat(file,options);}) as typeof fs.lstatSync);})).toThrow('active phase changed before cleanup');expect(observed).toBe(1);}finally{reader?.mockRestore();}});
test('exact release rejects active or decision inode substitution and overrides callback success or failure',()=>{for(const phase of ['active','decision'] as const){const dir=tmp();let replacement='';expect(()=>withLock(dir,()=>{const leases=path.join(dir,'.mutation-lock-leases'),name=fs.readdirSync(leases).find(value=>phase==='active'?value.includes('.active.'):value.endsWith('.decision'))!,lease=path.join(leases,name),value=fs.readFileSync(lease);fs.unlinkSync(lease);fs.writeFileSync(lease,value,{mode:0o600,flag:'wx'});replacement=lease;if(phase==='active')throw new Error('callback failed');return 1;})).toThrow(/changed before (cleanup|exact release)/);expect(fs.existsSync(replacement)).toBe(true);fs.rmSync(dir,{recursive:true,force:true});}});
test('exact release rejects active or decision inode substitution and overrides callback success or failure',()=>{for(const phase of ['active','decision'] as const){const dir=tmp();let replacement='',parked='';expect(()=>withLock(dir,()=>{const leases=path.join(dir,'.mutation-lock-leases'),name=fs.readdirSync(leases).find(value=>phase==='active'?value.includes('.active.'):value.endsWith('.decision'))!,lease=path.join(leases,name),value=fs.readFileSync(lease);parked=`${lease}.replaced`;fs.renameSync(lease,parked);fs.writeFileSync(lease,value,{mode:0o600,flag:'wx'});replacement=lease;if(phase==='active')throw new Error('callback failed');return 1;})).toThrow(/changed before (cleanup|exact release)/);expect(fs.existsSync(replacement)).toBe(true);expect(fs.existsSync(parked)).toBe(true);expect(fs.statSync(replacement).ino).not.toBe(fs.statSync(parked).ino);fs.rmSync(dir,{recursive:true,force:true});}});
test('concurrent stale-lock recovery never admits overlapping report writers',async()=>{const dir=tmp(),lock=path.join(dir,'.mutation-lock'),script=path.join(dir,'racer.ts');fs.mkdirSync(lock);fs.writeFileSync(path.join(lock,'owner.json'),JSON.stringify({pid:2147483647,token:'stale',createdAt:0,expiresAt:0}));fs.writeFileSync(script,`import fs from 'node:fs';import path from 'node:path';import {withLock} from ${JSON.stringify(path.resolve(import.meta.dir,'../lib/cso/state.ts'))};const dir=process.env.RACE_DIR!;try{await withLock(dir,async()=>{const active=path.join(dir,'active');try{fs.writeFileSync(active,String(process.pid),{flag:'wx'});}catch{fs.appendFileSync(path.join(dir,'overlap'),'yes\\n');}await Bun.sleep(50);try{if(fs.readFileSync(active,'utf8')===String(process.pid))fs.unlinkSync(active);}catch{}});}catch{}`);const children=Array.from({length:8},()=>spawn(process.execPath,[script],{env:{...process.env,RACE_DIR:dir},stdio:'ignore'}));await Promise.all(children.map(child=>new Promise<void>(resolve=>child.on('close',()=>resolve()))));expect(fs.existsSync(path.join(dir,'overlap'))).toBe(false);});
test('concurrent recovery of one dead hard-link publication has a winner and no raw race errors',async()=>{
const dir=tmp(),barrier=path.join(dir,'barrier'),script=path.join(dir,'recovery-racer.ts');fs.mkdirSync(barrier);expect(withLock(dir,()=>1)).toBe(1);
+1
View File
@@ -84,6 +84,7 @@ describe('CSO native Windows build contract', () => {
expect(build).toContain('-LockOutputPath "$(cygpath -w "$CSO_STAGE_LOCKER")"');
expect(build).toContain('-CoreSha256 "$CSO_CORE_SHA256"');
expect(build).toContain('-GitExePath "$(cygpath -aw "$CSO_WINDOWS_GIT")"');
expect(build).toContain('CSO_PUBLISH_SHELL="$(cygpath -aw /usr/bin/bash.exe)"');
expect(build).not.toContain('launcher-windows.ts');
expect(fs.existsSync(path.join(ROOT, 'lib/cso/launcher-windows.ts'))).toBe(false);
expect(msvc).toContain('Launch-VsDevShell.ps1');
+27 -17
View File
@@ -127,33 +127,38 @@ describe('CSO producer provider policies', () => {
});
test('passes only selected provider auth plus safe execution inputs and strips Docker credentials', () => {
const fixtureRoot = join(tmpdir(), 'gstack-provider-environment-policy');
const state = join(fixtureRoot, 'state');
const source = join(fixtureRoot, 'source');
const helpers = join(fixtureRoot, 'helpers');
const work = join(fixtureRoot, 'work');
const sourceEnv = {
PATH: '/usr/bin', HOME: '/home/eval', LANG: 'C.UTF-8', LC_ALL: 'C.UTF-8', TZ: 'UTC',
GSTACK_HOME: '/state', GSTACK_SESSION_KIND: 'spawned', GSTACK_HEADLESS: '1',
GSTACK_HOME: state, GSTACK_SESSION_KIND: 'spawned', GSTACK_HEADLESS: '1',
OPENAI_API_KEY: 'openai-auth', ANTHROPIC_API_KEY: 'anthropic-auth', CLAUDE_CODE_OAUTH_TOKEN: 'claude-auth',
GEMINI_API_KEY: 'gemini-auth', GOOGLE_CLOUD_PROJECT: 'project',
CSO_EVAL_PAID: '1', AWS_SECRET_ACCESS_KEY: 'unrelated',
DOCKER_HOST: 'tcp://remote.example:2376', DOCKER_CONFIG: '/credentials', DOCKER_CERT_PATH: '/certs',
};
const safe = { PATH: '/usr/bin', HOME: '/home/eval', LANG: 'C.UTF-8', LC_ALL: 'C.UTF-8', TZ: 'UTC', GSTACK_HOME: '/state', GSTACK_SESSION_KIND: 'spawned', GSTACK_HEADLESS: '1' };
const safe = { PATH: '/usr/bin', HOME: '/home/eval', LANG: 'C.UTF-8', LC_ALL: 'C.UTF-8', TZ: 'UTC', GSTACK_HOME: state, GSTACK_SESSION_KIND: 'spawned', GSTACK_HEADLESS: '1' };
expect(csoProducerChildEnvironment('gpt', sourceEnv)).toEqual({ ...safe, OPENAI_API_KEY: 'openai-auth' });
expect(csoProducerChildEnvironment('claude', sourceEnv)).toEqual({ ...safe, ANTHROPIC_API_KEY: 'anthropic-auth', CLAUDE_CODE_OAUTH_TOKEN: 'claude-auth' });
expect(csoProducerChildEnvironment('gemini', sourceEnv)).toEqual({ ...safe, GEMINI_API_KEY: 'gemini-auth', GOOGLE_CLOUD_PROJECT: 'project' });
const helper = helperAt('/helpers');
const producer = policy('/state', '/source', helper);
const common = { prompt: '', workdir: '/work', timeoutMs: 1, csoProducer: producer };
const codexPaths = codexProducerPaths('/state');
const helper = helperAt(helpers);
const producer = policy(state, source, helper);
const common = { prompt: '', workdir: work, timeoutMs: 1, csoProducer: producer };
const codexPaths = codexProducerPaths(state);
expect(codexExecEnvironment(common, sourceEnv)).toEqual({
...safe, HOME: codexPaths.home, GSTACK_HOME: '/state/cso-home', CODEX_HOME: codexPaths.home, OPENAI_API_KEY: 'openai-auth',
...safe, HOME: codexPaths.home, GSTACK_HOME: join(state, 'cso-home'), CODEX_HOME: codexPaths.home, OPENAI_API_KEY: 'openai-auth',
});
const claudePaths = claudeProducerPaths('/state');
const claudePaths = claudeProducerPaths(state);
expect(claudeExecEnvironment(common, sourceEnv)).toEqual({
...safe, HOME: claudePaths.home, GSTACK_HOME: '/state/cso-home',
...safe, HOME: claudePaths.home, GSTACK_HOME: join(state, 'cso-home'),
ANTHROPIC_API_KEY: 'anthropic-auth', CLAUDE_CODE_OAUTH_TOKEN: 'claude-auth', CLAUDE_CODE_SUBPROCESS_ENV_SCRUB: '1',
});
const geminiPaths = geminiProducerPaths('/state');
const geminiPaths = geminiProducerPaths(state);
expect(geminiExecEnvironment(common, sourceEnv)).toEqual({
...safe, HOME: geminiPaths.home, GSTACK_HOME: '/state/cso-home',
...safe, HOME: geminiPaths.home, GSTACK_HOME: join(state, 'cso-home'),
GEMINI_API_KEY: 'gemini-auth', GOOGLE_API_KEY: 'gemini-auth', GOOGLE_CLOUD_PROJECT: 'project',
GEMINI_SANDBOX: 'false', GEMINI_TELEMETRY_ENABLED: 'false', GEMINI_TELEMETRY_LOG_PROMPTS: 'false',
GEMINI_CLI_TRUST_WORKSPACE: 'true', GEMINI_SYSTEM_MD: 'false', GEMINI_WRITE_SYSTEM_MD: 'false',
@@ -169,12 +174,17 @@ describe('CSO producer provider policies', () => {
});
test('preserves default provider environments and rejects producer escape-hatch arguments', () => {
const source = { PATH: '/bin', CSO_EVAL_PAID: '1', UNRELATED_SECRET: 'kept-by-default', GEMINI_API_KEY: 'key' };
const common = { prompt: '', workdir: '/work', timeoutMs: 1 };
const producer = policy('/state', '/source', helperAt('/helpers'));
expect(codexExecEnvironment(common, source)).toBe(source);
expect(claudeExecEnvironment(common, source)).toEqual({ ...source, GSTACK_HEADLESS: '1' });
expect(geminiExecEnvironment(common, source)).toEqual({ ...source, GOOGLE_API_KEY: 'key' });
const fixtureRoot = join(tmpdir(), 'gstack-provider-default-policy');
const state = join(fixtureRoot, 'state');
const source = join(fixtureRoot, 'source');
const helpers = join(fixtureRoot, 'helpers');
const work = join(fixtureRoot, 'work');
const sourceEnv = { PATH: '/bin', CSO_EVAL_PAID: '1', UNRELATED_SECRET: 'kept-by-default', GEMINI_API_KEY: 'key' };
const common = { prompt: '', workdir: work, timeoutMs: 1 };
const producer = policy(state, source, helperAt(helpers));
expect(codexExecEnvironment(common, sourceEnv)).toBe(sourceEnv);
expect(claudeExecEnvironment(common, sourceEnv)).toEqual({ ...sourceEnv, GSTACK_HEADLESS: '1' });
expect(geminiExecEnvironment(common, sourceEnv)).toEqual({ ...sourceEnv, GOOGLE_API_KEY: 'key' });
for (const invoke of [
() => codexExecArgs({ ...common, csoProducer: producer, extraArgs: ['--unsafe'] }, 'model'),
() => claudeExecArgs({ ...common, csoProducer: producer, extraArgs: ['--unsafe'] }, 'model'),
+15
View File
@@ -119,6 +119,21 @@ describe('test-free-shards: Windows curation', () => {
expect(reason.length).toBeGreaterThan(0);
}
});
test('excludes CSO containment suites while retaining portable image provisioning coverage', () => {
const containmentOnly = [
'test/cso-preparation-adversarial.test.ts',
'test/cso-preparation-container.test.ts',
'test/cso-preparation-executor.test.ts',
'test/cso-verification-cleanup.test.ts',
'test/cso-witness.test.ts',
];
const portable = 'test/cso-image-provisioning.test.ts';
const result = curateWindowsSafe([...containmentOnly, portable], ROOT);
expect(result.safe).toEqual([portable]);
expect(result.excluded.map(({ file }) => file).sort()).toEqual(containmentOnly.sort());
for (const { reason } of result.excluded) expect(reason).toMatch(/Linux|POSIX|Windows/);
});
});
describe('test-free-shards: sharding', () => {