aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2020-12-15 00:05:17 -0500
committerRuss Cox <rsc@swtch.com>2020-12-15 00:06:03 -0500
commit2991442aef1cf020ffde43673433ee97ef322a53 (patch)
tree528bf5357535af9af48034f81eafd1e8a9913564
parenta012d174336358f997ddcb0099c0b01499b053e4 (diff)
downloadplan9port-2991442aef1cf020ffde43673433ee97ef322a53.tar.gz
plan9port-2991442aef1cf020ffde43673433ee97ef322a53.tar.bz2
plan9port-2991442aef1cf020ffde43673433ee97ef322a53.zip
libthread: fix use after free of first thread in each proc
This was causing sporadic but frequent crashes at startup in 9pserve on the new M1 Macs, correctly diagnosing a use-after-free.
-rw-r--r--src/libthread/thread.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/libthread/thread.c b/src/libthread/thread.c
index 902942d9..65e65194 100644
--- a/src/libthread/thread.c
+++ b/src/libthread/thread.c
@@ -411,7 +411,14 @@ Top:
p->nthread--;
/*print("nthread %d\n", p->nthread); */
_threadstkfree(t->stk, t->stksize);
- free(t);
+ /*
+ * Cannot free p->thread0 yet: it is used for the
+ * context switches back to the scheduler.
+ * Instead, we will free it at the end of this function.
+ * But all the other threads can be freed now.
+ */
+ if(t != p->thread0)
+ free(t);
}
for(;;){
@@ -490,6 +497,7 @@ Out:
unlock(&threadnproclock);
unlock(&p->lock);
_threadsetproc(nil);
+ free(p->thread0);
free(p);
_threadpexit();
}