Package: dpkg
Version: 1.17.23+local1
Severity: important
Tags: patch
On a Debian Jessie kFreeBSD system, start-stop-daemon sometimes exits with
an odd error:
$ sudo service nfsd restart
start-stop-daemon: _cpu_tick_frequency: no such symbol
The specific command invocation which was reliably printing the error
for me was:
# start-stop-daemon --stop --quiet --retry=USR1/30/KILL/5 --name nfsd
start-stop-daemon: _cpu_tick_frequency: no such symbol
This turns out to be due to file descriptor exhaustion due to calls to
kvm_openfiles without balancing calls to kvm_close, which is fixed by the
attached patch.
-- System Information:
Debian Release: 8.0
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'testing'), (500, 'stable')
Architecture: kfreebsd-amd64 (x86_64)
Kernel: kFreeBSD 10.1-0-amd64
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: sysvinit (via /sbin/init)
Versions of packages dpkg depends on:
ii libbz2-1.0 1.0.6-7+b2
ii libc0.1 2.19-15
ii libkvm6 10.1~svn273304-1
ii liblzma55.1.1alpha+20120614-2+b3
ii tar 1.27.1-2+b1
ii zlib1g 1:1.2.8.dfsg-2+b1
dpkg recommends no packages.
Versions of packages dpkg suggests:
ii apt 1.0.9.6
-- no debconf information
diff -Nru dpkg-1.17.23/debian/changelog dpkg-1.17.23+nmu1/debian/changelog
--- dpkg-1.17.23/debian/changelog 2014-12-27 16:44:47.0 -0600
+++ dpkg-1.17.23+nmu1/debian/changelog 2015-02-28 17:56:33.0 -0600
@@ -1,3 +1,10 @@
+dpkg (1.17.23+nmu1) UNRELEASED; urgency=medium
+
+ * Non-maintainer upload.
+ * Fix kvm_open file descriptor leak
+
+ --Sat, 28 Feb 2015 17:56:19 -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+nmu1/utils/start-stop-daemon.c
--- dpkg-1.17.23/utils/start-stop-daemon.c 2014-12-13 16:07:23.0 -0600
+++ dpkg-1.17.23+nmu1/utils/start-stop-daemon.c 2015-02-28 18:05:26.0 -0600
@@ -1374,11 +1374,13 @@
char buf[_POSIX2_LINE_MAX];
char **pid_argv_p;
char *start_argv_0_p, *end_argv_0_p;
+ bool result = false;
kd = ssd_kvm_open();
+ if(kd < 0) return false;
+
kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL);
- if (kp == NULL)
- return false;
+ if (kp == NULL) goto exit;
pid_argv_p = kvm_getargv(kd, kp, argv_len);
if (pid_argv_p == NULL)
@@ -1403,9 +1405,12 @@
}
if (stat(start_argv_0_p, &sb) != 0)
- return false;
+ goto exit;
- return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino);
+ result = (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino);
+exit:
+ kvm_close(kd);
+ return result;
}
#endif
@@ -1460,11 +1465,12 @@
kvm_t *kd;
struct kinfo_proc *kp;
pid_t proc_ppid;
+ int result = false;
kd = ssd_kvm_open();
kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL);
if (kp == NULL)
- return false;
+ goto exit;
#if defined(OSFreeBSD)
proc_ppid = kp->ki_ppid;
@@ -1476,7 +1482,10 @@
proc_ppid = kp->kp_proc.p_ppid;
#endif
- return proc_ppid == ppid;
+ result = proc_ppid == ppid;
+exit:
+ kvm_close(kd);
+ return result;
}
#endif
@@ -1518,11 +1527,12 @@
kvm_t *kd;
uid_t proc_uid;
struct kinfo_proc *kp;
+ bool result = false;
kd = ssd_kvm_open();
kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL);
if (kp == NULL)
- return false;
+ goto exit;
#if defined(OSFreeBSD)
proc_uid = kp->ki_ruid;
@@ -1535,10 +1544,13 @@
kvm_read(kd, (u_long)&(kp->kp_proc.p_cred->p_ruid),
&proc_uid, sizeof(uid_t));
else
- return false;
+ goto exit;
#endif
- return (proc_uid == (uid_t)uid);
+ result = (proc_uid == (uid_t)uid);
+exit:
+ kvm_close(kd);
+ return result;
}
#endif
@@ -1602,11 +1614,12 @@
kvm_t *kd;
struct kinfo_proc *kp;
char *process_name;
+ bool result = false;
kd = ssd_kvm_open();
kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL);
if (kp == NULL)
- return false;
+ goto exit;
#if defined(OSFreeBSD)
process_name = kp->ki_comm;
@@ -1618,7 +1631,10 @@
process_name = kp->kp_proc.p_comm;
#endif
- return (strcmp(name, process_name) == 0);
+ result = (strcmp(name, process_name) == 0);
+exit:
+ kvm_close(kd);
+ return result;
}
#endif