diff --git a/backend/src/api.ts b/backend/src/api.ts index 292b9b4..bde47ef 100644 --- a/backend/src/api.ts +++ b/backend/src/api.ts @@ -56,10 +56,6 @@ export class Session { return { uid: this.uid, uuid: this.uuid }; } - get env() { - return util.getEnv(this.context); - } - log = (msg: string) => console.log(`[${this.uuid}] ${msg}`); constructor(ws: WebSocket, lang: string) { @@ -93,9 +89,7 @@ export class Session { await this.runCode(); if (this.config.daemon) { const daemonArgs = this.privilegedSpawn(bash(this.config.daemon)); - const daemonProc = spawn(daemonArgs[0], daemonArgs.slice(1), { - env: this.env, - }); + const daemonProc = spawn(daemonArgs[0], daemonArgs.slice(1)); this.daemon = { proc: daemonProc, }; @@ -128,7 +122,7 @@ export class Session { await this.run(this.privilegedSpawn(bash(this.config.lspSetup))); } const lspArgs = this.privilegedSpawn(bash(this.config.lsp)); - const lspProc = spawn(lspArgs[0], lspArgs.slice(1), { env: this.env }); + const lspProc = spawn(lspArgs[0], lspArgs.slice(1)); this.lsp = { proc: lspProc, reader: new rpc.StreamMessageReader(lspProc.stdout), @@ -270,7 +264,7 @@ export class Session { const args = this.privilegedSpawn( bash(`kill -SIGTERM ${pid}; sleep 3; kill -SIGKILL ${pid}`) ); - spawn(args[0], args.slice(1), { env: this.env }); + spawn(args[0], args.slice(1)); // Signal to terminalOutput message generator using closure. this.term.live = false; this.term = null; @@ -326,7 +320,6 @@ export class Session { const term = { pty: pty.spawn(termArgs[0], termArgs.slice(1), { name: "xterm-color", - env: this.env, }), live: true, }; diff --git a/backend/src/sandbox.ts b/backend/src/sandbox.ts index f987a52..f47ecf7 100644 --- a/backend/src/sandbox.ts +++ b/backend/src/sandbox.ts @@ -6,7 +6,6 @@ import { v4 as getUUID } from "uuid"; import { langs } from "./langs"; import { MIN_UID, MAX_UID, borrowUser, ignoreUsers } from "./users"; import { - getEnv, privilegedSetup, privilegedSpawn, privilegedTeardown, @@ -44,7 +43,6 @@ async function main() { await run(privilegedSetup({ uid, uuid }), log); const args = privilegedSpawn({ uid, uuid }, ["bash"]); const proc = spawn(args[0], args.slice(1), { - env: getEnv({ uid, uuid }), stdio: "inherit", }); await new Promise((resolve, reject) => { diff --git a/backend/src/util.ts b/backend/src/util.ts index 8178696..cdefaf1 100644 --- a/backend/src/util.ts +++ b/backend/src/util.ts @@ -3,6 +3,7 @@ import * as os from "os"; import * as process from "process"; import * as appRoot from "app-root-path"; +import { quote } from "shell-quote"; import { MIN_UID, MAX_UID } from "./users"; @@ -20,7 +21,7 @@ export const rijuSystemPrivileged = appRoot.resolve( "system/out/riju-system-privileged" ); -export function getEnv({ uid, uuid }: Context) { +function getEnv({ uid, uuid }: Context) { const cwd = `/tmp/riju/${uuid}`; const path = [ `${cwd}/.gem/ruby/2.7.0/bin`, @@ -44,11 +45,18 @@ export function getEnv({ uid, uuid }: Context) { PWD: cwd, SHELL: "/usr/bin/bash", TERM: "xterm-256color", + TMPDIR: `${cwd}`, USER: username, USERNAME: username, }; } +function getEnvString(ctx: Context) { + return Object.entries(getEnv(ctx)) + .map(([key, val]) => `${key}=${quote([val])}`) + .join(" "); +} + export async function run( args: string[], log: (msg: string) => void, @@ -94,8 +102,18 @@ export function privilegedSetup({ uid, uuid }: Context) { return [rijuSystemPrivileged, "setup", `${uid}`, uuid]; } -export function privilegedSpawn({ uid, uuid }: Context, args: string[]) { - return [rijuSystemPrivileged, "spawn", `${uid}`, uuid].concat(args); +export function privilegedSpawn(ctx: Context, args: string[]) { + const { uid, uuid } = ctx; + return [ + rijuSystemPrivileged, + "spawn", + `${uid}`, + uuid, + "bash", + "-c", + `exec env -i ${getEnvString(ctx)} "$@"`, + "--", + ].concat(args); } export function privilegedTeardown({ uid, uuid }: Context) {