From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, NICE_REPLY_A,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 29471 invoked from network); 6 Jun 2022 03:18:49 -0000 Received: from 9front.inri.net (168.235.81.73) by inbox.vuxu.org with ESMTPUTF8; 6 Jun 2022 03:18:49 -0000 Received: from mail.posixcafe.org ([45.76.19.58]) by 9front; Sun Jun 5 23:16:44 -0400 2022 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posixcafe.org; s=20200506; t=1654485400; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+tSBFa8xwE/PFt2f+D+1R4NZXwCtHqL8Wm4TMqGjbwE=; b=kTBa8LStwhsRNXzCO5JUXwwHhBmuOhscwZQCVOrPGezSf9FWQYum8xV8zJe2zzPH0quLNt l1j8ShDqsukuVwWpKHeitCvDChUGuhQ7Ym1uYEfrfz8OLf8x02Y6RCwegjmOdBdT6IQT6m eP5vykVe33ht8vw67FNDRUTu7xOdWWU= Received: from [192.168.168.200] (161-97-228-135.lpcnextlight.net [161.97.228.135]) by mail.posixcafe.org (OpenSMTPD) with ESMTPSA id 4d4d691b (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO) for <9front@9front.org>; Sun, 5 Jun 2022 22:16:40 -0500 (CDT) Message-ID: Date: Sun, 5 Jun 2022 21:16:07 -0600 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.8.1 Content-Language: en-US To: 9front@9front.org References: <59355e7b-9c12-90f8-d4b4-989f1fa30f26@posixcafe.org> From: Jacob Moody In-Reply-To: <59355e7b-9c12-90f8-d4b4-989f1fa30f26@posixcafe.org> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: private plugin HTML over TOR dependency-oriented database Subject: Re: [9front] Pitch for devskel Reply-To: 9front@9front.org Precedence: bulk To further the case for this, I've worked on a userspace application of the device in the form of auth/box. The premise of auth/box is to setup a slim namespace and execute a program as none. -f and -d specify the files and directories to be included in the new namespace. The absolute path is replicated to the new namespace and the specified file/dir is bound over the empty skeleton. The specified files/dirs are stat'd to reveal their device. Box then restricts devices to only those found this way, the -e option specifies additional devices. An example of creating a box with /env, /bin/walk and /sys/log: ; auth/box -f /bin/walk -d /env -d /sys/log walk / /sys/log/auth /sys/log/boot ... /sys/log /sys /env/terminal /env/cputype ... /env /bin/walk /bin / thanks, moody --- diff df92301d8fc8310fbfdf3de91b97a156ca0504d4 uncommitted --- /dev/null +++ b//sys/src/cmd/auth/box.c @@ -1,0 +1,210 @@ +#include +#include +#include + +static int debug; +static int mountok; + +#define DEBUG if(debug) + +typedef struct List List; +struct List { + char *s; + Rune dev; + List *next; +}; + +void +addto(List *l, char *s) +{ + List *p; + + for(p = l; p->s != nil && p->next != nil; p = p->next) + if(strcmp(p->s, s) == 0) + return; + + if(p->s != nil){ + p->next = mallocz(sizeof *p, 1); + p = p->next; + + } + p->s = s; +} + +void +resolve(List *l) +{ + List *p; + char buf[8192]; + int fd; + Dir *d; + + fd = open(".", OREAD); + if(fd < 0) + sysfatal("could not open .: %r"); + fd2path(fd, buf, sizeof buf); + for(p = l; p != nil; p = p->next){ + if(p->s == nil) + continue; + cleanname(p->s); + switch(p->s[0]){ + case '#': + case '/': + break; + case '.': + if(p->s[1] == '/') + break; + default: + p->s = cleanname(smprint("%s/%s", buf, p->s)); + } + d = dirstat(p->s); + if(d == nil){ + p->s = nil; + continue; + } + p->dev = d->type; + free(d); + } + + close(fd); +} + +void +mimic(char *newroot, List *l, int type) +{ + char *parts[32]; + char src[8192], targ[8192], dir[8192], skel[8192]; + char mode; + List *p; + int n, i; + + for(p = l; p != nil; p = p ->next){ + if(p->s == nil) + continue; + snprint(src, sizeof src, "%s", p->s); + n = gettokens(src, parts, nelem(parts), "/"); + snprint(targ, sizeof targ, "%s", newroot); + for(i = 0; i < n; i++){ + snprint(dir, sizeof dir, "%s", targ); + snprint(targ, sizeof targ, "%s/%s", targ, parts[i]); + if(close(open(targ, OREAD)) >= 0) + continue; + if(i == n-1 && type == QTFILE) + mode = 'f'; + else + mode = 'd'; + snprint(skel, sizeof skel, "#z%c/%s", mode, parts[i]); + DEBUG print("bind -b %s %s\n", skel, dir); + bind(skel, dir, MBEFORE); + } + if(i > 0){ + DEBUG print("bind %s %s\n", p->s, targ); + bind(p->s, targ, MREPL); + } + } + +} + +void +collectdevs(List *l, char *buf, int n) +{ + List *p; + for(p = l; p != nil; p = p->next){ + if(!mountok && p->dev == 'M') + continue; + if(utfrune(buf, p->dev) == nil) + snprint(buf, n, "%s%C", buf, p->dev); + } +} + +void +run(char **a) +{ + exec(a[0], a); + + if(a[0][0] != '/' && a[0][0] != '#' && + (a[0][0] != '.' || (a[0][1] != '/' && + (a[0][1] != '.' || a[0][2] != '/')))) + exec(smprint("/bin/%s", a[0]), a); + + sysfatal("exec: %s: %r", a[0]); +} + +void +usage(void) +{ + fprint(2, "usage %s: [ -f file ] [ -d dir ] cmd args...\n", argv0); + exits("usage"); +} + +void +main(int argc, char **argv) +{ + char newroot[8192]; + char devs[1024]; + int dfd; + char *p; + List files, dirs; + char *defargv[] = { "/bin/rc", "-i", nil }; + + dfd = -1; + mountok = 0; + memset(devs, 0, sizeof devs); + ARGBEGIN{ + case 'M': + mountok = 1; + snprint(devs, sizeof devs, "%s%c", devs, 'M'); + break; + case 'D': + debug = 1; + break; + case 'f': + addto(&files, EARGF(usage())); + break; + case 'd': + addto(&dirs, EARGF(usage())); + break; + case 'e': + p = EARGF(usage()); + snprint(devs, sizeof devs, "%s%s", devs, p); + break; + default: + usage(); + break; + }ARGEND + + rfork(RFNAMEG|RFENVG); + snprint(newroot, sizeof newroot, "#zd/newroot.%d", getpid()); + + resolve(&files); + resolve(&dirs); + if(procsetuser("none") < 0) + sysfatal("cant become none: %r"); + putenv("user", "none"); + collectdevs(&files, devs, sizeof devs); + collectdevs(&dirs, devs, sizeof devs); + if(devs[0] != '\0'){ + dfd = open("/dev/drivers", OWRITE); + if(dfd < 0) + sysfatal("cant open drivers: %r"); + } + + if(bind(newroot, "/", MBEFORE) < 0) + sysfatal("failed to bind: %r"); + + p = newroot + strlen("#zd"); + mimic(p, &files, QTFILE); + mimic(p, &dirs, QTDIR); + if(bind(p, "/", MREPL) < 0) + sysfatal("failed to bind: %r"); + + if(devs[0] != '\0'){ + DEBUG print("chdev %s\n", devs); + fprint(dfd, "chdev & %s", devs); + close(dfd); + } + + if(argc == 0) + argv = defargv; + run(argv); +} --- a//sys/src/cmd/auth/mkfile +++ b//sys/src/cmd/auth/mkfile @@ -9,6 +9,7 @@ asn1dump\ asn12rsa\ authsrv\ + box\ changeuser\ convkeys\ cron\