Thank you for the speedy reply! Unfortunately, with your patch, start-stop-daemon crashes. With valgrind (kfreebsd patches in stalled bug https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=702729) the site of the crash is spelled out:
Invalid read of size 4 at 0x40221B: do_findprocs (start-stop-daemon.c:1796) by 0x402264: do_stop (start-stop-daemon.c:1932) by 0x4037B3: main (start-stop-daemon.c:2117) Address 0x1b91e28 is 1,160 bytes inside a block of size 1,080,710 free'd at 0x100D1BC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-freebsd.so) by 0x12176BE: kvm_getprocs (in /lib/libkvm.so.6) by 0x401EA4: ssd_kvm_get_procs (start-stop-daemon.c:1273) by 0x402085: pid_check (start-stop-daemon.c:1610) by 0x402224: do_findprocs (start-stop-daemon.c:1796) by 0x402264: do_stop (start-stop-daemon.c:1932) by 0x4037B3: main (start-stop-daemon.c:2117) .. it appears that each call to ssd_kvm_get_procs(kd) frees the result of a previous call to ssd_kvm_get_procs(kd). Before your patch, the kd in each call was distinct; but now it is the same. The manpage for kvm_getprocs has this to say: The memory allocated to the argv pointers and string storage is owned by the kvm library. Subsequent kvm_getprocs() and kvm_close(3) calls will clobber this storage. which seems to be exactly what is going on. Boo. If you feel that a patch that doesn't change program flow is lower-impact, then this alternative does run for me. It makes each each function with a kvm_t local declare it as static. It's the same idea as your patch, but pushed up a level so that one function's call to ssd_kvm_get_procs doesn't free the memory used in another function. Jeff
diff -Nru dpkg-1.17.23/debian/changelog dpkg-1.17.23+local3/debian/changelog --- dpkg-1.17.23/debian/changelog 2014-12-27 16:44:47.000000000 -0600 +++ dpkg-1.17.23+local3/debian/changelog 2015-03-01 19:43:18.000000000 -0600 @@ -1,3 +1,10 @@ +dpkg (1.17.23+local3) UNRELEASED; urgency=medium + + * Non-maintainer upload. + * Avoid resource exhaustion by having one kvm_t per function using it. + + -- Jeff Epler <jep...@unpythonic.net> Sun, 01 Mar 2015 19:42:38 -0600 + dpkg (1.17.23) unstable; urgency=low [ Guillem Jover ] diff -Nru dpkg-1.17.23/utils/start-stop-daemon.c dpkg-1.17.23+local3/utils/start-stop-daemon.c --- dpkg-1.17.23/utils/start-stop-daemon.c 2014-12-13 16:07:23.000000000 -0600 +++ dpkg-1.17.23+local3/utils/start-stop-daemon.c 2015-03-01 19:42:19.000000000 -0600 @@ -1367,7 +1367,7 @@ static bool pid_is_exec(pid_t pid, const struct stat *esb) { - kvm_t *kd; + static kvm_t *kd; int argv_len = 0; struct kinfo_proc *kp; struct stat sb; @@ -1375,7 +1375,7 @@ char **pid_argv_p; char *start_argv_0_p, *end_argv_0_p; - kd = ssd_kvm_open(); + if (!kd) kd = ssd_kvm_open(); kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL); if (kp == NULL) return false; @@ -1457,11 +1457,11 @@ static bool pid_is_child(pid_t pid, pid_t ppid) { - kvm_t *kd; + static kvm_t *kd; struct kinfo_proc *kp; pid_t proc_ppid; - kd = ssd_kvm_open(); + if (!kd) kd = ssd_kvm_open(); kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL); if (kp == NULL) return false; @@ -1515,11 +1515,11 @@ static bool pid_is_user(pid_t pid, uid_t uid) { - kvm_t *kd; + static kvm_t *kd; uid_t proc_uid; struct kinfo_proc *kp; - kd = ssd_kvm_open(); + if (!kd) kd = ssd_kvm_open(); kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL); if (kp == NULL) return false; @@ -1599,11 +1599,11 @@ static bool pid_is_cmd(pid_t pid, const char *name) { - kvm_t *kd; + static kvm_t *kd; struct kinfo_proc *kp; char *process_name; - kd = ssd_kvm_open(); + if (!kd) kd = ssd_kvm_open(); kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL); if (kp == NULL) return false; @@ -1768,12 +1768,12 @@ static enum status_code do_procinit(void) { - kvm_t *kd; + static kvm_t *kd; int nentries, i; struct kinfo_proc *kp; enum status_code prog_status = STATUS_DEAD; - kd = ssd_kvm_open(); + if (!kd) kd = ssd_kvm_open(); kp = ssd_kvm_get_procs(kd, KERN_PROC_ALL, 0, &nentries); for (i = 0; i < nentries; i++) {