/n/sources/plan9/sys/src/9/port/./sysproc.c:92,98 - ./sysproc.c:92,97
p->dot = up->dot;
incref(p->dot);
- memmove(p->note, up->note, sizeof(p->note));
p->privatemem = up->privatemem;
p->noswap = up->noswap;
p->nnote = up->nnote;
/n/sources/plan9/sys/src/9/port/./segment.c:465,470 - ./segment.c:465,479
newtop = PGROUND(addr);
newsize = (newtop-s->base)/BY2PG;
if(newtop < s->top) {
+ /*
+ * do not shrink when shared with other procs, as the freed
+ * address space may have been passed to the kernel already
+ * by another proc and is past the validaddr stage.
+ */
+ if(s->ref > 1){
+ qunlock(&s->lk);
+ error(Einuse);
+ }
mfreeseg(s, newtop, (s->top-newtop)/BY2PG);
s->top = newtop;
s->size = newsize;
/n/sources/plan9/sys/src/9/port/./segment.c:642,653 - ./segment.c:651,662
Segment *s, *os;
Physseg *ps;
- if(va != 0 && va >= USTKTOP)
- error(Ebadarg);
+ name = validnamedup(name, 1);
+ if(waserror()){
+ free(name);
+ nexterror();
+ }
- validaddr((ulong)name, 1, 0);
- vmemchr(name, 0, ~0);
-
for(sno = 0; sno < NSEG; sno++)
if(p->seg[sno] == nil && sno != ESEG)
break;
/n/sources/plan9/sys/src/9/port/./segment.c:662,709 - ./segment.c:671,727
if(_globalsegattach != nil){
s = (*_globalsegattach)(p, name);
if(s != nil){
+ poperror();
+ free(name);
+
p->seg[sno] = s;
return s->base;
}
}
+ for(ps = physseg; ps->name; ps++)
+ if(strcmp(name, ps->name) == 0){
+ poperror();
+ free(name);
+
+ goto found;
+ }
+
+ error(Ebadarg);
+
+ found:
len = PGROUND(len);
if(len == 0)
error(Ebadarg);
+ if(len > ps->size)
+ error(Enovmem);
+
/*
* Find a hole in the address space.
* Starting at the lowest possible stack address - len,
* check for an overlapping segment, and repeat at the
* base of that segment - len until either a hole is found
- * or the address space is exhausted.
+ * or the address space is exhausted. make sure we dont
+ * map the zero page.
*/
if(va == 0) {
- va = p->seg[SSEG]->base - len;
- for(;;) {
- os = isoverlap(p, va, len);
- if(os == nil)
- break;
+ os = p->seg[SSEG];
+ do {
va = os->base;
- if(len > va)
+ if(len >= va)
error(Enovmem);
va -= len;
- }
+ os = isoverlap(p, va, len);
+ } while(os != nil);
+ } else {
+ va = va&~(BY2PG-1);
+ if(va == 0 || va >= USTKTOP)
+ error(Ebadarg);
+ if(isoverlap(p, va, len) != nil)
+ error(Esoverlap);
}
- va = va&~(BY2PG-1);
- if(isoverlap(p, va, len) != nil)
- error(Esoverlap);
-
- for(ps = physseg; ps->name; ps++)
- if(strcmp(name, ps->name) == 0)
- goto found;
-
- error(Ebadarg);
- found:
- if(len > ps->size)
- error(Enovmem);
-
attr &= ~SG_TYPE; /* Turn off what is not allowed */
attr |= ps->attr; /* Copy in defaults */
/n/sources/plan9/sys/src/9/port/./segment.c:710,716 - ./segment.c:728,733
s = newseg(attr, va, len/BY2PG);
s->pseg = ps;
p->seg[sno] = s;
-
return va;
}
/n/sources/plan9/sys/src/9/port/./chan.c:1281,1288 - ./chan.c:1281,1289
/*
* Turn a name into a channel.
- * &name[0] is known to be a valid address. It may be a kernel address.
*
+ * aname is validated and can be from user or kernel memory.
+ *
* Opening with amode Aopen, Acreate, Aremove, or Aaccess guarantees
* that the result will be the only reference to that particular fid.
* This is necessary since we might pass the result to
/n/sources/plan9/sys/src/9/port/./chan.c:1307,1319 - ./chan.c:1308,1320
char *createerr, tmperrbuf[ERRMAX];
char *name;
- if(aname[0] == '\0')
- error("empty file name");
aname = validnamedup(aname, 1);
if(waserror()){
free(aname);
nexterror();
}
+ if(aname[0] == '\0')
+ error("empty file name");
DBG("namec %s %d %d\n", aname, amode, omode);
name = aname;
/n/sources/plan9/sys/src/9/port/./chan.c:1667,1674 - ./chan.c:1668,1673
* a) is in valid memory.
* b) is shorter than 2^16 bytes, so it can fit in a 9P string field.
* c) contains no frogs.
- * The first byte is known to be addressible by the requester, so the
- * routine works for kernel and user memory both.
* The parameter slashok flags whether a slash character is an error
* or a valid character.
*
/n/sources/plan9/sys/src/9/port/./chan.c:1690,1696 - ./chan.c:1689,1695
if(!dup)
print("warning: validname called from %lux with user pointer", pc);
ename = vmemchr(name, 0, (1<<16));
- }else
+ } else
ename = memchr(name, 0, (1<<16));
if(ename==nil || ename-name>=(1<<16))
/n/sources/plan9/sys/src/9/port/./chan.c:1713,1723 - ./chan.c:1712,1721
if(c >= Runeself)
name += chartorune(&r, name);
else{
- if(isfrog[c])
- if(!slashok || c!='/'){
- snprint(up->genbuf, sizeof(up->genbuf), "%s: %q", Ebadchar, aname);
- free(s);
- error(up->genbuf);
+ if(isfrog[c] && (!slashok || c!='/')) {
+ snprint(up->genbuf, sizeof(up->genbuf), "%s: %q", Ebadchar, aname);
+ free(s);
+ error(up->genbuf);
}
name++;
}
/n/sources/plan9/sys/src/9/port/./fault.c:330,336 - ./fault.c:330,335
return 1;
}
}
- pprint("suicide: invalid address %#lux/%lud in sys call pc=%#lux\n", addr, len, userpc());
return 0;
}
/n/sources/plan9/sys/src/9/port/./fault.c:337,344 - ./fault.c:336,345
void
validaddr(ulong addr, ulong len, int write)
{
- if(!okaddr(addr, len, write))
- pexit("Suicide", 0);
+ if(!okaddr(addr, len, write)){
+ postnote(up, 1, "sys: bad address in syscall", NDebug);
+ error(Ebadarg);
+ }
}
/*
/n/sources/plan9/sys/src/9/port/./sysfile.c:266,281 - ./sysfile.c:266,279
sysopen(ulong *arg)
{
int fd;
- Chan *c = 0;
+ Chan *c;
openmode(arg[1]); /* error check only */
+ c = namec((char*)arg[0], Aopen, arg[1], 0);
if(waserror()){
- if(c)
- cclose(c);
+ cclose(c);
nexterror();
}
- validaddr(arg[0], 1, 0);
- c = namec((char*)arg[0], Aopen, arg[1], 0);
fd = newfd(c);
if(fd < 0)
error(Enofd);
/n/sources/plan9/sys/src/9/port/./sysfile.c:956,962 - ./sysfile.c:954,959
l = arg[2];
validaddr(arg[1], l, 1);
- validaddr(arg[0], 1, 0);
c = namec((char*)arg[0], Aaccess, 0, 0);
if(waserror()){
cclose(c);
/n/sources/plan9/sys/src/9/port/./sysfile.c:977,984 - ./sysfile.c:974,979
{
Chan *c;
- validaddr(arg[0], 1, 0);
-
c = namec((char*)arg[0], Atodir, 0, 0);
cclose(up->dot);
up->dot = c;
/n/sources/plan9/sys/src/9/port/./sysfile.c:1000,1008 - ./sysfile.c:995,1007
if((flag&~MMASK) || (flag&MORDER)==(MBEFORE|MAFTER))
error(Ebadarg);
- bogus.flags = flag & MCACHE;
-
if(ismount){
+ spec = validnamedup(spec, 1);
+ if(waserror()){
+ free(spec);
+ nexterror();
+ }
+
if(up->pgrp->noattach)
error(Enoattach);
/n/sources/plan9/sys/src/9/port/./sysfile.c:1014,1074 - ./sysfile.c:1013,1058
cclose(bc);
nexterror();
}
-
if(afd >= 0)
ac = fdtochan(afd, ORDWR, 0, 1);
-
+ bogus.flags = flag & MCACHE;
bogus.chan = bc;
bogus.authchan = ac;
-
- validaddr((ulong)spec, 1, 0);
bogus.spec = spec;
- if(waserror())
- error(Ebadspec);
- spec = validnamedup(spec, 1);
- poperror();
-
- if(waserror()){
- free(spec);
- nexterror();
- }
-
ret = devno('M', 0);
c0 = devtab[ret]->attach((char*)&bogus);
-
- poperror(); /* spec */
- free(spec);
poperror(); /* ac bc */
if(ac)
cclose(ac);
cclose(bc);
}else{
- bogus.spec = 0;
- validaddr((ulong)arg0, 1, 0);
+ spec = 0;
c0 = namec(arg0, Abind, 0, 0);
}
-
if(waserror()){
cclose(c0);
nexterror();
}
- validaddr((ulong)arg1, 1, 0);
c1 = namec(arg1, Amount, 0, 0);
if(waserror()){
cclose(c1);
nexterror();
}
-
- ret = cmount(&c0, c1, flag, bogus.spec);
-
+ ret = cmount(&c0, c1, flag, spec);
poperror();
cclose(c1);
+
poperror();
cclose(c0);
- if(ismount)
+
+ if(ismount){
fdclose(fd, 0);
+ poperror();
+ free(spec);
+ }
+
return ret;
}
/n/sources/plan9/sys/src/9/port/./sysfile.c:1097,1111 - ./sysfile.c:1081,1094
cmounted = 0;
- validaddr(arg[1], 1, 0);
cmount = namec((char *)arg[1], Amount, 0, 0);
-
+ if(waserror()) {
+ cclose(cmount);
+ if(cmounted)
+ cclose(cmounted);
+ nexterror();
+ }
if(arg[0]) {
- if(waserror()) {
- cclose(cmount);
- nexterror();
- }
- validaddr(arg[0], 1, 0);
/*
* This has to be namec(..., Aopen, ...) because
* if arg[0] is something like /srv/cs or /fd/0,
/n/sources/plan9/sys/src/9/port/./sysfile.c:1113,1133 - ./sysfile.c:1096,1107
* Chan underneath.
*/
cmounted = namec((char*)arg[0], Aopen, OREAD, 0);
- poperror();
}
-
- if(waserror()) {
- cclose(cmount);
- if(cmounted)
- cclose(cmounted);
- nexterror();
- }
-
cunmount(cmount, cmounted);
+ poperror();
cclose(cmount);
if(cmounted)
cclose(cmounted);
- poperror();
return 0;
}
/n/sources/plan9/sys/src/9/port/./sysfile.c:1135,1150 - ./sysfile.c:1109,1122
syscreate(ulong *arg)
{
int fd;
- Chan *c = 0;
+ Chan *c;
openmode(arg[1]&~OEXCL); /* error check only; OEXCL okay here */
+ c = namec((char*)arg[0], Acreate, arg[1], arg[2]);
if(waserror()) {
- if(c)
- cclose(c);
+ cclose(c);
nexterror();
}
- validaddr(arg[0], 1, 0);
- c = namec((char*)arg[0], Acreate, arg[1], arg[2]);
fd = newfd(c);
if(fd < 0)
error(Enofd);
/n/sources/plan9/sys/src/9/port/./sysfile.c:1157,1164 - ./sysfile.c:1129,1136
{
Chan *c;
- validaddr(arg[0], 1, 0);
c = namec((char*)arg[0], Aremove, 0, 0);
+
/*
* Removing mount points is disallowed to avoid surprises
* (which should be removed: the mount point or the mounted Chan?).
/n/sources/plan9/sys/src/9/port/./sysfile.c:1167,1172 - ./sysfile.c:1139,1145
cclose(c);
error(Eismtpt);
}
+
if(waserror()){
c->type = 0; /* see below */
cclose(c);
/n/sources/plan9/sys/src/9/port/./sysfile.c:1217,1223 - ./sysfile.c:1190,1195
l = arg[2];
validaddr(arg[1], l, 0);
validstat((uchar*)arg[1], l);
- validaddr(arg[0], 1, 0);
c = namec((char*)arg[0], Aaccess, 0, 0);
return wstat(c, (uchar*)arg[1], l);
}
/n/sources/plan9/sys/src/9/port/./sysfile.c:1280,1286 - ./sysfile.c:1252,1257
char old[] = "old stat system call - recompile";
validaddr(arg[1], 116, 1);
- validaddr(arg[0], 1, 0);
c = namec((char*)arg[0], Aaccess, 0, 0);
if(waserror()){
cclose(c);
/n/sources/plan9/sys/src/9/port/./sysfile.c:1297,1303 - ./sysfile.c:1268,1273
if(l == 0)
error(old);
packoldstat((uchar*)arg[1], &d);
-
poperror();
cclose(c);
return 0;
/n/sources/plan9/sys/src/9/port/./auth.c:65,71 - ./auth.c:65,70
char *aname;
int fd;
- validaddr(arg[1], 1, 0);
aname = validnamedup((char*)arg[1], 1);
if(waserror()){
free(aname);
/n/sources/plan9/sys/src/9/port/./auth.c:79,94 - ./auth.c:78,92
ac = mntauth(c, aname);
/* at this point ac is responsible for keeping c alive */
- cclose(c);
poperror(); /* c */
- free(aname);
+ cclose(c);
poperror(); /* aname */
+ free(aname);
if(waserror()){
cclose(ac);
nexterror();
}
-
fd = newfd(ac);
if(fd < 0)
error(Enofd);
|