ref: 29eea45931f6ae094bb2be5c82d7ad6641dc1e65
parent: 0b95485db79d3033cacd42038f0cf575e430e066
author: cinap_lenrek <[email protected]>
date: Sun Feb 2 05:41:51 EST 2014
kernel: do not pass user address of fd[2] array to newfd2() access to user memory can pagefault and newfd2() holds fgrp spinlock while writing to it. make temporary copy on the stack in syspipe().
--- a/sys/src/9/port/fault.c
+++ b/sys/src/9/port/fault.c
@@ -14,8 +14,11 @@
if(up == nil)
panic("fault: nil up");
- if(up->nlocks.ref)
- print("fault: nlocks %ld\n", up->nlocks.ref);
+ if(up->nlocks.ref){
+ Lock *l = up->lastlock;
+ print("fault: nlocks %ld, proc %lud %s, addr %#p, lock %#p, lpc %#p\n",
+ up->nlocks.ref, up->pid, up->text, addr, l, l ? l->pc : 0);
+ }
pnd = up->notepending;
sps = up->psstate;
--- a/sys/src/9/port/sysfile.c
+++ b/sys/src/9/port/sysfile.c
@@ -189,21 +189,19 @@
uintptr
syspipe(va_list list)
{
- int *fd;
+ int fd[2], *ufd;
Chan *c[2];
Dev *d;
static char *datastr[] = {"data", "data1"};
- fd = va_arg(list, int*);
- validaddr((uintptr)fd, 2*sizeof(int), 1);
- evenaddr((uintptr)fd);
-
+ ufd = va_arg(list, int*);
+ validaddr((uintptr)ufd, sizeof(fd), 1);
+ evenaddr((uintptr)ufd);
+
+ ufd[0] = ufd[1] = fd[0] = fd[1] = -1;
d = devtab[devno('|', 0)];
c[0] = namec("#|", Atodir, 0, 0);
c[1] = 0;
- fd[0] = -1;
- fd[1] = -1;
-
if(waserror()){
cclose(c[0]);
if(c[1])
@@ -219,6 +217,8 @@
c[1] = d->open(c[1], ORDWR);
if(newfd2(fd, c) < 0)
error(Enofd);
+ ufd[0] = fd[0];
+ ufd[1] = fd[1];
poperror();
return 0;
}