Fix conflicts between sandboxes

This commit is contained in:
Radon Rosborough 2020-07-12 12:35:51 -06:00
parent febaef0770
commit 03117016cd
2 changed files with 41 additions and 5 deletions

View File

@ -4,7 +4,7 @@ import * as fs from "fs";
import { v4 as getUUID } from "uuid";
import { langs } from "./langs";
import { borrowUser } from "./users";
import { MIN_UID, MAX_UID, borrowUser, ignoreUsers } from "./users";
import {
getEnv,
privilegedSetup,
@ -23,6 +23,22 @@ function log(msg: any) {
}
async function main() {
const dirs = await new Promise<string[]>((resolve, reject) =>
fs.readdir("/tmp/riju", (err, dirs) => (err ? reject(err) : resolve(dirs)))
);
const uids = (
await Promise.all(
dirs.map(
(dir) =>
new Promise<number>((resolve, reject) =>
fs.stat(`/tmp/riju/${dir}`, (err, stat) =>
err ? reject(err) : resolve(stat.uid)
)
)
)
)
).filter((uid) => uid >= MIN_UID && uid < MAX_UID);
await ignoreUsers(uids, log);
const uuid = getUUID();
const { uid, returnUID } = await borrowUser(log);
await run(privilegedSetup({ uid, uuid }), log);

View File

@ -10,8 +10,8 @@ import { PRIVILEGED } from "./config";
import { privilegedUseradd, run } from "./util";
// Keep in sync with system/src/riju-system-privileged.c
const MIN_UID = 2000;
const MAX_UID = 65000;
export const MIN_UID = 2000;
export const MAX_UID = 65000;
const CUR_UID = os.userInfo().uid;
@ -33,9 +33,10 @@ async function readExistingUsers(log: (msg: string) => void) {
)
.filter(({ username }) => username.startsWith("riju"))
.map(({ uid }) => parseInt(uid))
.filter((uid) => !isNaN(uid) && uid >= MIN_UID && uid < MAX_UID);
.filter((uid) => !isNaN(uid) && uid >= MIN_UID && uid < MAX_UID)
.reverse();
nextId = (_.max(availIds) || MIN_UID - 1) + 1;
log(`Found ${availIds.length} existing users, next ID is ${nextId}`);
log(`Found ${availIds.length} existing users, next is riju${nextId}`);
}
async function createUser(log: (msg: string) => void): Promise<number> {
@ -49,6 +50,25 @@ async function createUser(log: (msg: string) => void): Promise<number> {
return uid;
}
export async function ignoreUsers(uids: number[], log: (msg: string) => void) {
await lock.acquire("key", async () => {
if (availIds === null || nextId === null) {
await readExistingUsers(log);
}
const uidSet = new Set(uids);
if (uidSet.size > 0) {
const plural = uidSet.size !== 1 ? "s" : "";
log(
`Ignoring user${plural} from open session${plural}: ${Array.from(uidSet)
.sort()
.map((uid) => `riju${uid}`)
.join(", ")}`
);
}
availIds = availIds!.filter((uid) => !uidSet.has(uid));
});
}
export async function borrowUser(log: (msg: string) => void) {
if (!PRIVILEGED) {
return { uid: CUR_UID, returnUID: async () => {} };