Module Name:    src
Committed By:   riastradh
Date:           Tue Jun  1 21:11:07 UTC 2021

Modified Files:
        src/sys/kern: kern_ksyms.c

Log Message:
ksyms(4): Modify ksyms_symtabs only at IPL_HIGH.

This limits the opportunities for ddb to witness an inconsistent
state of the symbol table list.


To generate a diff of this commit:
cvs rdiff -u -r1.90 -r1.91 src/sys/kern/kern_ksyms.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_ksyms.c
diff -u src/sys/kern/kern_ksyms.c:1.90 src/sys/kern/kern_ksyms.c:1.91
--- src/sys/kern/kern_ksyms.c:1.90	Tue Jun  1 21:10:23 2021
+++ src/sys/kern/kern_ksyms.c	Tue Jun  1 21:11:07 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_ksyms.c,v 1.90 2021/06/01 21:10:23 riastradh Exp $	*/
+/*	$NetBSD: kern_ksyms.c,v 1.91 2021/06/01 21:11:07 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -73,7 +73,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.90 2021/06/01 21:10:23 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.91 2021/06/01 21:11:07 riastradh Exp $");
 
 #if defined(_KERNEL) && defined(_KERNEL_OPT)
 #include "opt_copy_symtab.h"
@@ -93,6 +93,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c
 #include <sys/atomic.h>
 #include <sys/ksyms.h>
 #include <sys/kernel.h>
+#include <sys/intr.h>
 
 #ifdef DDB
 #include <ddb/db_output.h>
@@ -308,6 +309,7 @@ addsymtab(const char *name, void *symsta
 	int i, j, n, nglob;
 	char *str;
 	int nsyms = symsize / sizeof(Elf_Sym);
+	int s;
 
 	/* Sanity check for pre-allocated map table used during startup. */
 	if ((nmap == ksyms_nmap) && (nsyms >= KSYMS_MAX_ID)) {
@@ -443,7 +445,14 @@ addsymtab(const char *name, void *symsta
 	KASSERT(strcmp(name, "netbsd") == 0 || mutex_owned(&ksyms_lock));
 	KASSERT(cold || mutex_owned(&ksyms_lock));
 
+	/*
+	 * Ensure ddb never witnesses an inconsistent state of the
+	 * queue, unless memory is so corrupt that we crash in
+	 * TAILQ_INSERT_TAIL.
+	 */
+	s = splhigh();
 	TAILQ_INSERT_TAIL(&ksyms_symtabs, tab, sd_queue);
+	splx(s);
 
 	ksyms_sizes_calc();
 	ksyms_loaded = true;
@@ -772,6 +781,7 @@ ksyms_modunload(const char *name)
 {
 	struct ksyms_symtab *st;
 	bool do_free = false;
+	int s;
 
 	mutex_enter(&ksyms_lock);
 	TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) {
@@ -782,7 +792,14 @@ ksyms_modunload(const char *name)
 		st->sd_gone = true;
 		ksyms_sizes_calc();
 		if (!ksyms_isopen) {
+			/*
+			 * Ensure ddb never witnesses an inconsistent
+			 * state of the queue, unless memory is so
+			 * corrupt that we crash in TAILQ_REMOVE.
+			 */
+			s = splhigh();
 			TAILQ_REMOVE(&ksyms_symtabs, st, sd_queue);
+			splx(s);
 			do_free = true;
 		}
 		break;
@@ -1015,6 +1032,7 @@ ksymsclose(dev_t dev, int oflags, int de
 {
 	struct ksyms_symtab *st, *next;
 	TAILQ_HEAD(, ksyms_symtab) to_free = TAILQ_HEAD_INITIALIZER(to_free);
+	int s;
 
 	/* Discard references to symbol tables. */
 	mutex_enter(&ksyms_lock);
@@ -1022,7 +1040,14 @@ ksymsclose(dev_t dev, int oflags, int de
 	ksyms_last_snapshot = NULL;
 	TAILQ_FOREACH_SAFE(st, &ksyms_symtabs, sd_queue, next) {
 		if (st->sd_gone) {
+			/*
+			 * Ensure ddb never witnesses an inconsistent
+			 * state of the queue, unless memory is so
+			 * corrupt that we crash in TAILQ_REMOVE.
+			 */
+			s = splhigh();
 			TAILQ_REMOVE(&ksyms_symtabs, st, sd_queue);
+			splx(s);
 			TAILQ_INSERT_TAIL(&to_free, st, sd_queue);
 		}
 	}

Reply via email to