Hi,

In a separate mail thread, bluhm@ mentioned that panic(9) does not
cleanly handle multiple CPUs entering it simultaneously:

https://marc.info/?l=openbsd-tech&m=161908805925325&w=2

I'm unsure which part of panic(9) is causing the problem he mentions,
but one obvious issue I see is that panicstr is not set atomically,
so two CPUs entering panic(9) simultaneously may clobber panicbuf.

If we set panicstr atomically only one CPU will write panicbuf.

Thoughts?

Index: kern/subr_prf.c
===================================================================
RCS file: /cvs/src/sys/kern/subr_prf.c,v
retrieving revision 1.102
diff -u -p -r1.102 subr_prf.c
--- kern/subr_prf.c     28 Nov 2020 17:53:05 -0000      1.102
+++ kern/subr_prf.c     13 May 2021 00:04:28 -0000
@@ -97,7 +97,7 @@ struct mutex kprintf_mutex =
  */
 
 extern int log_open;   /* subr_log: is /dev/klog open? */
-const  char *panicstr; /* arg to first call to panic (used as a flag
+volatile const char *panicstr; /* arg to first call to panic (used as a flag
                           to indicate that panic has already been called). */
 const  char *faultstr; /* page fault string */
 #ifdef DDB
@@ -195,12 +195,10 @@ panic(const char *fmt, ...)
 
        bootopt = RB_AUTOBOOT | RB_DUMP;
        va_start(ap, fmt);
-       if (panicstr)
+       if (atomic_cas_ptr(&panicstr, NULL, panicbuf) != NULL)
                bootopt |= RB_NOSYNC;
-       else {
+       else
                vsnprintf(panicbuf, sizeof panicbuf, fmt, ap);
-               panicstr = panicbuf;
-       }
        va_end(ap);
 
        printf("panic: ");
Index: sys/systm.h
===================================================================
RCS file: /cvs/src/sys/sys/systm.h,v
retrieving revision 1.153
diff -u -p -r1.153 systm.h
--- sys/systm.h 28 Apr 2021 09:42:04 -0000      1.153
+++ sys/systm.h 13 May 2021 00:04:28 -0000
@@ -71,7 +71,7 @@
  * patched by a stalking hacker.
  */
 extern int securelevel;                /* system security level */
-extern const char *panicstr;   /* panic message */
+extern volatile const char *panicstr;  /* panic message */
 extern const char *faultstr;   /* fault message */
 extern const char version[];           /* system version */
 extern const char copyright[]; /* system copyright */

Reply via email to