Misc bugfixes and robustness improvements
This commit is contained in:
parent
4425f31b88
commit
337658a8bf
|
@ -43,8 +43,8 @@ container first:
|
|||
|
||||
$ make docker
|
||||
|
||||
Note that building the image takes 30 minutes and requires about 15 GB
|
||||
of disk space.
|
||||
Note that building the image takes about 30 minutes on high-end
|
||||
hardware and ethernet, and it requires about 15 GB of disk space.
|
||||
|
||||
## Flag
|
||||
|
||||
|
|
|
@ -10,7 +10,12 @@ import { v4 as getUUID } from "uuid";
|
|||
import { PRIVILEGED } from "./config";
|
||||
import { LangConfig, langs } from "./langs";
|
||||
import { borrowUser } from "./users";
|
||||
import { callPrivileged, getEnv, spawnPrivileged } from "./util";
|
||||
import {
|
||||
callPrivileged,
|
||||
getEnv,
|
||||
rijuSystemPrivileged,
|
||||
spawnPrivileged,
|
||||
} from "./util";
|
||||
|
||||
export class Session {
|
||||
uuid: string;
|
||||
|
@ -193,17 +198,15 @@ export class Session {
|
|||
);
|
||||
}
|
||||
}
|
||||
const args = PRIVILEGED
|
||||
? [
|
||||
"/home/docker/src/system/out/riju-system-privileged",
|
||||
"spawn",
|
||||
`${this.uid}`,
|
||||
`${this.uuid}`,
|
||||
"bash",
|
||||
"-c",
|
||||
cmdline,
|
||||
]
|
||||
: ["bash", "-c", cmdline];
|
||||
const args = [
|
||||
rijuSystemPrivileged,
|
||||
"spawn",
|
||||
`${this.uid}`,
|
||||
`${this.uuid}`,
|
||||
"bash",
|
||||
"-c",
|
||||
cmdline,
|
||||
];
|
||||
const env = getEnv(this.uuid);
|
||||
const term = {
|
||||
pty: pty.spawn(args[0], args.slice(1), {
|
||||
|
@ -227,17 +230,15 @@ export class Session {
|
|||
}
|
||||
});
|
||||
if (lsp && this.lsp === null) {
|
||||
const lspArgs = PRIVILEGED
|
||||
? [
|
||||
"/home/docker/src/system/out/riju-system-privileged",
|
||||
"spawn",
|
||||
`${this.uid}`,
|
||||
`${this.uuid}`,
|
||||
"bash",
|
||||
"-c",
|
||||
lsp,
|
||||
]
|
||||
: ["bash", "-c", lsp];
|
||||
const lspArgs = [
|
||||
rijuSystemPrivileged,
|
||||
"spawn",
|
||||
`${this.uid}`,
|
||||
`${this.uuid}`,
|
||||
"bash",
|
||||
"-c",
|
||||
lsp,
|
||||
];
|
||||
const proc = spawn(lspArgs[0], lspArgs.slice(1), {
|
||||
env: getEnv(this.uuid),
|
||||
});
|
||||
|
@ -254,6 +255,22 @@ export class Session {
|
|||
};
|
||||
cleanup = async () => {
|
||||
this.log(`Cleaning up session`);
|
||||
if (this.term.pty) {
|
||||
await spawnPrivileged(
|
||||
this.uid!,
|
||||
this.uuid,
|
||||
["kill", "-9", `${this.term.pty.pid}`],
|
||||
this.log
|
||||
);
|
||||
}
|
||||
if (this.lsp !== null) {
|
||||
await spawnPrivileged(
|
||||
this.uid!,
|
||||
this.uuid,
|
||||
["kill", "-9", `${this.lsp.proc.pid}`],
|
||||
this.log
|
||||
);
|
||||
}
|
||||
if (this.homedir) {
|
||||
await callPrivileged(["teardown", this.uuid], this.log);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { spawn } from "child_process";
|
||||
import * as fs from "fs";
|
||||
import * as os from "os";
|
||||
|
||||
import * as AsyncLock from "async-lock";
|
||||
import * as _ from "lodash";
|
||||
|
@ -12,7 +13,7 @@ import { callPrivileged } from "./util";
|
|||
const MIN_UID = 2000;
|
||||
const MAX_UID = 65000;
|
||||
|
||||
const CUR_UID = parseInt(process.env.UID || "") || null;
|
||||
const CUR_UID = os.userInfo().uid;
|
||||
|
||||
let availIds: number[] | null = null;
|
||||
let nextId: number | null = null;
|
||||
|
@ -50,11 +51,7 @@ async function createUser(log: (msg: string) => void): Promise<number> {
|
|||
|
||||
export async function borrowUser(log: (msg: string) => void) {
|
||||
if (!PRIVILEGED) {
|
||||
if (CUR_UID === null) {
|
||||
throw new Error("unable to determine current UID");
|
||||
} else {
|
||||
return { uid: CUR_UID, cleanup: async () => {} };
|
||||
}
|
||||
return { uid: CUR_UID, cleanup: async () => {} };
|
||||
} else {
|
||||
return await lock.acquire("key", async () => {
|
||||
if (availIds === null || nextId === null) {
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
import { spawn, SpawnOptions } from "child_process";
|
||||
import * as process from "process";
|
||||
|
||||
import * as appRoot from "app-root-path";
|
||||
|
||||
interface Options extends SpawnOptions {
|
||||
input?: string;
|
||||
}
|
||||
|
||||
export const rijuSystemPrivileged = appRoot.resolve(
|
||||
"system/out/riju-system-privileged"
|
||||
);
|
||||
|
||||
export function getEnv(uuid: string) {
|
||||
const cwd = `/tmp/riju/${uuid}`;
|
||||
return {
|
||||
HOME: cwd,
|
||||
HOSTNAME: "riju",
|
||||
LANG: "C.UTF-8",
|
||||
LC_ALL: "C.UTF-8",
|
||||
LANG: process.env.LANG || "",
|
||||
LC_ALL: process.env.LC_ALL || "",
|
||||
PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/bin",
|
||||
PWD: cwd,
|
||||
SHELL: "/usr/bin/bash",
|
||||
|
@ -59,11 +65,7 @@ export async function callPrivileged(
|
|||
log: (msg: string) => void,
|
||||
options?: Options
|
||||
) {
|
||||
await call(
|
||||
["/home/docker/src/system/out/riju-system-privileged"].concat(args),
|
||||
log,
|
||||
options
|
||||
);
|
||||
await call([rijuSystemPrivileged].concat(args), log, options);
|
||||
}
|
||||
|
||||
export async function spawnPrivileged(
|
||||
|
|
|
@ -49,9 +49,9 @@
|
|||
"frontend": "webpack --production",
|
||||
"frontend-dev": "webpack --development --watch",
|
||||
"server": "scripts/setup.bash && node backend/out/server.js",
|
||||
"server-dev": "watchexec -w backend/out -r 'scripts/setup.bash && node backend/out/server.js'",
|
||||
"server-dev": "watchexec --no-vcs-ignore -w backend/out -r 'scripts/setup.bash && node backend/out/server.js'",
|
||||
"system": "scripts/compile-system.bash",
|
||||
"system-dev": "watchexec -w system/src -n scripts/compile-system.bash",
|
||||
"system-dev": "watchexec --no-vcs-ignore -w system/src -n scripts/compile-system.bash",
|
||||
"build": "run-s backend frontend system",
|
||||
"dev": "run-p backend-dev frontend-dev system-dev server-dev"
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ chmod +x /opt/mspyls/Microsoft.Python.LanguageServer
|
|||
ln -s /opt/mspyls/Microsoft.Python.LanguageServer /usr/bin/Microsoft.Python.LanguageServer
|
||||
|
||||
# SNOBOL
|
||||
wget -nv ftp://ftp.snobol4.org/snobol/snobol4-2.0.tar.gz
|
||||
wget -nv ftp://ftp.snobol4.org/snobol/old/snobol4-2.1.4.tar.gz
|
||||
tar -xf snobol4-*.tar.gz
|
||||
rm snobol4-*.tar.gz
|
||||
pushd snobol4-* >/dev/null
|
||||
|
|
|
@ -5,6 +5,6 @@ set -o pipefail
|
|||
|
||||
mkdir -p /tmp/riju
|
||||
if [[ -x system/out/riju-system-privileged ]]; then
|
||||
system/out/riju-system-privileged teardown "*"
|
||||
system/out/riju-system-privileged teardown "*" || true
|
||||
fi
|
||||
chmod a=x,u=rwx /tmp/riju
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
const int MIN_UID = 2000;
|
||||
const int MAX_UID = 65000;
|
||||
|
||||
int privileged;
|
||||
|
||||
void die(char *msg)
|
||||
{
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
|
@ -29,6 +31,8 @@ void die_with_usage()
|
|||
|
||||
int parseUID(char *str)
|
||||
{
|
||||
if (!privileged)
|
||||
return -1;
|
||||
char *endptr;
|
||||
long uid = strtol(str, &endptr, 10);
|
||||
if (!*str || *endptr)
|
||||
|
@ -50,6 +54,8 @@ char *parseUUID(char *uuid)
|
|||
|
||||
void useradd(int uid)
|
||||
{
|
||||
if (!privileged)
|
||||
die("useradd not allowed without root privileges");
|
||||
char *cmdline;
|
||||
if (asprintf(&cmdline, "groupadd -g %1$d riju%1$d", uid) < 0)
|
||||
die("asprintf failed");
|
||||
|
@ -70,12 +76,14 @@ void spawn(int uid, char *uuid, char **cmdline)
|
|||
die("asprintf failed");
|
||||
if (chdir(cwd) < 0)
|
||||
die("chdir failed");
|
||||
if (setgid(uid) < 0)
|
||||
die("setgid failed");
|
||||
if (setgroups(0, NULL) < 0)
|
||||
die("setgroups failed");
|
||||
if (setuid(uid) < 0)
|
||||
die("setuid failed");
|
||||
if (privileged) {
|
||||
if (setgid(uid) < 0)
|
||||
die("setgid failed");
|
||||
if (setgroups(0, NULL) < 0)
|
||||
die("setgroups failed");
|
||||
if (setuid(uid) < 0)
|
||||
die("setuid failed");
|
||||
}
|
||||
umask(077);
|
||||
execvp(cmdline[0], cmdline);
|
||||
die("execvp failed");
|
||||
|
@ -84,7 +92,9 @@ void spawn(int uid, char *uuid, char **cmdline)
|
|||
void setup(int uid, char *uuid)
|
||||
{
|
||||
char *cmdline;
|
||||
if (asprintf(&cmdline, "install -d -o riju%1$d -g riju%1$d -m 700 /tmp/riju/%2$s", uid, uuid) < 0)
|
||||
if (asprintf(&cmdline, privileged
|
||||
? "install -d -o riju%1$d -g riju%1$d -m 700 /tmp/riju/%2$s"
|
||||
: "install -d -m 700 /tmp/riju/%2$s", uid, uuid) < 0)
|
||||
die("asprintf failed");
|
||||
int status = system(cmdline);
|
||||
if (status)
|
||||
|
@ -103,7 +113,10 @@ void teardown(char *uuid)
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
setuid(0);
|
||||
int code = setuid(0);
|
||||
if (code != 0 && code != -EPERM)
|
||||
die("setuid failed");
|
||||
privileged = code == 0;
|
||||
if (argc < 2)
|
||||
die_with_usage();
|
||||
if (!strcmp(argv[1], "useradd")) {
|
||||
|
|
Loading…
Reference in New Issue