git: 9front

Download patch

ref: 9b1f208cc2b58f2c3051ffdba69590af20f2a45d
parent: 433a2d3668e9e9a33bba905e3f5995f11581931e
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Mon Aug 15 14:27:30 EDT 2011

devshr: security!

--- a/sys/man/3/shr
+++ b/sys/man/3/shr
@@ -14,7 +14,9 @@
 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 @@
 .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 @@
 .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
--- a/sys/src/9/boot/nusbrc
+++ b/sys/src/9/boot/nusbrc
@@ -2,7 +2,7 @@
 
 if(! bind -a '#u' /dev)
 	exit
-mkdir '#σc/usb'
+mkdir -m 0700 '#σc/usb'
 if(! nusb/usbd)
 	exit
 
--- a/sys/src/9/port/devshr.c
+++ b/sys/src/9/port/devshr.c
@@ -392,6 +392,8 @@
 		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));
@@ -430,6 +432,12 @@
 	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 @@
 		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 @@
 	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 @@
 		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 @@
 		wunlock(&h->lock);
 		break;
 	}
-
 	return n;
 }
 
--