Re: Bug#779467: dpkg: start-stop-daemon sometimes exits with "_cpu_tick_frequency: no such symbol" on kFreeBSD
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 <jepler@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++) {
Reply to: