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: