summaryrefslogtreecommitdiff
path: root/sys/src/9/ip
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2019-09-21 23:28:37 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2019-09-21 23:28:37 +0200
commit5993760e143bfab2a29fa3d5a4655ed5842fd21f (patch)
treead7a372f8cf518ddfce9d525e9762ff9be1de075 /sys/src/9/ip
parentb56909157f0cd2491cd2918f7923676f22b5707c (diff)
devip: fix permission checking
permission checking had the "other" and "owner" bits swapped plus incoming connections where always owned by "network" instead of the owner of the listening connection. also, ipwstat() was not effective as the uid strings where not parsed. this fixes the permission checks for data/ctl/err file and makes incoming connections inherit the owner from the listening connection. we also allow ipwstat() to change ownership to the commonuser() or anyone if we are eve. we might have to add additional restrictions for none at a later point...
Diffstat (limited to 'sys/src/9/ip')
-rw-r--r--sys/src/9/ip/devip.c77
1 files changed, 47 insertions, 30 deletions
diff --git a/sys/src/9/ip/devip.c b/sys/src/9/ip/devip.c
index 896d5ef65..c7fc0c72f 100644
--- a/sys/src/9/ip/devip.c
+++ b/sys/src/9/ip/devip.c
@@ -355,7 +355,7 @@ ipopen(Chan* c, int omode)
default:
break;
case Qndb:
- if(omode & (OWRITE|OTRUNC) && !iseve())
+ if((omode & (OWRITE|OTRUNC)) != 0 && !iseve())
error(Eperm);
if((omode & (OWRITE|OTRUNC)) == (OWRITE|OTRUNC))
f->ndb[0] = 0;
@@ -412,15 +412,12 @@ ipopen(Chan* c, int omode)
qunlock(p);
nexterror();
}
- if((perm & (cv->perm>>6)) != perm) {
- if(strcmp(ATTACHER(c), cv->owner) != 0)
- error(Eperm);
- if((perm & cv->perm) != perm)
- error(Eperm);
+ if(strcmp(ATTACHER(c), cv->owner) == 0)
+ perm <<= 6;
+ if((perm & cv->perm) != perm && !iseve())
+ error(Eperm);
- }
- cv->inuse++;
- if(cv->inuse == 1){
+ if(++cv->inuse == 1){
kstrdup(&cv->owner, ATTACHER(c));
cv->perm = 0660;
}
@@ -430,24 +427,26 @@ ipopen(Chan* c, int omode)
break;
case Qlisten:
cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
- if((perm & (cv->perm>>6)) != perm) {
- if(strcmp(ATTACHER(c), cv->owner) != 0)
- error(Eperm);
- if((perm & cv->perm) != perm)
- error(Eperm);
-
+ qlock(cv);
+ if(waserror()){
+ qunlock(cv);
+ nexterror();
}
+ if(strcmp(ATTACHER(c), cv->owner) == 0)
+ perm <<= 6;
+ if((perm & cv->perm) != perm && !iseve())
+ error(Eperm);
if(cv->state != Announced)
error("not announced");
+ cv->inuse++;
+ qunlock(cv);
+ poperror();
if(waserror()){
closeconv(cv);
nexterror();
}
- qlock(cv);
- cv->inuse++;
- qunlock(cv);
nc = nil;
while(nc == nil) {
@@ -469,7 +468,6 @@ ipopen(Chan* c, int omode)
if(nc != nil){
cv->incall = nc->next;
mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE);
- kstrdup(&cv->owner, ATTACHER(c));
}
qunlock(cv);
@@ -502,10 +500,9 @@ ipremove(Chan*)
static int
ipwstat(Chan *c, uchar *dp, int n)
{
- Dir d;
+ Dir *dir;
Conv *cv;
Fs *f;
- Proto *p;
f = ipfs[c->dev];
switch(TYPE(c->qid)) {
@@ -517,16 +514,36 @@ ipwstat(Chan *c, uchar *dp, int n)
break;
}
- n = convM2D(dp, n, &d, nil);
- if(n > 0){
- p = f->p[PROTO(c->qid)];
- cv = p->conv[CONV(c->qid)];
- if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0)
+ dir = smalloc(sizeof(Dir)+n);
+ if(waserror()){
+ free(dir);
+ nexterror();
+ }
+ n = convM2D(dp, n, &dir[0], (char*)&dir[1]);
+ if(n == 0)
+ error(Eshortstat);
+
+ cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)];
+ qlock(cv);
+ if(waserror()){
+ qunlock(cv);
+ nexterror();
+ }
+ if(strcmp(ATTACHER(c), cv->owner) != 0 && !iseve())
+ error(Eperm);
+ if(!emptystr(dir->uid)){
+ if(strcmp(dir->uid, commonuser()) != 0 && !iseve())
error(Eperm);
- if(d.uid[0])
- kstrdup(&cv->owner, d.uid);
- cv->perm = d.mode & 0777;
+ kstrdup(&cv->owner, dir->uid);
}
+ if(dir->mode != ~0UL)
+ cv->perm = dir->mode & 0666;
+ qunlock(cv);
+ poperror();
+
+ free(dir);
+ poperror();
+
return n;
}
@@ -1394,7 +1411,7 @@ Fsnewcall(Conv *c, uchar *raddr, ushort rport, uchar *laddr, ushort lport, uchar
}
/* find a free conversation */
- nc = Fsprotoclone(c->p, network);
+ nc = Fsprotoclone(c->p, c->owner);
if(nc == nil) {
qunlock(c);
return nil;