Selaa lähdekoodia

s-s-d: Do not leak kvm descriptors

Cherry picked from commit eaa073bc37901a6d8c46abc9fa5e7ec5551df04b.

We should close the kvm instances after every operation, so not to leak
them, as they might exhaust the file descriptor pool, or leak into the
started process.

Closes: #779467
Based-on-patch-by: Jeff Epler <jepler@unpythonic.net>
Guillem Jover 11 vuotta sitten
vanhempi
commit
c8c665f47a
2 muutettua tiedostoa jossa 36 lisäystä ja 10 poistoa
  1. 2 0
      debian/changelog
  2. 34 10
      utils/start-stop-daemon.c

+ 2 - 0
debian/changelog

@@ -56,6 +56,8 @@ dpkg (1.18.0) UNRELEASED; urgency=low
     We should not create a new template symbols file, because the output
     We should not create a new template symbols file, because the output
     might change (different sorting order for example) relative to the
     might change (different sorting order for example) relative to the
     original. Closes: #773718
     original. Closes: #773718
+  * Do not leak kvm descriptors in start-stop-daemon on GNU/kFreeBSD systems.
+    Based on a patch by Jeff Epler <jepler@unpythonic.net>. Closes: #779467
 
 
   * Perl modules:
   * Perl modules:
     - Rename and deprecate Dpkg::Gettext _g function with new g_.
     - Rename and deprecate Dpkg::Gettext _g function with new g_.

+ 34 - 10
utils/start-stop-daemon.c

@@ -1374,11 +1374,12 @@ pid_is_exec(pid_t pid, const struct stat *esb)
 	char buf[_POSIX2_LINE_MAX];
 	char buf[_POSIX2_LINE_MAX];
 	char **pid_argv_p;
 	char **pid_argv_p;
 	char *start_argv_0_p, *end_argv_0_p;
 	char *start_argv_0_p, *end_argv_0_p;
+	bool res = false;
 
 
 	kd = ssd_kvm_open();
 	kd = ssd_kvm_open();
 	kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL);
 	kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL);
 	if (kp == NULL)
 	if (kp == NULL)
-		return false;
+		goto cleanup;
 
 
 	pid_argv_p = kvm_getargv(kd, kp, argv_len);
 	pid_argv_p = kvm_getargv(kd, kp, argv_len);
 	if (pid_argv_p == NULL)
 	if (pid_argv_p == NULL)
@@ -1403,9 +1404,14 @@ pid_is_exec(pid_t pid, const struct stat *esb)
 	}
 	}
 
 
 	if (stat(start_argv_0_p, &sb) != 0)
 	if (stat(start_argv_0_p, &sb) != 0)
-		return false;
+		goto cleanup;
 
 
-	return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino);
+	res = (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino);
+
+cleanup:
+	kvm_close(kd);
+
+	return res;
 }
 }
 #endif
 #endif
 
 
@@ -1460,11 +1466,12 @@ pid_is_child(pid_t pid, pid_t ppid)
 	kvm_t *kd;
 	kvm_t *kd;
 	struct kinfo_proc *kp;
 	struct kinfo_proc *kp;
 	pid_t proc_ppid;
 	pid_t proc_ppid;
+	bool res = false;
 
 
 	kd = ssd_kvm_open();
 	kd = ssd_kvm_open();
 	kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL);
 	kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL);
 	if (kp == NULL)
 	if (kp == NULL)
-		return false;
+		goto cleanup;
 
 
 #if defined(OSFreeBSD)
 #if defined(OSFreeBSD)
 	proc_ppid = kp->ki_ppid;
 	proc_ppid = kp->ki_ppid;
@@ -1476,7 +1483,12 @@ pid_is_child(pid_t pid, pid_t ppid)
 	proc_ppid = kp->kp_proc.p_ppid;
 	proc_ppid = kp->kp_proc.p_ppid;
 #endif
 #endif
 
 
-	return proc_ppid == ppid;
+	res = (proc_ppid == ppid);
+
+cleanup:
+	kvm_close(kd);
+
+	return res;
 }
 }
 #endif
 #endif
 
 
@@ -1518,11 +1530,12 @@ pid_is_user(pid_t pid, uid_t uid)
 	kvm_t *kd;
 	kvm_t *kd;
 	uid_t proc_uid;
 	uid_t proc_uid;
 	struct kinfo_proc *kp;
 	struct kinfo_proc *kp;
+	bool res = false;
 
 
 	kd = ssd_kvm_open();
 	kd = ssd_kvm_open();
 	kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL);
 	kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL);
 	if (kp == NULL)
 	if (kp == NULL)
-		return false;
+		goto cleanup;
 
 
 #if defined(OSFreeBSD)
 #if defined(OSFreeBSD)
 	proc_uid = kp->ki_ruid;
 	proc_uid = kp->ki_ruid;
@@ -1535,10 +1548,15 @@ pid_is_user(pid_t pid, uid_t uid)
 		kvm_read(kd, (u_long)&(kp->kp_proc.p_cred->p_ruid),
 		kvm_read(kd, (u_long)&(kp->kp_proc.p_cred->p_ruid),
 		         &proc_uid, sizeof(uid_t));
 		         &proc_uid, sizeof(uid_t));
 	else
 	else
-		return false;
+		goto cleanup;
 #endif
 #endif
 
 
-	return (proc_uid == (uid_t)uid);
+	res = (proc_uid == (uid_t)uid);
+
+cleanup:
+	kvm_close(kd);
+
+	return res;
 }
 }
 #endif
 #endif
 
 
@@ -1602,11 +1620,12 @@ pid_is_cmd(pid_t pid, const char *name)
 	kvm_t *kd;
 	kvm_t *kd;
 	struct kinfo_proc *kp;
 	struct kinfo_proc *kp;
 	char *process_name;
 	char *process_name;
+	bool res = false;
 
 
 	kd = ssd_kvm_open();
 	kd = ssd_kvm_open();
 	kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL);
 	kp = ssd_kvm_get_procs(kd, KERN_PROC_PID, pid, NULL);
 	if (kp == NULL)
 	if (kp == NULL)
-		return false;
+		goto cleanup;
 
 
 #if defined(OSFreeBSD)
 #if defined(OSFreeBSD)
 	process_name = kp->ki_comm;
 	process_name = kp->ki_comm;
@@ -1618,7 +1637,12 @@ pid_is_cmd(pid_t pid, const char *name)
 	process_name = kp->kp_proc.p_comm;
 	process_name = kp->kp_proc.p_comm;
 #endif
 #endif
 
 
-	return (strcmp(name, process_name) == 0);
+	res = (strcmp(name, process_name) == 0);
+
+cleanup:
+	kvm_close(kd);
+
+	return res;
 }
 }
 #endif
 #endif