kvm_deadprocs returns -1 to signify an error.
Current kvm_getprocs code would pass this return code as 'cnt' out parameter and
would not reset return value to NULL.
This confuses some callers, most prominently procstat_getprocs, into believing
that kvm_getprocs was successful.  Moreover, the code tried to use cnt=-1 as an
unsigned number to allocate some additional memory.  As a result fstat -M could
try to allocate huge amount of memory e.g. when used with a kernel that didn't
match userland.

With the proposed change the error code should be handled properly.
Additionally it should now be possible to enable realloc code, which previously
contained a bug and was called even after kvm_deadprocs error.

commit 6ddf602409119eded40321e5bb349b464f24e81a
Author: Andriy Gapon <a...@icyb.net.ua>
Date:   Sun Sep 23 22:52:28 2012 +0300

    kvm_proc: gracefully handle errors in kvm_deadprocs, don't confuse callers

    Plus fix a bug under 'notdef' (sic) section.

diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
index d1daf77..31258d7 100644
--- a/lib/libkvm/kvm_proc.c
+++ b/lib/libkvm/kvm_proc.c
@@ -593,9 +593,15 @@ liveout:

                nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value,
                                      nl[2].n_value, nprocs);
+               if (nprocs <= 0) {
+                       _kvm_freeprocs(kd);
+                       nprocs = 0;
+               }
 #ifdef notdef
-               size = nprocs * sizeof(struct kinfo_proc);
-               (void)realloc(kd->procbase, size);
+               else {
+                       size = nprocs * sizeof(struct kinfo_proc);
+                       kd->procbase = realloc(kd->procbase, size);
+               }
 #endif
        }
        *cnt = nprocs;

P.S. it might may sense to change 'count' parameter of procstat_getprocs to 
signed
int so that it matches kvm_getprocs interface.  Alternatively, an intermediate
variable could be used to insulate signedness difference:

index 56562e1..11a817e 100644
--- a/lib/libprocstat/libprocstat.c
+++ b/lib/libprocstat/libprocstat.c
@@ -184,15 +184,18 @@ procstat_getprocs(struct procstat *procstat, int what, 
int arg,
        struct kinfo_proc *p0, *p;
        size_t len;
        int name[4];
+       int cnt;
        int error;

        assert(procstat);
        assert(count);
        p = NULL;
        if (procstat->type == PROCSTAT_KVM) {
-               p0 = kvm_getprocs(procstat->kd, what, arg, count);
-               if (p0 == NULL || count == 0)
+               *count = 0;
+               p0 = kvm_getprocs(procstat->kd, what, arg, &cnt);
+               if (p0 == NULL || cnt <= 0)
                        return (NULL);
+               *count = cnt;
                len = *count * sizeof(*p);
                p = malloc(len);
                if (p == NULL) {



-- 
Andriy Gapon
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Reply via email to