shithub: riscv

Download patch

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;
 }