From ee4fc2b732eadf4d86547301c6b72b45a128c8af Mon Sep 17 00:00:00 2001 From: Yang Gao <6821729+criyle@users.noreply.github.com> Date: Wed, 1 Nov 2023 09:40:14 +0800 Subject: [PATCH] judge: add address space limit to language config (#682) --- packages/hydrojudge/src/judge/default.ts | 3 +++ packages/hydrojudge/src/judge/hack.ts | 3 +++ packages/hydrojudge/src/judge/interactive.ts | 3 +++ packages/hydrojudge/src/judge/run.ts | 3 +++ packages/hydrojudge/src/sandbox.ts | 2 ++ packages/hydrojudge/src/sandbox/interface.ts | 7 ++++++- packages/hydrooj/setting.yaml | 4 ++++ packages/utils/lib/lang.ts | 2 ++ 8 files changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/hydrojudge/src/judge/default.ts b/packages/hydrojudge/src/judge/default.ts index bc1ab556..389ee09b 100644 --- a/packages/hydrojudge/src/judge/default.ts +++ b/packages/hydrojudge/src/judge/default.ts @@ -14,6 +14,7 @@ const logger = new Logger('judge/default'); function judgeCase(c: NormalizedCase) { return async (ctx: Context, ctxSubtask: ContextSubTask, runner?: Function) => { + const { address_space_limit, process_limit } = ctx.session.getLang(ctx.lang); const res = await runQueued( ctx.execute.execute, { @@ -23,6 +24,8 @@ function judgeCase(c: NormalizedCase) { time: c.time, memory: c.memory, cacheStdoutAndStderr: true, + addressSpaceLimit: address_space_limit, + processLimit: process_limit, }, ); const { diff --git a/packages/hydrojudge/src/judge/hack.ts b/packages/hydrojudge/src/judge/hack.ts index d0141764..14d2fbb8 100644 --- a/packages/hydrojudge/src/judge/hack.ts +++ b/packages/hydrojudge/src/judge/hack.ts @@ -41,6 +41,7 @@ export async function judge(ctx: Context) { const message = `${validateResult.stdout || ''}\n${validateResult.stderr || ''}`.trim(); return ctx.end({ status: STATUS.STATUS_FORMAT_ERROR, message }); } + const { address_space_limit, process_limit } = ctx.session.getLang(ctx.lang); const res = await runQueued( execute.execute, { @@ -49,6 +50,8 @@ export async function judge(ctx: Context) { time: parseTimeMS(ctx.config.time || '1s'), memory: parseMemoryMB(ctx.config.memory || '256m'), cacheStdoutAndStderr: true, + addressSpaceLimit: address_space_limit, + processLimit: process_limit, }, ); const { diff --git a/packages/hydrojudge/src/judge/interactive.ts b/packages/hydrojudge/src/judge/interactive.ts index bd9962c7..9ccc7038 100644 --- a/packages/hydrojudge/src/judge/interactive.ts +++ b/packages/hydrojudge/src/judge/interactive.ts @@ -13,6 +13,7 @@ function judgeCase(c: NormalizedCase) { return async (ctx: Context, ctxSubtask: ContextSubTask) => { ctx.executeInteractor.copyIn.in = c.input ? { src: c.input } : { content: '' }; ctx.executeInteractor.copyIn.out = c.output ? { src: c.output } : { content: '' }; + const { address_space_limit, process_limit } = ctx.session.getLang(ctx.lang); const [{ code, signalled, time, memory, }, resInteractor] = await runPiped( @@ -21,6 +22,8 @@ function judgeCase(c: NormalizedCase) { copyIn: ctx.executeUser.copyIn, time: c.time, memory: c.memory, + addressSpaceLimit: address_space_limit, + processLimit: process_limit, }, { execute: `${ctx.executeInteractor.execute} /w/in /w/tout /w/out`, diff --git a/packages/hydrojudge/src/judge/run.ts b/packages/hydrojudge/src/judge/run.ts index 52c89315..aa6ef370 100644 --- a/packages/hydrojudge/src/judge/run.ts +++ b/packages/hydrojudge/src/judge/run.ts @@ -46,6 +46,7 @@ export const judge = async (ctx: Context) => { } ctx.clean.push(ctx.execute.clean); ctx.next({ status: STATUS.STATUS_JUDGING, progress: 0 }); + const { address_space_limit, process_limit } = ctx.session.getLang(ctx.lang); const res = await runQueued( ctx.execute.execute, { @@ -54,6 +55,8 @@ export const judge = async (ctx: Context) => { // Allow 2x limits for better debugging time: parseTimeMS(ctx.config.time || '1s') * 2, memory: parseMemoryMB(ctx.config.memory || '128m'), + addressSpaceLimit: address_space_limit, + processLimit: process_limit, }, 1, ); diff --git a/packages/hydrojudge/src/sandbox.ts b/packages/hydrojudge/src/sandbox.ts index 23fb86f2..13adf9f9 100644 --- a/packages/hydrojudge/src/sandbox.ts +++ b/packages/hydrojudge/src/sandbox.ts @@ -33,6 +33,7 @@ interface Parameter { execute?: string; memory?: number; processLimit?: number; + addressSpaceLimit?: boolean; copyIn?: CopyIn; copyOut?: string[]; copyOutCached?: string[]; @@ -101,6 +102,7 @@ function proc(params: Parameter): Cmd { clockLimit: 3 * cpuLimit, memoryLimit: Math.floor(memory * 1024 * 1024), strictMemoryLimit: getConfig('strict_memory'), + addressSpaceLimit: params.addressSpaceLimit, stackLimit: getConfig('strict_memory') ? Math.floor(memory * 1024 * 1024) : 0, procLimit: params.processLimit || getConfig('processLimit'), copyOutMax: Math.floor(1024 * 1024 * stdioLimit * 3), diff --git a/packages/hydrojudge/src/sandbox/interface.ts b/packages/hydrojudge/src/sandbox/interface.ts index 9c3a9885..e4213fb6 100644 --- a/packages/hydrojudge/src/sandbox/interface.ts +++ b/packages/hydrojudge/src/sandbox/interface.ts @@ -5,6 +5,7 @@ export interface SandboxVersion { os: string; copyOutOptional?: boolean; pipeProxy?: boolean; + addressSpaceLimit?: boolean; } export interface LocalFile { @@ -50,8 +51,12 @@ export interface Cmd { cpuRateLimit?: number; /** cpuSetLimit defines cpu set limit if enabled in sandbox server */ cpuSetLimit?: string; - /** strictMemoryLimit set rlimit_data limit for memoryLimit */ + /** @deprecated use dataSegmentLimit instead, keep compatibility for old versions */ strictMemoryLimit?: boolean; + /** dataSegmentLimit set rlimit_data limit for memoryLimit */ + dataSegmentLimit?: boolean; + /** addressSpaceLimit set rlimit_address_space limit for memoryLimit */ + addressSpaceLimit?: boolean; /** files to be copied into sandbox before execution */ copyIn?: Record; diff --git a/packages/hydrooj/setting.yaml b/packages/hydrooj/setting.yaml index e1c00673..5d79177a 100644 --- a/packages/hydrooj/setting.yaml +++ b/packages/hydrooj/setting.yaml @@ -42,6 +42,8 @@ langs: target?: Compiler output file, defaults to `foo` display: Display name compile_time_limit?: Compile time limit, in milliseconds + address_space_limit?: Enable address space memory limit as CCF did + process_limit?: Limit the number of thread bash: display: Bash code_file: foo.sh @@ -58,6 +60,8 @@ langs: highlight: cpp monaco: cpp display: C++ + address_space_limit: true + process_limit: 1 cc.cc98: compile: /usr/bin/g++ -Wall -std=c++98 -o foo foo.cc -lm -I/include display: C++98 diff --git a/packages/utils/lib/lang.ts b/packages/utils/lib/lang.ts index 461bb219..14f4c2c3 100644 --- a/packages/utils/lib/lang.ts +++ b/packages/utils/lib/lang.ts @@ -9,6 +9,8 @@ export interface LangConfig { monaco: string; time_limit_rate: number; memory_limit_rate: number; + address_space_limit?: boolean; + process_limit?: number; display: string; target?: string; key: string;