ref: 3258ec2db178f2df85ab3fe360b89bac608e3c04
parent: 29df7173e25df1922686ac8b1c7cafb8b49c9ba9
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Jun 27 13:01:02 EDT 2025
kernel: fix crash in fpunoted() when called from noted(NRSTR) (thanks yuvia) We must call fpunoted() only when actually notified. In case of NRSTR, it can be called from outside of note handler! This issue was reproduced by hitting del on ape/psh prompt.
--- a/sys/src/9/arm64/trap.c
+++ b/sys/src/9/arm64/trap.c
@@ -268,16 +268,16 @@
uintptr oureg, sp;
qlock(&up->debug);
- if(arg0 != NRSTR && !up->notified){
+ if(up->notified){
+ up->notified = 0;
+ splhi();
+ fpunoted(up);
+ spllo();
+ } else if(arg0!=NRSTR){
qunlock(&up->debug);
pprint("call to noted() when not notified\n");
pexit("Suicide", 0);
}
- up->notified = 0;
-
- splhi();
- fpunoted(up);
- spllo();
nureg = up->ureg;
--- a/sys/src/9/cycv/trap.c
+++ b/sys/src/9/cycv/trap.c
@@ -292,17 +292,17 @@
ulong oureg, sp;
qlock(&up->debug);
- if(arg0 != NRSTR && !up->notified){
+ if(up->notified){
+ up->notified = 0;
+ splhi();
+ fpunoted();
+ spllo();
+ } else if(arg0!=NRSTR){
qunlock(&up->debug);
pprint("call to noted() when not notified\n");
pexit("Suicide", 0);
}
- up->notified = 0;
- splhi();
- fpunoted();
- spllo();
-
nureg = up->ureg;
oureg = (ulong) nureg;
if(!okaddr(oureg - BY2WD, BY2WD + sizeof(Ureg), 0) || (oureg & 3) != 0){
--- a/sys/src/9/mt7688/syscall.c
+++ b/sys/src/9/mt7688/syscall.c
@@ -116,14 +116,14 @@
ulong oureg, sp;
qlock(&up->debug);
- if(arg0!=NRSTR && !up->notified) {
+ if(up->notified){
+ up->notified = 0;
+ fpunoted();
+ } else if(arg0!=NRSTR){
qunlock(&up->debug);
pprint("call to noted() when not notified\n");
pexit("Suicide", 0);
}
- up->notified = 0;
-
- fpunoted();
nur = up->ureg;
--- a/sys/src/9/omap/syscall.c
+++ b/sys/src/9/omap/syscall.c
@@ -28,16 +28,16 @@
NFrame *nf;
qlock(&up->debug);
- if(arg0 != NRSTR && !up->notified){
+ if(up->notified){
+ up->notified = 0;
+ splhi();
+ fpunoted();
+ spllo();
+ } else if(arg0!=NRSTR){
qunlock(&up->debug);
pprint("call to noted() when not notified\n");
pexit("Suicide", 0);
}
- up->notified = 0;
-
- splhi();
- fpunoted();
- spllo();
nf = up->ureg;
--- a/sys/src/9/pc/trap.c
+++ b/sys/src/9/pc/trap.c
@@ -534,16 +534,16 @@
ulong oureg, sp;
qlock(&up->debug);
- if(arg0!=NRSTR && !up->notified) {
+ if(up->notified){
+ up->notified = 0;
+ splhi();
+ fpunoted(up);
+ spllo();
+ } else if(arg0!=NRSTR){
qunlock(&up->debug);
pprint("call to noted() when not notified\n");
pexit("Suicide", 0);
}
- up->notified = 0;
-
- splhi();
- fpunoted(up);
- spllo();
nureg = up->ureg; /* pointer to user returned Ureg struct */
--- a/sys/src/9/pc64/trap.c
+++ b/sys/src/9/pc64/trap.c
@@ -516,16 +516,16 @@
uintptr oureg, sp;
qlock(&up->debug);
- if(arg0!=NRSTR && !up->notified) {
+ if(up->notified){
+ up->notified = 0;
+ splhi();
+ fpunoted(up);
+ spllo();
+ } else if(arg0!=NRSTR){
qunlock(&up->debug);
pprint("call to noted() when not notified\n");
pexit("Suicide", 0);
}
- up->notified = 0;
-
- splhi();
- fpunoted(up);
- spllo();
nureg = up->ureg; /* pointer to user returned Ureg struct */
--- a/sys/src/9/sgi/trap.c
+++ b/sys/src/9/sgi/trap.c
@@ -528,16 +528,16 @@
ulong oureg, sp;
qlock(&up->debug);
- if(arg0!=NRSTR && !up->notified) {
+ if(up->notified){
+ up->notified = 0;
+ splhi();
+ fpunoted();
+ spllo();
+ } else if(arg0!=NRSTR){
qunlock(&up->debug);
pprint("call to noted() when not notified\n");
pexit("Suicide", 0);
}
- up->notified = 0;
-
- splhi();
- fpunoted();
- spllo();
nur = up->ureg;
oureg = (ulong)nur;
--- a/sys/src/9/xen/trap.c
+++ b/sys/src/9/xen/trap.c
@@ -440,16 +440,16 @@
ulong oureg, sp;
qlock(&up->debug);
- if(arg0!=NRSTR && !up->notified) {
+ if(up->notified){
+ up->notified = 0;
+ splhi();
+ fpunoted(up);
+ spllo();
+ } else if(arg0!=NRSTR){
qunlock(&up->debug);
pprint("call to noted() when not notified\n");
pexit("Suicide", 0);
}
- up->notified = 0;
-
- splhi();
- fpunoted(up);
- spllo();
nureg = up->ureg; /* pointer to user returned Ureg struct */
--- a/sys/src/9/zynq/trap.c
+++ b/sys/src/9/zynq/trap.c
@@ -331,16 +331,16 @@
ulong oureg, sp;
qlock(&up->debug);
- if(arg0 != NRSTR && !up->notified){
+ if(up->notified){
+ up->notified = 0;
+ splhi();
+ fpunoted();
+ spllo();
+ } else if(arg0!=NRSTR){
qunlock(&up->debug);
pprint("call to noted() when not notified\n");
pexit("Suicide", 0);
}
- up->notified = 0;
-
- splhi();
- fpunoted();
- spllo();
nureg = up->ureg;
oureg = (ulong) nureg;
--
⑨