From 7350dd84a0c2e03ec519968b219eb4f4e5f81536 Mon Sep 17 00:00:00 2001
From: Peter Wemm <peter@FreeBSD.org>
Date: Sat, 24 Feb 1996 14:37:30 +0000
Subject: [PATCH] If the two recently added sysctl variables exist, use those
 rather than the statically compiled PS_STRINGS and USRSTACK variables.  This
 prevents programs using setproctitle from coredumping if the kernel VM is
 increased, and stops libkvm users (w, ps, etc) from needing to be recompiled
 if only the VM layout changes.

---
 lib/libc/gen/setproctitle.c | 27 +++++++++++++++++----------
 lib/libkvm/kvm_proc.c       | 19 +++++++++++++++++--
 lib/libutil/setproctitle.c  | 27 +++++++++++++++++----------
 3 files changed, 51 insertions(+), 22 deletions(-)

diff --git a/lib/libc/gen/setproctitle.c b/lib/libc/gen/setproctitle.c
index 2faf976b3c34..08efa993a68b 100644
--- a/lib/libc/gen/setproctitle.c
+++ b/lib/libc/gen/setproctitle.c
@@ -11,19 +11,16 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. This work was done expressly for inclusion into FreeBSD.  Other use
- *    is permitted provided this notation is included.
- * 4. Absolutely no warranty of function or purpose is made by the author
+ * 3. Absolutely no warranty of function or purpose is made by the author
  *    Peter Wemm.
- * 5. Modifications may be freely made to this file providing the above
- *    conditions are met.
  *
- * $Id$
+ * $Id: setproctitle.c,v 1.1 1995/12/26 22:50:08 peter Exp $
  */
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/exec.h>
+#include <sys/sysctl.h>
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -71,10 +68,12 @@ setproctitle(fmt, va_alist)
 #endif
 {
 	char *p;
-	int len;
 	static char buf[SPT_BUFSIZE];
 	static char *ps_argv[2];
 	va_list ap;
+	int mib[2];
+	struct ps_strings *ps_strings;
+	size_t len;
 
 #if defined(__STDC__)
 	va_start(ap, fmt);
@@ -104,13 +103,21 @@ setproctitle(fmt, va_alist)
 
 	va_end(ap);
 
+	ps_strings = NULL;
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_PS_STRINGS;
+	len = sizeof(ps_strings);
+	if (sysctl(mib, 2, &ps_strings, &len, NULL, 0) < 0 ||
+	    ps_strings == NULL)
+		ps_strings = PS_STRINGS;
+
 	/* PS_STRINGS points to zeroed memory on a style #2 kernel */
-	if (PS_STRINGS->ps_argvstr) {
+	if (ps_strings->ps_argvstr) {
 		/* style #3 */
 		ps_argv[0] = buf;
 		ps_argv[1] = NULL;
-		PS_STRINGS->ps_nargvstr = 1;
-		PS_STRINGS->ps_argvstr = ps_argv;
+		ps_strings->ps_nargvstr = 1;
+		ps_strings->ps_argvstr = ps_argv;
 	} else {
 		/* style #2 */
 		OLD_PS_STRINGS->old_ps_nargvstr = 1;
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
index c26e680b79a0..47773e7b4f6b 100644
--- a/lib/libkvm/kvm_proc.c
+++ b/lib/libkvm/kvm_proc.c
@@ -599,13 +599,23 @@ kvm_doargv(kd, kp, nchr, info)
 	register char **ap;
 	u_long addr;
 	int cnt;
-	struct ps_strings arginfo;
+	struct ps_strings arginfo, *ps_strings;
+	int mib[2];
+	size_t len;
+
+	ps_strings = NULL;
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_PS_STRINGS;
+	len = sizeof(ps_strings);
+	if (sysctl(mib, 2, &ps_strings, &len, NULL, 0) < 0 ||
+	    ps_strings == NULL)
+		ps_strings = PS_STRINGS;
 
 	/*
 	 * Pointers are stored at the top of the user stack.
 	 */
 	if (p->p_stat == SZOMB ||
-	    kvm_uread(kd, p, USRSTACK - sizeof(arginfo), (char *)&arginfo,
+	    kvm_uread(kd, p, ps_strings, (char *)&arginfo,
 		      sizeof(arginfo)) != sizeof(arginfo))
 		return (0);
 
@@ -659,6 +669,11 @@ kvm_uread(kd, p, uva, buf, len)
 	ssize_t amount;
 	int fd;
 
+	if (!ISALIVE(kd)) {
+		_kvm_err(kd, kd->program, "cannot read user space from dead kernel");
+		return(0);
+	}
+
 	cp = buf;
 
 	sprintf(procfile, "/proc/%d/mem", p->p_pid);
diff --git a/lib/libutil/setproctitle.c b/lib/libutil/setproctitle.c
index 2faf976b3c34..08efa993a68b 100644
--- a/lib/libutil/setproctitle.c
+++ b/lib/libutil/setproctitle.c
@@ -11,19 +11,16 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. This work was done expressly for inclusion into FreeBSD.  Other use
- *    is permitted provided this notation is included.
- * 4. Absolutely no warranty of function or purpose is made by the author
+ * 3. Absolutely no warranty of function or purpose is made by the author
  *    Peter Wemm.
- * 5. Modifications may be freely made to this file providing the above
- *    conditions are met.
  *
- * $Id$
+ * $Id: setproctitle.c,v 1.1 1995/12/26 22:50:08 peter Exp $
  */
 
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/exec.h>
+#include <sys/sysctl.h>
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -71,10 +68,12 @@ setproctitle(fmt, va_alist)
 #endif
 {
 	char *p;
-	int len;
 	static char buf[SPT_BUFSIZE];
 	static char *ps_argv[2];
 	va_list ap;
+	int mib[2];
+	struct ps_strings *ps_strings;
+	size_t len;
 
 #if defined(__STDC__)
 	va_start(ap, fmt);
@@ -104,13 +103,21 @@ setproctitle(fmt, va_alist)
 
 	va_end(ap);
 
+	ps_strings = NULL;
+	mib[0] = CTL_KERN;
+	mib[1] = KERN_PS_STRINGS;
+	len = sizeof(ps_strings);
+	if (sysctl(mib, 2, &ps_strings, &len, NULL, 0) < 0 ||
+	    ps_strings == NULL)
+		ps_strings = PS_STRINGS;
+
 	/* PS_STRINGS points to zeroed memory on a style #2 kernel */
-	if (PS_STRINGS->ps_argvstr) {
+	if (ps_strings->ps_argvstr) {
 		/* style #3 */
 		ps_argv[0] = buf;
 		ps_argv[1] = NULL;
-		PS_STRINGS->ps_nargvstr = 1;
-		PS_STRINGS->ps_argvstr = ps_argv;
+		ps_strings->ps_nargvstr = 1;
+		ps_strings->ps_argvstr = ps_argv;
 	} else {
 		/* style #2 */
 		OLD_PS_STRINGS->old_ps_nargvstr = 1;