From: Jacob Moody <moody@mail.posixcafe.org>
To: 9front@9front.org
Subject: [9front] [PATCH] Unmount to remove sharp devices.
Date: Wed, 4 May 2022 08:09:56 -0600 [thread overview]
Message-ID: <164813d2-28cb-44dd-2aee-b789ea75ba9a@posixcafe.org> (raw)
Hello,
This patch allows processes to unmount sharp devices to prevent itself and its children from accessing
them. This is implemented through an internal rework of how RFNOMNT works, making RFNOMNT a special
case of setting disallowed devices. To replicate the mount blocking functionality of RFNOMNT a special
case is given for blocking devmnt, which also blocks the process and its children from making any mount
calls.
If everything passes the sniff test I can commit these changes. Diff is here: http://okturing.com/src/13574/body and included
below.
Thanks,
moody
diff 9126ee3eea90d639f4e877c01400248581d10f65 uncommitted
--- a//sys/man/3/0intro
+++ b//sys/man/3/0intro
@@ -87,6 +87,20 @@
commands will need quotes to protect the
.B #
characters.
+.PP
+Access to a kernel device can be forfeited by
+unmounting it. For example, after
+.IP
+.EX
+unmount(nil, "#c")
+.EE
+.LP
+the calling process and its children can no longer access the device through its
+sharp name. Existing binds of these devices are untouched.
+Unmounting the mount device (see
+.IR mnt (3))
+has the side effect of preventing the calling process and its children
+from performing mounts.
.SH SEE ALSO
.IR intro (5),
.IR intro (2)
--- a//sys/src/9/port/chan.c
+++ b//sys/src/9/port/chan.c
@@ -1313,24 +1313,19 @@
up->genbuf[n++] = *name++;
}
up->genbuf[n] = '\0';
- /*
- * noattach is sandboxing.
- *
- * the OK exceptions are:
- * | it only gives access to pipes you create
- * d this process's file descriptors
- * e this process's environment
- * the iffy exceptions are:
- * c time and pid, but also cons and consctl
- * p control of your own processes (and unfortunately
- * any others left unprotected)
- */
n = chartorune(&r, up->genbuf+1)+1;
- if(up->pgrp->noattach && utfrune("|decp", r)==nil)
- error(Enoattach);
t = devno(r, 1);
if(t == -1)
error(Ebadsharp);
+ /*
+ * Notallowed is sandboxing.
+ * A process group can willingly give up access to a
+ * sharp device by unmounting it. Notallowed itself is
+ * a bitmask of indicies in to devtab, a high bit indicating
+ * that the process has given up its right to use that device.
+ */
+ if((up->pgrp->notallowed[t/(sizeof(u64int)*8)] & 1<<(t%(sizeof(u64int)*8))) != 0)
+ error(Enoattach);
c = devtab[t]->attach(up->genbuf+n);
break;
--- a//sys/src/9/port/devshr.c
+++ b//sys/src/9/port/devshr.c
@@ -464,7 +464,7 @@
cclose(c);
return nc;
case Qcroot:
- if(up->pgrp->noattach)
+ if(!canmount(up->pgrp, 1))
error(Enoattach);
if((perm & DMDIR) == 0 || mode != OREAD)
error(Eperm);
@@ -498,7 +498,7 @@
sch->shr = shr;
break;
case Qcshr:
- if(up->pgrp->noattach)
+ if(!canmount(up->pgrp, 1))
error(Enoattach);
if((perm & DMDIR) != 0 || mode != OWRITE)
error(Eperm);
@@ -731,7 +731,7 @@
Mhead *h;
Mount *m;
- if(up->pgrp->noattach)
+ if(!canmount(up->pgrp, 1))
error(Enoattach);
sch = tosch(c);
if(sch->level != Qcmpt)
--- a//sys/src/9/port/mkdevc
+++ b//sys/src/9/port/mkdevc
@@ -78,6 +78,9 @@
if(ARGC < 2)
exit "usage"
+ if(ndev >= 256)
+ exit "device count will overflow Pgrp.notallowed"
+
printf "#include \"u.h\"\n";
printf "#include \"../port/lib.h\"\n";
printf "#include \"mem.h\"\n";
--- a//sys/src/9/port/portdat.h
+++ b//sys/src/9/port/portdat.h
@@ -484,7 +484,7 @@
{
Ref;
RWlock ns; /* Namespace n read/one write lock */
- int noattach;
+ u64int notallowed[4]; /* Room for 256 devices */
Mhead *mnthash[MNTHASH];
};
--- a//sys/src/9/port/portfns.h
+++ b//sys/src/9/port/portfns.h
@@ -413,6 +413,7 @@
ushort nhgets(void*);
ulong µs(void);
long lcycles(void);
+int canmount(Pgrp*,int);
#pragma varargck argpos iprint 1
#pragma varargck argpos panic 1
--- a//sys/src/9/port/sysfile.c
+++ b//sys/src/9/port/sysfile.c
@@ -1048,7 +1048,7 @@
nexterror();
}
- if(up->pgrp->noattach)
+ if(!canmount(up->pgrp, 1))
error(Enoattach);
ac = nil;
@@ -1146,6 +1146,8 @@
{
Chan *cmount, *cmounted;
char *name, *old;
+ int t;
+ Rune r;
name = va_arg(list, char*);
old = va_arg(list, char*);
@@ -1152,6 +1154,14 @@
cmounted = nil;
validaddr((uintptr)old, 1, 0);
+ if(old[0] == '#' && utflen(old) == 2){
+ chartorune(&r, old+1);
+ t = devno(r, 1);
+ if(t == -1)
+ error(Ebadsharp);
+ up->pgrp->notallowed[t/(sizeof(u64int)*8)] |= 1<<(t%(sizeof(u64int)*8));
+ return 0;
+ }
cmount = namec(old, Amount, 0, 0);
if(waserror()) {
cclose(cmount);
--- a//sys/src/9/port/sysproc.c
+++ b//sys/src/9/port/sysproc.c
@@ -23,6 +23,43 @@
pexit("fork aborted", 1);
}
+int
+canmount(Pgrp *p, int user)
+{
+ int t;
+
+ /*
+ * Devmnt is not usable directly from user procs, so
+ * having it removed is interpreted to block any mounts.
+ */
+ t = devno('M', user);
+ if(t != -1 && (p->notallowed[t/(sizeof(u64int)*8)] & 1<<(t%(sizeof(u64int)*8))) != 0)
+ return 0;
+ return 1;
+}
+
+static void
+setrfnomnt(Pgrp *p)
+{
+ int t, i;
+ u64int mask[nelem(p->notallowed)];
+ char allowed[] = "|decp";
+
+ /*
+ * Code using RFNOMNT expects to block all sharp devices
+ * and mounting except for the devices defined in allowed[]
+ */
+ for(i=0; i < sizeof allowed; i++){
+ t = devno(allowed[i], 1);
+ if(t == -1)
+ continue;
+ mask[t/(sizeof(u64int)*8)] |= 1<<(t%(sizeof(u64int)*8));
+ }
+ /* Sets bit for devmnt, so all mounts are disabled implicitly */
+ for(i=0; i < nelem(p->notallowed); i++)
+ p->notallowed[i] |= ~mask[i];
+}
+
uintptr
sysrfork(va_list list)
{
@@ -60,12 +97,12 @@
up->pgrp = newpgrp();
if(flag & RFNAMEG)
pgrpcpy(up->pgrp, opg);
- /* inherit noattach */
- up->pgrp->noattach = opg->noattach;
+ /* inherit notallowed */
+ memmove(up->pgrp->notallowed, opg->notallowed, sizeof up->pgrp->notallowed);
closepgrp(opg);
}
if(flag & RFNOMNT)
- up->pgrp->noattach = 1;
+ setrfnomnt(up->pgrp);
if(flag & RFREND) {
org = up->rgrp;
up->rgrp = newrgrp();
@@ -177,8 +214,8 @@
p->pgrp = newpgrp();
if(flag & RFNAMEG)
pgrpcpy(p->pgrp, up->pgrp);
- /* inherit noattach */
- p->pgrp->noattach = up->pgrp->noattach;
+ /* inherit notallowed */
+ memmove(p->pgrp->notallowed, up->pgrp->notallowed, sizeof p->pgrp->notallowed);
}
else {
p->pgrp = up->pgrp;
@@ -185,7 +222,7 @@
incref(p->pgrp);
}
if(flag & RFNOMNT)
- p->pgrp->noattach = 1;
+ setrfnomnt(p->pgrp);
if(flag & RFREND)
p->rgrp = newrgrp();
next reply other threads:[~2022-05-04 14:13 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-04 14:09 Jacob Moody [this message]
2022-05-04 15:05 ` ori
2022-05-04 15:31 ` ori
2022-05-04 16:15 ` Stanley Lieber
2022-05-04 17:41 ` Lyndon Nerenberg (VE7TFX/VE6BBM)
2022-05-04 17:55 ` Jacob Moody
2022-05-05 1:59 ` Alex Musolino
2022-05-05 16:07 ` Jacob Moody
2022-05-08 2:55 ` Jacob Moody
2022-05-11 14:47 ` Jacob Moody
2022-05-11 16:11 ` Stanley Lieber
2022-05-12 4:29 ` Jacob Moody
2022-05-12 3:18 ` ori
2022-05-12 5:10 ` Jacob Moody
2022-05-12 14:21 ` ori
2022-05-23 5:42 ` Jacob Moody
2022-05-23 17:06 ` cinap_lenrek
2022-05-23 17:37 ` Jacob Moody
2022-05-25 19:03 ` Jacob Moody
2022-05-25 20:53 ` hiro
2022-05-25 21:20 ` Jacob Moody
2022-05-26 5:55 ` Jacob Moody
2022-05-26 23:36 ` unobe
2022-05-27 0:33 ` Jacob Moody
2022-05-27 3:25 ` unobe
2022-05-26 3:13 ` ori
2022-05-27 1:11 ` Lyndon Nerenberg (VE7TFX/VE6BBM)
2022-05-27 2:25 ` Frank D. Engel, Jr.
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=164813d2-28cb-44dd-2aee-b789ea75ba9a@posixcafe.org \
--to=moody@mail.posixcafe.org \
--cc=9front@9front.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).