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 liblzma5 5.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.000000000 -0600 +++ dpkg-1.17.23+nmu1/debian/changelog 2015-02-28 17:56:33.000000000 -0600 @@ -1,3 +1,10 @@ +dpkg (1.17.23+nmu1) UNRELEASED; urgency=medium + + * Non-maintainer upload. + * Fix kvm_open file descriptor leak + + -- <jep...@communitycrops.org> 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.000000000 -0600 +++ dpkg-1.17.23+nmu1/utils/start-stop-daemon.c 2015-02-28 18:05:26.000000000 -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