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().
This commit is contained in:
cinap_lenrek 2014-02-02 10:41:51 +01:00
parent 0b95485db7
commit 29eea45931
2 changed files with 13 additions and 10 deletions

View file

@ -14,8 +14,11 @@ fault(uintptr addr, int read)
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;

View file

@ -189,21 +189,19 @@ sysfd2path(va_list list)
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 @@ syspipe(va_list list)
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;
}