DragonFly bugs List (threaded) for 2009-05
DragonFly BSD
DragonFly bugs List (threaded) for 2009-05
[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]

zero-size malloc and ps: kvm_getprocs: Bad address


From: YONETANI Tomokazu <qhwt+dfly@xxxxxxxxxx>
Date: Sun, 24 May 2009 11:35:47 +0900

Hello.
On recent -DEVELOPMENT ps command displays a non-intuitive error message
on a non-existent pid:
  ps: kvm_getprocs: Bad address

Apparently the recent malloc reimplementation has changed malloc(3) family
so as malloc(0) now returns a pointer such that useracc() returns EFAULT
for it.  kvm_getprocs() is one the functions affected by the new behavior
(no, I don't have the list of affected functions other than this
yet :).  It used to return a non-NULL pointer and a 0 to *cnt, but now
it returns just NULL without affecting *cnt, so ps command displays the
error message.  I think one way to fix is something like below (the fix
to the callers is taken from FreeBSD), but if we can restore the old
behavior of malloc(0), we don't need such fix.

%%%
diff --git a/bin/ps/ps.c b/bin/ps/ps.c
index 82e3e63..b66988a 100644
--- a/bin/ps/ps.c
+++ b/bin/ps/ps.c
@@ -385,7 +385,9 @@ main(int argc, char **argv)
 	/*
 	 * select procs
 	 */
-	if ((kp = kvm_getprocs(kd, what, flag, &nentries)) == NULL)
+	nentries = -1;
+	kp = kvm_getprocs(kd, what, flag, &nentries);
+	if ((kp == NULL && nentries > 0) || (kp != NULL && nentries < 0))
 		errx(1, "%s", kvm_geterr(kd));
 	if ((kinfo = malloc(nentries * sizeof(*kinfo))) == NULL)
 		err(1, NULL);
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
index 1c39636..d0e388d 100644
--- a/lib/libkvm/kvm_proc.c
+++ b/lib/libkvm/kvm_proc.c
@@ -479,6 +479,10 @@ kvm_getprocs(kvm_t *kd, int op, int arg, int *cnt)
 			_kvm_syserr(kd, kd->program, "kvm_getprocs");
 			return (0);
 		}
+		if (size == 0) {
+			*cnt = 0;
+			return (0);
+		}
 		do {
 			size += size / 10;
 			kd->procbase = (struct kinfo_proc *)
diff --git a/usr.bin/fstat/fstat.c b/usr.bin/fstat/fstat.c
index 133fff7..7a8545d 100644
--- a/usr.bin/fstat/fstat.c
+++ b/usr.bin/fstat/fstat.c
@@ -241,7 +241,9 @@ main(int argc, char **argv)
 	if (kvm_nlist(kd, nl) != 0)
 		errx(1, "no namelist: %s", kvm_geterr(kd));
 #endif
-	if ((p = kvm_getprocs(kd, what, arg, &cnt)) == NULL)
+	cnt = -1;
+	p = kvm_getprocs(kd, what, arg, &cnt);
+	if ((p == NULL && cnt > 0) || (p != NULL && cnt < 0))
 		errx(1, "%s", kvm_geterr(kd));
 	if (nflg)
 		printf("USER     %-*.*s %*.*s   FD DEV              %*.*s MODE   SZ|DV R/W", 
%%%



[Date Prev][Date Next]  [Thread Prev][Thread Next]  [Date Index][Thread Index]