--- a/sys/src/9/ip/devip.c Thu May 21 15:38:05 2020 +++ b/sys/src/9/ip/devip.c Tue Jun 9 16:22:06 2026 @@ -351,7 +351,8 @@ static int m2p[] = { [OREAD] 4, [OWRITE] 2, - [ORDWR] 6 + [ORDWR] 6, + [OEXEC] 1 }; static Chan* @@ -432,10 +433,10 @@ qunlock(p); nexterror(); } - if((perm & (cv->perm>>6)) != perm) { + if((perm & cv->perm) != perm) { if(strcmp(ATTACHER(c), cv->owner) != 0) error(Eperm); - if((perm & cv->perm) != perm) + if((perm & (cv->perm>>6)) != perm) error(Eperm); } @@ -450,10 +451,10 @@ break; case Qlisten: cv = f->p[PROTO(c->qid)]->conv[CONV(c->qid)]; - if((perm & (cv->perm>>6)) != perm) { + if((perm & cv->perm) != perm) { if(strcmp(ATTACHER(c), cv->owner) != 0) error(Eperm); - if((perm & cv->perm) != perm) + if((perm & (cv->perm>>6)) != perm) error(Eperm); } @@ -489,7 +490,7 @@ if(nc != nil){ cv->incall = nc->next; mkqid(&c->qid, QID(PROTO(c->qid), nc->x, Qctl), 0, QTFILE); - kstrdup(&cv->owner, ATTACHER(c)); + kstrdup(&nc->owner, ATTACHER(c)); } qunlock(cv); @@ -521,7 +522,7 @@ static int ipwstat(Chan *c, uchar *dp, int n) { - Dir d; + Dir *d; Conv *cv; Fs *f; Proto *p; @@ -536,16 +537,25 @@ break; } - n = convM2D(dp, n, &d, nil); + d = smalloc(sizeof(Dir)+n); + if(waserror()){ + free(d); + nexterror(); + } + n = convM2D(dp, n, &d[0], (char*)&d[1]); if(n > 0){ p = f->p[PROTO(c->qid)]; cv = p->conv[CONV(c->qid)]; if(!iseve() && strcmp(ATTACHER(c), cv->owner) != 0) error(Eperm); - if(d.uid[0]) - kstrdup(&cv->owner, d.uid); - cv->perm = d.mode & 0777; - } + if(!emptystr(d->uid)) + kstrdup(&cv->owner, d->uid); + if(d->mode != ~0UL) + cv->perm = d->mode & 0777; + } else + error(Eshortstat); + poperror(); + free(d); return n; } --- a/sys/src/9/port/devsdp.c Thu Jun 13 22:24:49 2013 +++ b/sys/src/9/port/devsdp.c Tue Jun 9 16:22:31 2026 @@ -252,7 +252,8 @@ static int m2p[] = { [OREAD] 4, [OWRITE] 2, - [ORDWR] 6 + [ORDWR] 6, + [OEXEC] 1 }; enum { @@ -446,8 +447,8 @@ qunlock(c); nexterror(); } - if((perm & (c->perm>>6)) != perm) - if(strcmp(up->user, c->owner) != 0 || (perm & c->perm) != perm) + if((perm & c->perm) != perm) + if(strcmp(up->user, c->owner) != 0 || (perm & (c->perm>>6)) != perm) error(Eperm); c->ref++; --- a/sys/src/9/port/devssl.c Thu Jun 13 22:24:42 2013 +++ b/sys/src/9/port/devssl.c Tue Jun 9 16:22:56 2026 @@ -278,6 +278,9 @@ case ORDWR: perm = 6; break; + case OEXEC: + perm = 1; + break; } ft = TYPE(c->qid); @@ -309,9 +312,9 @@ if(s == 0) dsnew(c, pp); else { - if((perm & (s->perm>>6)) != perm + if((perm & s->perm) != perm && (strcmp(up->user, s->user) != 0 - || (perm & s->perm) != perm)) + || (perm & (s->perm>>6)) != perm)) error(Eperm); s->ref++; --- a/sys/src/9/port/devtls.c Fri Apr 6 20:17:06 2018 +++ b/sys/src/9/port/devtls.c Tue Jun 9 16:23:14 2026 @@ -424,6 +424,9 @@ case ORDWR: perm = 6; break; + case OEXEC: + perm = 1; + break; } t = TYPE(c->qid); @@ -457,9 +460,9 @@ tr = *pp; if(tr == nil) error("must open connection using clone"); - if((perm & (tr->perm>>6)) != perm + if((perm & tr->perm) != perm && (strcmp(up->user, tr->user) != 0 - || (perm & tr->perm) != perm)) + || (perm & (tr->perm>>6)) != perm)) error(Eperm); if(t == Qhand){ if(waserror()){