Subject: bin/2665: kvm_mkdb may not upgrade /var/db/kvm_netbsd.db on some archs
To: None <gnats-bugs@NetBSD.ORG>
From: None <leo@marco.de>
List: netbsd-bugs
Date: 07/31/1996 14:43:00
>Number:         2665
>Category:       bin
>Synopsis:       kvm_mkdb may not upgrade /var/db/kvm_netbsd.db on some archs
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jul 31 09:05:01 1996
>Last-Modified:
>Originator:     Matthias Pfaller
>Organization:
leo@dachau.marco.de			in real life: Matthias Pfaller
marco GmbH, 85221 Dachau, Germany	tel: +49 8131 516142
>Release:        1.2_BETA
>Environment:
	
System: NetBSD klondike 1.2_BETA NetBSD 1.2_BETA (KLONDIKE) #62: Sat Jul 20 01:29:59 MET DST 1996 leo@klondike:/usr/src/sys/arch/pc532/compile/KLONDIKE pc532


>Description:
	The code in src/usr.sbin/kvm_mkdb/nlist.c tries to find the
	offset of the version[] array in the kernel binary. It
	relies on the fact that the symbol _kernel_text marks the
	start of the kernel text segment. On systems linking the
	kernel with -z (or -Q?), the kernel text segment starts at
	(_kernel_text - sizeof(struct exec)). When kvm_mkdb hits an
	empty string as the kernel version, the call to bcmp in
	dbtest.c will alway return success for future invocations
	of kvom_mkdb.

>How-To-Repeat:
	Get a kernel that has a null byte at (_version - sizeof(struct exec)),
	do a kvm_mkdb on a pc532 (or an i386?) and your kvm_netbsd.db will no
	longer get updated.

>Fix:
--- usr.sbin/kvm_mkdb/nlist.c.ORIG	Fri May 17 14:16:24 1996
+++ usr.sbin/kvm_mkdb/nlist.c	Sat Jul 20 01:14:02 1996
@@ -59,7 +59,7 @@
 #define	badfmt(str)	errx(1, "%s: %s: %s", kfile, str, strerror(EFTYPE))
 
 static void badread __P((int, char *));
-static u_long get_kerntext __P((char *kfn));
+static u_long get_kerntext __P((char *kfn, int magic));
 
 static char *kfile;
 
@@ -117,7 +117,7 @@
 	data.data = (u_char *)&nbuf;
 	data.size = sizeof(NLIST);
 
-	kerntextoff = get_kerntext(name);
+	kerntextoff = get_kerntext(name, N_GETMAGIC(ebuf));
 
 	/* Read each symbol and enter it into the database. */
 	nsyms = ebuf.a_syms / sizeof(struct nlist);
@@ -201,8 +201,9 @@
 #endif
 
 static u_long
-get_kerntext(name)
+get_kerntext(name, magic)
 	char *name;
+	int magic;
 {
 	NLIST nl[2];
 
@@ -212,5 +213,12 @@
 	if (nlist(name, nl) != 0)
 		return (KERNTEXTOFF);
 
-	return (nl[0].n_value);
+	/*
+	 * For ZMAGIC (and QMAGIC?) binaries, the text segment starts
+	 * at _kernel_text - sizeof(struct exec).
+	 */
+	if (magic == ZMAGIC || magic == QMAGIC)
+		return (nl[0].n_value - sizeof(struct exec));
+	else
+		return (nl[0].n_value);
 }
>Audit-Trail:
>Unformatted: