Skip to content

Commit ac3cc13

Browse files
committed
secure CGI using seccomp
1 parent 0a82f3c commit ac3cc13

File tree

1 file changed

+72
-2
lines changed

1 file changed

+72
-2
lines changed

xidelcgi.lpr

+72-2
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,10 @@ function extractKindToString(kind: TExtractionKind): string;
134134
type TTimeoutThread = class(TThread)
135135
procedure Execute; override;
136136
end;
137+
procedure lockdownSyscalls;forward;
137138
procedure TTimeoutThread.Execute;
138139
begin
140+
lockdownSyscalls;
139141
self.sleep(10*1000);
140142
w('TIMEOUT');
141143
flush(xidelOutputFile);
@@ -215,8 +217,6 @@ procedure printPre(extractionKind: TExtractionKind);
215217
if (mycmdline.readFlag('case-sensitive')) then
216218
xqueryDefaultCollation:='http://www.w3.org/2005/xpath-functions/collation/codepoint';
217219

218-
startTimeoutThread;
219-
220220
if mycmdline.readFlag('raw') then begin
221221
case mycmdLine.readString('output-format') of
222222
//'xml', 'xml-wrapped': w('Content-Type: application/xml');
@@ -480,8 +480,78 @@ procedure lockdownFileAccess;
480480
patchExecutable(@FpExecve, @fpOpenOverride);
481481
end;
482482

483+
484+
type tscmp_filter_ctx = pointer;
485+
const SCMP_ACT_ERRNO = $00050000;
486+
const SCMP_ACT_ERRNO_SYSACCESS = SCMP_ACT_ERRNO or ESysEACCES;
487+
const SCMP_ACT_ALLOW = $7fff0000;
488+
const libseccomp = 'seccomp';
489+
function seccomp_init(def_action: uint32): tscmp_filter_ctx; cdecl; external libseccomp;
490+
function seccomp_load(ctx: tscmp_filter_ctx): cint; cdecl; external libseccomp;
491+
function seccomp_release(ctx: tscmp_filter_ctx): cint; cdecl; external libseccomp;
492+
function seccomp_rule_add(ctx: tscmp_filter_ctx; action: uint32; syscall: cint; arg_cnt: cardinal): cint; cdecl; external libseccomp;
493+
494+
{calls during test suite run
495+
access( //file functions
496+
brk(
497+
close( //test case loading
498+
exit_group(
499+
flock( //test case loading
500+
fstat( //test case loading
501+
futex( //icuu dynamic loading ? only ?
502+
getcwd( //test case loading
503+
getrandom( //icuu dynamic loading
504+
gettimeofday(
505+
lseek( //test case loading ? only ?
506+
mmap(
507+
mprotect( //icuu dynamic loading ? only ?
508+
munmap(
509+
newfstatat( //icuu dynamic loading ? only ?
510+
open( //tests
511+
openat( //icuu dynamic loading
512+
read(
513+
rt_sigprocmask( //FPU exceptions
514+
rt_sigreturn( //FPU exceptions
515+
stat( //test case loading ? only ?
516+
write(
517+
}
518+
procedure lockdownSyscalls;
519+
const syscalls: array of dword = (
520+
syscall_nr_brk,
521+
syscall_nr_exit_group,
522+
syscall_nr_gettimeofday,
523+
syscall_nr_mmap,
524+
syscall_nr_munmap,
525+
syscall_nr_read,
526+
syscall_nr_rt_sigprocmask,
527+
syscall_nr_rt_sigreturn,
528+
syscall_nr_write,
529+
syscall_nr_nanosleep
530+
);
531+
procedure checkerr(e: cint);
532+
begin
533+
if e < 0 then begin
534+
writeln('seccomp error');
535+
halt;
536+
end;
537+
end;
538+
539+
var ctx: pointer;
540+
i: Integer;
541+
begin
542+
ctx := seccomp_init(SCMP_ACT_ERRNO_SYSACCESS);
543+
for i := low(syscalls) to high(syscalls) do
544+
checkerr(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls[i], 0));
545+
checkerr(seccomp_load(ctx));
546+
checkerr(seccomp_release(ctx));
547+
end;
548+
483549
begin
484550
lockdownFileAccess;
551+
startTimeoutThread;
552+
LoadICU; //need to load it before file access is blocked
553+
lockdownSyscalls;
554+
485555

486556
//writeln(output,'Content-Type: text/plain');
487557
//writeln(output,'');

0 commit comments

Comments
 (0)