Misc bugfixes and robustness improvements

This commit is contained in:
Radon Rosborough 2020-07-05 12:21:59 -06:00
parent 4425f31b88
commit 337658a8bf
8 changed files with 79 additions and 50 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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) {

View File

@ -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(

View File

@ -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"
}

View File

@ -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

View File

@ -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

View File

@ -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")) {