shithub: riscv

Download patch

ref: 42074003ca31dea9589012fe3e235e4ddec5be1f
parent: afc2d547e18381ce2dd0f69f0e88860d49b7e54f
author: cinap_lenrek <[email protected]>
date: Sun Dec 29 02:48:19 EST 2013

kernel: dont call pprint() while holding up->debug qlock

pprint() might block or even (maliciously) call into
devproc write which will corrupt the qlock chain on attempt
to qlock up->debug again.

--- a/sys/src/9/alphapc/trap.c
+++ b/sys/src/9/alphapc/trap.c
@@ -543,9 +543,9 @@
 	}
 
 	if(n->flag != NUser && (up->notified || up->notify==0)) {
+		qunlock(&up->debug);
 		if(n->flag == NDebug)
 			pprint("suicide: %s\n", n->msg);
-		qunlock(&up->debug);
 		pexit(n->msg, n->flag!=NDebug);
 	}
 
@@ -564,9 +564,8 @@
 
 	if(!okaddr((ulong)up->notify, BY2WD, 0)
 	|| !okaddr(sp-ERRMAX-6*BY2WD, sizeof(Ureg)+ERRMAX-6*BY2WD, 1)) {
-		pprint("suicide: bad address or sp in notify\n");
-print("suicide: bad address or sp in notify\n");
 		qunlock(&up->debug);
+		pprint("suicide: bad address or sp in notify\n");
 		pexit("Suicide", 0);
 	}
 
@@ -618,7 +617,6 @@
 	if(arg0!=NRSTR && !up->notified) {
 		qunlock(&up->debug);
 		pprint("call to noted() when not notified\n");
-print("call to noted() when not notified\n");
 		pexit("Suicide", 0);
 	}
 	up->notified = 0;
@@ -630,9 +628,8 @@
 	oureg = (ulong)nur;
 	if((oureg & (BY2V-1))
 	|| !okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
-		pprint("bad ureg in noted or call to noted() when not notified\n");
-print("bad ureg in noted or call to noted() when not notified\n");
 		qunlock(&up->debug);
+		pprint("bad ureg in noted or call to noted() when not notified\n");
 		pexit("Suicide", 0);
 	}
 
@@ -639,7 +636,6 @@
 	if(!validstatus(kur->status, nur->status)) {
 		qunlock(&up->debug);
 		pprint("bad noted ureg status %lux\n", (ulong)nur->status);
-print("bad noted ureg status %lux\n", (ulong)nur->status);
 		pexit("Suicide", 0);
 	}
 
@@ -648,9 +644,8 @@
 	case NCONT:
 	case NRSTR:
 		if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){
-			pprint("suicide: trap in noted\n");
-print("suicide: trap in noted\n");
 			qunlock(&up->debug);
+			pprint("suicide: trap in noted\n");
 			pexit("Suicide", 0);
 		}
 		up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
@@ -661,9 +656,8 @@
 
 	case NSAVE:
 		if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){
-			pprint("suicide: trap in noted\n");
-print("suicide: trap in noted\n");
 			qunlock(&up->debug);
+			pprint("suicide: trap in noted\n");
 			pexit("Suicide", 0);
 		}
 		qunlock(&up->debug);
@@ -677,15 +671,13 @@
 		break;
 
 	default:
-		pprint("unknown noted arg 0x%lux\n", arg0);
-print("unknown noted arg 0x%lux\n", arg0);
 		up->lastnote.flag = NDebug;
 		/* fall through */
 		
 	case NDFLT:
+		qunlock(&up->debug);
 		if(up->lastnote.flag == NDebug)
 			pprint("suicide: %s\n", up->lastnote.msg);
-		qunlock(&up->debug);
 		pexit(up->lastnote.msg, up->lastnote.flag!=NDebug);
 	}
 }
--- a/sys/src/9/bitsy/devether.c
+++ b/sys/src/9/bitsy/devether.c
@@ -124,7 +124,7 @@
 			ether->ea[0], ether->ea[1], ether->ea[2],
 			ether->ea[3], ether->ea[4], ether->ea[5]);
 		seprint(p, e, "\n");
-		pprint(buf);
+		print("%s", buf);
 
 		etherxx[ctlrno] = ether;
 		return 0;
--- a/sys/src/9/bitsy/trap.c
+++ b/sys/src/9/bitsy/trap.c
@@ -617,8 +617,8 @@
 	/* sanity clause */
 	oureg = (ulong)nureg;
 	if(!okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
-		pprint("bad ureg in noted or call to noted when not notified\n");
 		qunlock(&up->debug);
+		pprint("bad ureg in noted or call to noted when not notified\n");
 		pexit("Suicide", 0);
 	}
 
@@ -656,16 +656,13 @@
 		break;
 
 	default:
-		pprint("unknown noted arg 0x%lux\n", arg0);
 		up->lastnote.flag = NDebug;
 		/* fall through */
 		
 	case NDFLT:
-		if(up->lastnote.flag == NDebug){ 
-			qunlock(&up->debug);
+		qunlock(&up->debug);
+		if(up->lastnote.flag == NDebug)
 			pprint("suicide: %s\n", up->lastnote.msg);
-		} else
-			qunlock(&up->debug);
 		pexit(up->lastnote.msg, up->lastnote.flag!=NDebug);
 	}
 }
@@ -698,9 +695,9 @@
 	}
 
 	if(n->flag!=NUser && (up->notified || up->notify==0)){
+		qunlock(&up->debug);
 		if(n->flag == NDebug)
 			pprint("suicide: %s\n", n->msg);
-		qunlock(&up->debug);
 		pexit(n->msg, n->flag!=NDebug);
 	}
 
@@ -719,8 +716,8 @@
 
 	if(!okaddr((ulong)up->notify, 1, 0)
 	|| !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)){
-		pprint("suicide: bad address in notify\n");
 		qunlock(&up->debug);
+		pprint("suicide: bad address in notify\n");
 		pexit("Suicide", 0);
 	}
 
--- a/sys/src/9/kw/syscall.c
+++ b/sys/src/9/kw/syscall.c
@@ -80,16 +80,12 @@
 		cur->sp = PTR2UINT(nf);
 		break;
 	default:
-		pprint("unknown noted arg %#p\n", arg0);
 		up->lastnote.flag = NDebug;
 		/*FALLTHROUGH*/
 	case NDFLT:
-		if(up->lastnote.flag == NDebug){ 
-			qunlock(&up->debug);
+		qunlock(&up->debug);
+		if(up->lastnote.flag == NDebug)
 			pprint("suicide: %s\n", up->lastnote.msg);
-		}
-		else
-			qunlock(&up->debug);
 		pexit(up->lastnote.msg, up->lastnote.flag != NDebug);
 	}
 }
@@ -127,9 +123,9 @@
 	}
 
 	if(n->flag != NUser && (up->notified || up->notify == 0)){
+		qunlock(&up->debug);
 		if(n->flag == NDebug)
 			pprint("suicide: %s\n", n->msg);
-		qunlock(&up->debug);
 		pexit(n->msg, n->flag != NDebug);
 	}
 
@@ -144,8 +140,8 @@
 		pexit(n->msg, n->flag != NDebug);
 	}
 	if(!okaddr(PTR2UINT(up->notify), 1, 0)){
-		pprint("suicide: notify function address %#p\n", up->notify);
 		qunlock(&up->debug);
+		pprint("suicide: notify function address %#p\n", up->notify);
 		pexit("Suicide", 0);
 	}
 
--- a/sys/src/9/mtx/trap.c
+++ b/sys/src/9/mtx/trap.c
@@ -717,9 +717,9 @@
 	}
 
 	if(n->flag!=NUser && (up->notified || up->notify==0)){
+		qunlock(&up->debug);
 		if(n->flag == NDebug)
 			pprint("suicide: %s\n", n->msg);
-		qunlock(&up->debug);
 		pexit(n->msg, n->flag!=NDebug);
 	}
 
@@ -738,8 +738,8 @@
 
 	if(!okaddr((ulong)up->notify, BY2WD, 0) ||
 	   !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)) {
-		pprint("suicide: bad address or sp in notify\n");
 		qunlock(&up->debug);
+		pprint("suicide: bad address or sp in notify\n");
 		pexit("Suicide", 0);
 	}
 
@@ -788,8 +788,8 @@
 	/* sanity clause */
 	oureg = (ulong)nureg;
 	if(!okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
-		pprint("bad ureg in noted or call to noted when not notified\n");
 		qunlock(&up->debug);
+		pprint("bad ureg in noted or call to noted when not notified\n");
 		pexit("Suicide", 0);
 	}
 
@@ -799,8 +799,8 @@
 	case NCONT:
 	case NRSTR:
 		if(!okaddr(nureg->pc, 1, 0) || !okaddr(nureg->usp, BY2WD, 0)){
-			pprint("suicide: trap in noted\n");
 			qunlock(&up->debug);
+			pprint("suicide: trap in noted\n");
 			pexit("Suicide", 0);
 		}
 		up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
@@ -810,8 +810,8 @@
 	case NSAVE:
 		if(!okaddr(nureg->pc, BY2WD, 0)
 		|| !okaddr(nureg->usp, BY2WD, 0)){
-			pprint("suicide: trap in noted\n");
 			qunlock(&up->debug);
+			pprint("suicide: trap in noted\n");
 			pexit("Suicide", 0);
 		}
 		qunlock(&up->debug);
@@ -823,14 +823,13 @@
 		break;
 
 	default:
-		pprint("unknown noted arg 0x%lux\n", arg0);
 		up->lastnote.flag = NDebug;
 		/* fall through */
 		
 	case NDFLT:
+		qunlock(&up->debug);
 		if(up->lastnote.flag == NDebug)
 			pprint("suicide: %s\n", up->lastnote.msg);
-		qunlock(&up->debug);
 		pexit(up->lastnote.msg, up->lastnote.flag!=NDebug);
 	}
 }
--- a/sys/src/9/omap/syscall.c
+++ b/sys/src/9/omap/syscall.c
@@ -80,16 +80,12 @@
 		cur->sp = PTR2UINT(nf);
 		break;
 	default:
-		pprint("unknown noted arg %#p\n", arg0);
 		up->lastnote.flag = NDebug;
 		/*FALLTHROUGH*/
 	case NDFLT:
-		if(up->lastnote.flag == NDebug){ 
-			qunlock(&up->debug);
+		qunlock(&up->debug);
+		if(up->lastnote.flag == NDebug)
 			pprint("suicide: %s\n", up->lastnote.msg);
-		}
-		else
-			qunlock(&up->debug);
 		pexit(up->lastnote.msg, up->lastnote.flag != NDebug);
 	}
 }
@@ -127,9 +123,9 @@
 	}
 
 	if(n->flag != NUser && (up->notified || up->notify == 0)){
+		qunlock(&up->debug);
 		if(n->flag == NDebug)
 			pprint("suicide: %s\n", n->msg);
-		qunlock(&up->debug);
 		pexit(n->msg, n->flag != NDebug);
 	}
 
@@ -144,8 +140,8 @@
 		pexit(n->msg, n->flag != NDebug);
 	}
 	if(!okaddr(PTR2UINT(up->notify), 1, 0)){
-		pprint("suicide: notify function address %#p\n", up->notify);
 		qunlock(&up->debug);
+		pprint("suicide: notify function address %#p\n", up->notify);
 		pexit("Suicide", 0);
 	}
 
--- a/sys/src/9/omap4/trap.c
+++ b/sys/src/9/omap4/trap.c
@@ -154,9 +154,9 @@
 		sprint(n->msg + l, " pc=0x%.8lux", ureg->pc);
 	}
 	if(n->flag != NUser && (up->notified || up->notify == 0)){
+		qunlock(&up->debug);
 		if(n->flag == NDebug)
 			pprint("suicide: %s\n", n->msg);
-		qunlock(&up->debug);
 		pexit(n->msg, n->flag != NDebug);
 	}
 	if(up->notified){
@@ -247,7 +247,6 @@
 		break;
 	
 	default:
-		pprint("unknown noted arg 0x%lux\n", arg0);
 		up->lastnote.flag = NDebug;
 		/* fallthrough */
 	
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -846,9 +846,9 @@
 	}
 
 	if(n->flag!=NUser && (up->notified || up->notify==0)){
+		qunlock(&up->debug);
 		if(n->flag == NDebug)
 			pprint("suicide: %s\n", n->msg);
-		qunlock(&up->debug);
 		pexit(n->msg, n->flag!=NDebug);
 	}
 
@@ -964,16 +964,13 @@
 		break;
 
 	default:
-		pprint("unknown noted arg 0x%lux\n", arg0);
 		up->lastnote.flag = NDebug;
 		/* fall through */
 
 	case NDFLT:
-		if(up->lastnote.flag == NDebug){
-			qunlock(&up->debug);
+		qunlock(&up->debug);
+		if(up->lastnote.flag == NDebug)
 			pprint("suicide: %s\n", up->lastnote.msg);
-		} else
-			qunlock(&up->debug);
 		pexit(up->lastnote.msg, up->lastnote.flag!=NDebug);
 	}
 }
--- a/sys/src/9/port/devproc.c
+++ b/sys/src/9/port/devproc.c
@@ -446,7 +446,7 @@
 		break;
 
 	default:
-		pprint("procopen %#lux\n", QID(c->qid));
+		print("procopen %#lux\n", QID(c->qid));
 		error(Egreg);
 	}
 
@@ -1156,7 +1156,7 @@
 			error(Ebadarg);
 		break;
 	default:
-		pprint("unknown qid in procwrite\n");
+		print("unknown qid in procwrite\n");
 		error(Egreg);
 	}
 	poperror();
--- a/sys/src/9/port/fault.c
+++ b/sys/src/9/port/fault.c
@@ -328,7 +328,6 @@
 			return 1;
 		}
 	}
-	pprint("suicide: invalid address %#lux/%lud in sys call pc=%#lux\n", addr, len, userpc());
 	return 0;
 }
 
@@ -336,6 +335,7 @@
 validaddr(ulong addr, ulong len, int write)
 {
 	if(!okaddr(addr, len, write)){
+		pprint("suicide: invalid address %#lux/%lud in sys call pc=%#lux\n", addr, len, userpc());
 		postnote(up, 1, "sys: bad address in syscall", NDebug);
 		error(Ebadarg);
 	}
--- a/sys/src/9/ppc/trap.c
+++ b/sys/src/9/ppc/trap.c
@@ -728,9 +728,9 @@
 	}
 
 	if(n->flag!=NUser && (up->notified || up->notify==0)){
+		qunlock(&up->debug);
 		if(n->flag == NDebug)
 			pprint("suicide: %s\n", n->msg);
-		qunlock(&up->debug);
 		pexit(n->msg, n->flag!=NDebug);
 	}
 
@@ -750,8 +750,8 @@
 
 	if(!okaddr((ulong)up->notify, BY2WD, 0) ||
 	   !okaddr(sp-ERRMAX-4*BY2WD, sizeof(Ureg)+ERRMAX+4*BY2WD, 1)) {
-		pprint("suicide: bad address or sp in notify\n");
 		qunlock(&up->debug);
+		pprint("suicide: bad address or sp in notify\n");
 		pexit("Suicide", 0);
 	}
 
@@ -800,8 +800,8 @@
 	/* sanity clause */
 	oureg = (ulong)nureg;
 	if(!okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){
-		pprint("bad ureg in noted or call to noted when not notified\n");
 		qunlock(&up->debug);
+		pprint("bad ureg in noted or call to noted when not notified\n");
 		pexit("Suicide", 0);
 	}
 
@@ -811,8 +811,8 @@
 	case NCONT:
 	case NRSTR:
 		if(!okaddr(nureg->pc, 1, 0) || !okaddr(nureg->usp, BY2WD, 0)){
-			pprint("suicide: trap in noted\n");
 			qunlock(&up->debug);
+			pprint("suicide: trap in noted\n");
 			pexit("Suicide", 0);
 		}
 		up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD));
@@ -822,8 +822,8 @@
 	case NSAVE:
 		if(!okaddr(nureg->pc, BY2WD, 0)
 		|| !okaddr(nureg->usp, BY2WD, 0)){
-			pprint("suicide: trap in noted\n");
 			qunlock(&up->debug);
+			pprint("suicide: trap in noted\n");
 			pexit("Suicide", 0);
 		}
 		qunlock(&up->debug);
@@ -835,14 +835,13 @@
 		break;
 
 	default:
-		pprint("unknown noted arg 0x%lux\n", arg0);
 		up->lastnote.flag = NDebug;
 		/* fall through */
 		
 	case NDFLT:
+		qunlock(&up->debug);
 		if(up->lastnote.flag == NDebug)
 			pprint("suicide: %s\n", up->lastnote.msg);
-		qunlock(&up->debug);
 		pexit(up->lastnote.msg, up->lastnote.flag!=NDebug);
 	}
 	up->fpstate &= ~FPillegal;
--- a/sys/src/9/teg2/syscall.c
+++ b/sys/src/9/teg2/syscall.c
@@ -86,16 +86,12 @@
 		cur->sp = PTR2UINT(nf);
 		break;
 	default:
-		pprint("unknown noted arg %#p\n", arg0);
 		up->lastnote.flag = NDebug;
 		/*FALLTHROUGH*/
 	case NDFLT:
-		if(up->lastnote.flag == NDebug){ 
-			qunlock(&up->debug);
+		qunlock(&up->debug);
+		if(up->lastnote.flag == NDebug)
 			pprint("suicide: %s\n", up->lastnote.msg);
-		}
-		else
-			qunlock(&up->debug);
 		pexit(up->lastnote.msg, up->lastnote.flag != NDebug);
 	}
 }
@@ -133,9 +129,9 @@
 	}
 
 	if(n->flag != NUser && (up->notified || up->notify == 0)){
+		qunlock(&up->debug);
 		if(n->flag == NDebug)
 			pprint("suicide: %s\n", n->msg);
-		qunlock(&up->debug);
 		pexit(n->msg, n->flag != NDebug);
 	}
 
@@ -150,8 +146,8 @@
 		pexit(n->msg, n->flag != NDebug);
 	}
 	if(!okaddr(PTR2UINT(up->notify), 1, 0)){
-		pprint("suicide: notify function address %#p\n", up->notify);
 		qunlock(&up->debug);
+		pprint("suicide: notify function address %#p\n", up->notify);
 		pexit("Suicide", 0);
 	}