devshr: security!

This commit is contained in:
cinap_lenrek 2011-08-15 18:27:30 +02:00
parent e1318e0bef
commit b39d5fbbef
3 changed files with 45 additions and 14 deletions

View file

@ -14,7 +14,9 @@ shr \- global mountpoints
The
.I shr
device provides global mountpoints in the form of share directories
where 9p services can be mounted and unmounted dynamically.
where
.IR 9P
services can be mounted on.
Effectively, it is a global mountpoint registry that is separate from
private namespaces.
@ -26,7 +28,7 @@ in the mount tree
.BI #σ
are the share mountpoints themselve and in the control tree
.BI #σc
share directories can be created or removed.
share directories list the service files of the share.
.PP
To create a new share, create the directory
.B #σc/myshare
@ -37,13 +39,26 @@ and then write a text string (suitable for
.IR strtoul ;
see
.IR atof (2))
giving the file descriptor number of an open 9p service. Any process
giving the file descriptor number of an open
.I 9P
service. Any process
with the proper permission may then access
.B #σ/myshare
to use the service.
on the mount tree.
.PP
Multiple services can be mounted under a share. New services get
mounted before old ones. Removing the service file from a share
removes the service as soon as the last reference goes away.
The service file can be reopened and passed to
.IR mount
(see
.IR bind(2))
or added to another share.
.PP
Multiple services can be mounted under a share forming a union
directory. New services get mounted before old ones.
Removing the service file unmounts the service from the share.
.PP
Creating shares and mounts requires read-write access in the share
directory. The special user
.B none
is prohibited from these operations.
.SH SOURCE
.B /sys/src/9/port/devshr.c

View file

@ -2,7 +2,7 @@
if(! bind -a '#u' /dev)
exit
mkdir '#σc/usb'
mkdir -m 0700 '#σc/usb'
if(! nusb/usbd)
exit

View file

@ -392,6 +392,8 @@ shropen(Chan *c, int omode)
devpermcheck(shr->owner, shr->perm, openmode(omode));
break;
case Qcmpt:
if(omode&OTRUNC)
error(Eexist);
shr = sch->shr;
mpt = sch->mpt;
devpermcheck(mpt->owner, mpt->perm, openmode(omode));
@ -429,6 +431,12 @@ shrcreate(Chan *c, char *name, int omode, ulong perm)
switch(sch->level){
default:
error(Enocreate);
case Qcroot:
case Qcshr:
if(strcmp(up->user, "none") == 0)
error(Eperm);
}
switch(sch->level){
case Qcroot:
if((perm & DMDIR) == 0 || openmode(omode) != OREAD)
error(Eperm);
@ -461,11 +469,14 @@ shrcreate(Chan *c, char *name, int omode, ulong perm)
sch->shr = shr;
break;
case Qcshr:
shr = sch->shr;
devpermcheck(shr->owner, shr->perm, ORDWR);
if((perm & DMDIR) || openmode(omode) != OWRITE)
error(Eperm);
shr = sch->shr;
if(strcmp(shr->owner, eve) == 0 && !iseve())
error(Eperm);
devpermcheck(shr->owner, shr->perm, ORDWR);
h = &shr->umh;
wlock(&h->lock);
if(waserror()){
@ -520,8 +531,16 @@ shrremove(Chan *c)
default:
error(Eperm);
case Qcshr:
case Qcmpt:
shr = sch->shr;
devpermcheck(shr->owner, shr->perm, ORDWR);
if(!iseve()){
if(strcmp(shr->owner, eve) == 0)
error(Eperm);
devpermcheck(shr->owner, shr->perm, ORDWR);
}
}
switch(sch->level){
case Qcshr:
h = &shr->umh;
qlock(&shrslk);
rlock(&h->lock);
@ -541,8 +560,6 @@ shrremove(Chan *c)
qunlock(&shrslk);
break;
case Qcmpt:
shr = sch->shr;
devpermcheck(shr->owner, shr->perm, ORDWR);
mpt = sch->mpt;
m = &mpt->m;
h = &shr->umh;
@ -630,7 +647,6 @@ shrwstat(Chan *c, uchar *dp, int n)
wunlock(&h->lock);
break;
}
return n;
}