Subject: Re: kern/15502: savecore: /netbsd: kvm_dump_mkheader: Pread: Invalid argument
To: None <netbsd-bugs@netbsd.org>
From: Wolfgang Rupprecht <wolfgang+gnus20020205T183629@wsrcc.com>
List: netbsd-bugs
Date: 02/05/2002 18:44:07
anne@alcor.concordia.ca writes:
> >Synopsis:       savecore: /netbsd: kvm_dump_mkheader: Pread: Invalid argument

This appears to be a 32-bit overflow in the "dumplo" variable.  I've
been meaning to send this in for a while.

To reproduce the problem make a dump partition with over 2 gigs of
storage.  Dumplo turns negative and the kvm_dump_mkheader() fails when
it tries to seek to the large negative offset.

-wolfgang

NB. KREAD() only returns a long, so this problem will happen again
when swap partitions get 512x bigger, but that shouldn't be for a few
years.

Index: savecore.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/savecore/savecore.c,v
retrieving revision 1.55
diff -u -r1.55 savecore.c
--- savecore.c	2001/11/01 07:39:38	1.55
+++ savecore.c	2002/02/01 00:51:02
@@ -115,7 +115,7 @@
 };
 
 /* Types match kernel declarations. */
-long	dumplo;				/* where dump starts on dumpdev */
+off_t	dumplo;				/* where dump starts on dumpdev */
 int	dumpmag;			/* magic number in dump */
 int	dumpsize;			/* amount of memory dumped */
 
@@ -274,19 +274,24 @@
 		syslog(LOG_WARNING, "no core dump (no dumpdev)");
 		exit(1);
 	}
-	if (KREAD(kd_kern, current_nl[X_DUMPLO].n_value, &dumplo) != 0) {
-		if (verbose)
-		    syslog(LOG_WARNING, "kvm_read: %s", kvm_geterr(kd_kern));
+	{
+	    long l_dumplo;
+
+	    if (KREAD(kd_kern, current_nl[X_DUMPLO].n_value, &l_dumplo) != 0) {
+		    if (verbose)
+			syslog(LOG_WARNING, "kvm_read: %s", kvm_geterr(kd_kern));
+		    exit(1);
+	    }
+	    if (l_dumplo == -1) {
+		syslog(LOG_WARNING, "no core dump (invalid dumplo)");
 		exit(1);
+	    }
+	    dumplo = DEV_BSIZE * (off_t) l_dumplo;
 	}
-	if (dumplo == -1) {
-	    syslog(LOG_WARNING, "no core dump (invalid dumplo)");
-	    exit(1);
-	}
-	dumplo *= DEV_BSIZE;
+
 	if (verbose)
-		(void)printf("dumplo = %ld (%ld * %ld)\n",
-		    (long)dumplo, (long)(dumplo / DEV_BSIZE), (long)DEV_BSIZE);
+		(void)printf("dumplo = %lld (%ld * %ld)\n",
+		    (long long)dumplo, (long)(dumplo / DEV_BSIZE), (long)DEV_BSIZE);
 	if (KREAD(kd_kern, current_nl[X_DUMPMAG].n_value, &dumpmag) != 0) {
 		if (verbose)
 		    syslog(LOG_WARNING, "kvm_read: %s", kvm_geterr(kd_kern));
@@ -316,7 +321,7 @@
 			    kernel, dump_nl[dumpsyms[i]].n_name);
 			exit(1);
 		}
-	hdrsz = kvm_dump_mkheader(kd_dump, (off_t)dumplo);
+	hdrsz = kvm_dump_mkheader(kd_dump, dumplo);
 
 	/*
 	 * If 'hdrsz' == 0, kvm_dump_mkheader() failed on the magic-number
@@ -533,7 +538,7 @@
 	}
 
 	/* Seek to the start of the core. */
-	Lseek(ifd, (off_t)dumplo, SEEK_SET);
+	Lseek(ifd, dumplo, SEEK_SET);
 
 	if (kvm_dump_wrtheader(kd_dump, fp, dumpsize) == -1) {
 		syslog(LOG_ERR, "kvm_dump_wrtheader: %s : %s", path,



-- 
       Wolfgang Rupprecht <wolfgang+gnus@dailyplanet.wsrcc.com>
		    http://www.wsrcc.com/wolfgang/
Coming soon: GPS mapping tools for Open Systems. http://www.gnomad-mapping.com/