M pc/devrtc.c => pc/devrtc.c +10 -0
@@ 84,6 84,16 @@ rtcstat(Chan *c, char *dp)
Chan*
rtcopen(Chan *c, int omode)
{
+ omode = openmode(omode);
+ switch(c->qid.path){
+ case Qrtc:
+ if(omode == OREAD)
+ break;
+ /* fall through */
+ case Qnvram:
+ if(strcmp(u->p->user, eve)!=0 || !cpuserver)
+ error(Eperm);
+ }
return devopen(c, omode, rtcdir, NRTC, devgen);
}
M port/devarp.c => port/devarp.c +4 -5
@@ 148,8 148,7 @@ arpstat(Chan *c, char *db)
Chan *
arpopen(Chan *c, int omode)
{
-
- if(c->qid.path == CHDIR){
+ if(c->qid.path&CHDIR){
if(omode != OREAD)
error(Eperm);
}
@@ 165,7 164,6 @@ arpopen(Chan *c, int omode)
break;
}
-
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
@@ 207,9 205,10 @@ arpread(Chan *c, void *a, long n, ulong offset)
int part, bytes, size;
char *ststr;
+ if(c->qid.path&CHDIR)
+ return devdirread(c, a, n, arptab, Narptab, arpgen);
+
switch((int)(c->qid.path&~CHDIR)){
- case arpdirqid:
- return devdirread(c, a, n, 0, 0, arpgen);
case arpdataqid:
bytes = c->offset;
while(bytes < conf.arp*ARP_ENTRYLEN && n) {
M port/net.c => port/net.c +32 -20
@@ 164,26 164,6 @@ netstat(Chan *c, char *db, Network *np)
}
}
-void
-netwstat(Chan *c, char *db, Network *np)
-{
- Dir dir;
- Netprot *p;
-
- p = findprot(np, STREAMID(c->qid.path));
- if(p == 0)
- error(Enonexist);
- lock(np);
- if(strncmp(p->owner, u->p->user, NAMELEN)){
- unlock(np);
- error(Eperm);
- }
- convM2D(db, &dir);
- strncpy(p->owner, dir.uid, NAMELEN);
- p->mode = dir.mode;
- unlock(np);
-}
-
Chan *
netopen(Chan *c, int omode, Network *np)
{
@@ 306,3 286,35 @@ netdisown(Netprot *p)
{
p->owner[0] = 0;
}
+
+#undef CHDIR /* BUG */
+#include "/sys/src/libc/9syscall/sys.h"
+
+void
+netwstat(Chan *c, char *db, Network *np)
+{
+ Dir dir;
+ Netprot *p;
+
+ p = findprot(np, STREAMID(c->qid.path));
+ if(p == 0)
+ error(Enonexist);
+ lock(np);
+
+ /*
+ * A network channel's ownership/permissions can be changed only if the
+ * wstat is by the owner or (HACK!) if it is performed using an fwstat.
+ * The latter allows processes started by a network listener to gain
+ * ownership of the connection. The open file descriptor is used as
+ * a capability for the connection.
+ */
+ if(strncmp(p->owner, u->p->user, NAMELEN) != 0 && u->scallnr != FWSTAT){
+ unlock(np);
+ error(Eperm);
+ }
+ convM2D(db, &dir);
+ strncpy(p->owner, dir.uid, NAMELEN);
+ p->mode = dir.mode;
+
+ unlock(np);
+}
M power/dat.h => power/dat.h +1 -1
@@ 29,8 29,8 @@ struct Lock
struct Label
{
- ulong pc;
ulong sp;
+ ulong pc;
};
struct Conf
M power/devrtc.c => power/devrtc.c +10 -0
@@ 97,6 97,16 @@ rtcstat(Chan *c, char *dp)
Chan*
rtcopen(Chan *c, int omode)
{
+ omode = openmode(omode);
+ switch(c->qid.path){
+ case Qrtc:
+ if(omode == OREAD)
+ break;
+ /* fall through */
+ case Qnvram:
+ if(strcmp(u->p->user, eve)!=0 || !cpuserver)
+ error(Eperm);
+ }
return devopen(c, omode, rtcdir, NRTC, devgen);
}
M power/l.s => power/l.s +4 -4
@@ 163,15 163,15 @@ TEXT wbflush(SB), $-4
TEXT setlabel(SB), $-4
- MOVW R31, 0(R1)
- MOVW R29, 4(R1)
+ MOVW R29, 0(R1)
+ MOVW R31, 4(R1)
MOVW $0, R1
RET
TEXT gotolabel(SB), $-4
- MOVW 0(R1), R31
- MOVW 4(R1), R29
+ MOVW 0(R1), R29
+ MOVW 4(R1), R31
MOVW $1, R1
RET
M ss/devrtc.c => ss/devrtc.c +10 -0
@@ 89,6 89,16 @@ rtcstat(Chan *c, char *dp)
Chan*
rtcopen(Chan *c, int omode)
{
+ omode = openmode(omode);
+ switch(c->qid.path){
+ case Qrtc:
+ if(omode == OREAD)
+ break;
+ /* fall through */
+ case Qnvram:
+ if(strcmp(u->p->user, eve)!=0 || !cpuserver)
+ error(Eperm);
+ }
return devopen(c, omode, rtcdir, NRTC, devgen);
}