Module Name:    src
Committed By:   martin
Date:           Tue Jan  7 11:54:58 UTC 2020

Modified Files:
        src/sys/kern [netbsd-9]: kern_ksyms.c

Log Message:
Pull up following revision(s) (requested by pgoyette in ticket #609):

        sys/kern/kern_ksyms.c: revision 1.88

When reading from /dev/ksyms we need to skip over entries that have
been marked as sd_gone.  Otherwise we might try to uiomove() data from
memory that has been unmapped, resulting in EFAULT.

XXX This (along with other pre-existing checks st->sd_gone) is still
racy, but it's an improvement over current code.  Ideally we would
make a complete copy of the symbol table when we open /dev/ksyms so
we could ignore any changes that occur.

ad@ says "good enough for now"

XXX Pullup to -9 and -8


To generate a diff of this commit:
cvs rdiff -u -r1.87 -r1.87.8.1 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.87 src/sys/kern/kern_ksyms.c:1.87.8.1
--- src/sys/kern/kern_ksyms.c:1.87	Sat Nov  4 22:17:55 2017
+++ src/sys/kern/kern_ksyms.c	Tue Jan  7 11:54:57 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_ksyms.c,v 1.87 2017/11/04 22:17:55 christos Exp $	*/
+/*	$NetBSD: kern_ksyms.c,v 1.87.8.1 2020/01/07 11:54:57 martin 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.87 2017/11/04 22:17:55 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.87.8.1 2020/01/07 11:54:57 martin Exp $");
 
 #if defined(_KERNEL) && defined(_KERNEL_OPT)
 #include "opt_copy_symtab.h"
@@ -765,9 +765,9 @@ ksyms_modunload(const char *name)
 		if (strcmp(name, st->sd_name) != 0)
 			continue;
 		st->sd_gone = true;
+		ksyms_sizes_calc();
 		if (!ksyms_isopen) {
 			TAILQ_REMOVE(&ksyms_symtabs, st, sd_queue);
-			ksyms_sizes_calc();
 			kmem_free(st->sd_nmap,
 				  st->sd_nmapsize * sizeof(uint32_t));
 			kmem_free(st, sizeof(*st));
@@ -856,6 +856,8 @@ ksyms_sizes_calc(void)
 
 	ksyms_symsz = ksyms_strsz = 0;
 	TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) {
+		if (__predict_false(st->sd_gone))
+			continue;
 		delta = ksyms_strsz - st->sd_usroffset;
 		if (delta != 0) {
 			for (i = 0; i < st->sd_symsize/sizeof(Elf_Sym); i++)
@@ -1034,6 +1036,8 @@ ksymsread(dev_t dev, struct uio *uio, in
 	 */
 	filepos = sizeof(struct ksyms_hdr);
 	TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) {
+		if (__predict_false(st->sd_gone))
+			continue;
 		if (uio->uio_resid == 0)
 			return 0;
 		if (uio->uio_offset <= st->sd_symsize + filepos) {
@@ -1052,6 +1056,8 @@ ksymsread(dev_t dev, struct uio *uio, in
 	KASSERT(filepos == sizeof(struct ksyms_hdr) +
 	    ksyms_hdr.kh_shdr[SYMTAB].sh_size);
 	TAILQ_FOREACH(st, &ksyms_symtabs, sd_queue) {
+		if (__predict_false(st->sd_gone))
+			continue;
 		if (uio->uio_resid == 0)
 			return 0;
 		if (uio->uio_offset <= st->sd_strsize + filepos) {

Reply via email to