xref: /openbsd-src/lib/libkvm/kvm_proc.c (revision ac9b4aacc1da35008afea06a5d23c2f2dea9b93e)
1 /*	$OpenBSD: kvm_proc.c,v 1.47 2012/04/14 12:11:47 guenther Exp $	*/
2 /*	$NetBSD: kvm_proc.c,v 1.30 1999/03/24 05:50:50 mrg Exp $	*/
3 /*-
4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Charles M. Hannum.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 /*-
32  * Copyright (c) 1994, 1995 Charles M. Hannum.  All rights reserved.
33  * Copyright (c) 1989, 1992, 1993
34  *	The Regents of the University of California.  All rights reserved.
35  *
36  * This code is derived from software developed by the Computer Systems
37  * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
38  * BG 91-66 and contributed to Berkeley.
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  * 1. Redistributions of source code must retain the above copyright
44  *    notice, this list of conditions and the following disclaimer.
45  * 2. Redistributions in binary form must reproduce the above copyright
46  *    notice, this list of conditions and the following disclaimer in the
47  *    documentation and/or other materials provided with the distribution.
48  * 3. Neither the name of the University nor the names of its contributors
49  *    may be used to endorse or promote products derived from this software
50  *    without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62  * SUCH DAMAGE.
63  */
64 
65 /*
66  * Proc traversal interface for kvm.  ps and w are (probably) the exclusive
67  * users of this code, so we've factored it out into a separate module.
68  * Thus, we keep this grunge out of the other kvm applications (i.e.,
69  * most other applications are interested only in open/close/read/nlist).
70  */
71 
72 #include <sys/param.h>
73 #include <sys/user.h>
74 #include <sys/proc.h>
75 #include <sys/exec.h>
76 #include <sys/stat.h>
77 #include <sys/ioctl.h>
78 #include <sys/tty.h>
79 #include <stdlib.h>
80 #include <string.h>
81 #include <unistd.h>
82 #include <nlist.h>
83 #include <kvm.h>
84 
85 #include <uvm/uvm_extern.h>
86 #include <uvm/uvm_amap.h>
87 #include <machine/vmparam.h>
88 #include <machine/pmap.h>
89 
90 #include <sys/sysctl.h>
91 
92 #include <limits.h>
93 #include <db.h>
94 #include <paths.h>
95 
96 #include "kvm_private.h"
97 
98 /*
99  * Common info from kinfo_proc used by helper routines.
100  */
101 struct miniproc {
102 	struct	vmspace *p_vmspace;
103 	char	p_stat;
104 	struct	proc *p_paddr;
105 	pid_t	p_pid;
106 };
107 
108 /*
109  * Convert from struct kinfo_proc to miniproc.
110  */
111 #define KPTOMINI(kp, p) \
112 	do { \
113 		(p)->p_stat = (kp)->p_stat; \
114 		(p)->p_pid = (kp)->p_pid; \
115 		(p)->p_paddr = (void *)(long)(kp)->p_paddr; \
116 		(p)->p_vmspace = (void *)(long)(kp)->p_vmspace; \
117 	} while (/*CONSTCOND*/0);
118 
119 
120 static char	*_kvm_ureadm(kvm_t *, const struct miniproc *, u_long, u_long *);
121 static ssize_t	kvm_ureadm(kvm_t *, const struct miniproc *, u_long, char *, size_t);
122 
123 static char	**kvm_argv(kvm_t *, const struct miniproc *, u_long, int, int);
124 
125 static char	**kvm_doargv(kvm_t *, const struct miniproc *, int,
126 		    void (*)(struct ps_strings *, u_long *, int *));
127 static int	proc_verify(kvm_t *, const struct miniproc *);
128 static void	ps_str_a(struct ps_strings *, u_long *, int *);
129 static void	ps_str_e(struct ps_strings *, u_long *, int *);
130 
131 static char *
132 _kvm_ureadm(kvm_t *kd, const struct miniproc *p, u_long va, u_long *cnt)
133 {
134 	u_long addr, offset, slot;
135 	struct vmspace vm;
136 	struct vm_anon *anonp, anon;
137 	struct vm_map_entry vme;
138 	struct vm_amap amap;
139 	struct vm_page pg;
140 
141 	if (kd->swapspc == 0) {
142 		kd->swapspc = _kvm_malloc(kd, kd->nbpg);
143 		if (kd->swapspc == 0)
144 			return (NULL);
145 	}
146 
147 	/*
148 	 * Look through the address map for the memory object
149 	 * that corresponds to the given virtual address.
150 	 */
151 	if (KREAD(kd, (u_long)p->p_vmspace, &vm))
152 		return (NULL);
153 	addr = (u_long)RB_ROOT(&vm.vm_map.addr);
154 	while (1) {
155 		if (addr == 0)
156 			return (NULL);
157 		if (KREAD(kd, addr, &vme))
158 			return (NULL);
159 
160 		if (va < vme.start)
161 			addr = (u_long)RB_LEFT(&vme, daddrs.addr_entry);
162 		else if (va >= vme.end + vme.guard + vme.fspace)
163 			addr = (u_long)RB_RIGHT(&vme, daddrs.addr_entry);
164 		else if (va >= vme.end)
165 			return (NULL);
166 		else
167 			break;
168 	}
169 
170 	/*
171 	 * we found the map entry, now to find the object...
172 	 */
173 	if (vme.aref.ar_amap == NULL)
174 		return (NULL);
175 
176 	addr = (u_long)vme.aref.ar_amap;
177 	if (KREAD(kd, addr, &amap))
178 		return (NULL);
179 
180 	offset = va - vme.start;
181 	slot = offset / kd->nbpg + vme.aref.ar_pageoff;
182 	/* sanity-check slot number */
183 	if (slot > amap.am_nslot)
184 		return (NULL);
185 
186 	addr = (u_long)amap.am_anon + (offset / kd->nbpg) * sizeof(anonp);
187 	if (KREAD(kd, addr, &anonp))
188 		return (NULL);
189 
190 	addr = (u_long)anonp;
191 	if (KREAD(kd, addr, &anon))
192 		return (NULL);
193 
194 	addr = (u_long)anon.an_page;
195 	if (addr) {
196 		if (KREAD(kd, addr, &pg))
197 			return (NULL);
198 
199 		if (_kvm_pread(kd, kd->pmfd, (void *)kd->swapspc,
200 		    (size_t)kd->nbpg, (off_t)pg.phys_addr) != kd->nbpg)
201 			return (NULL);
202 	} else {
203 		if (kd->swfd == -1 ||
204 		    _kvm_pread(kd, kd->swfd, (void *)kd->swapspc,
205 		    (size_t)kd->nbpg,
206 		    (off_t)(anon.an_swslot * kd->nbpg)) != kd->nbpg)
207 			return (NULL);
208 	}
209 
210 	/* Found the page. */
211 	offset %= kd->nbpg;
212 	*cnt = kd->nbpg - offset;
213 	return (&kd->swapspc[offset]);
214 }
215 
216 void *
217 _kvm_realloc(kvm_t *kd, void *p, size_t n)
218 {
219 	void *np = (void *)realloc(p, n);
220 
221 	if (np == 0)
222 		_kvm_err(kd, kd->program, "out of memory");
223 	return (np);
224 }
225 
226 /*
227  * Read in an argument vector from the user address space of process p.
228  * addr if the user-space base address of narg null-terminated contiguous
229  * strings.  This is used to read in both the command arguments and
230  * environment strings.  Read at most maxcnt characters of strings.
231  */
232 static char **
233 kvm_argv(kvm_t *kd, const struct miniproc *p, u_long addr, int narg,
234     int maxcnt)
235 {
236 	char *np, *cp, *ep, *ap, **argv;
237 	u_long oaddr = -1;
238 	int len, cc;
239 
240 	/*
241 	 * Check that there aren't an unreasonable number of arguments,
242 	 * and that the address is in user space.
243 	 */
244 	if (narg > ARG_MAX || addr < VM_MIN_ADDRESS || addr >= VM_MAXUSER_ADDRESS)
245 		return (0);
246 
247 	if (kd->argv == 0) {
248 		/*
249 		 * Try to avoid reallocs.
250 		 */
251 		kd->argc = MAX(narg + 1, 32);
252 		kd->argv = _kvm_malloc(kd, kd->argc *
253 		    sizeof(*kd->argv));
254 		if (kd->argv == 0)
255 			return (0);
256 	} else if (narg + 1 > kd->argc) {
257 		kd->argc = MAX(2 * kd->argc, narg + 1);
258 		kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc *
259 		    sizeof(*kd->argv));
260 		if (kd->argv == 0)
261 			return (0);
262 	}
263 	if (kd->argspc == 0) {
264 		kd->argspc = _kvm_malloc(kd, kd->nbpg);
265 		if (kd->argspc == 0)
266 			return (0);
267 		kd->arglen = kd->nbpg;
268 	}
269 	if (kd->argbuf == 0) {
270 		kd->argbuf = _kvm_malloc(kd, kd->nbpg);
271 		if (kd->argbuf == 0)
272 			return (0);
273 	}
274 	cc = sizeof(char *) * narg;
275 	if (kvm_ureadm(kd, p, addr, (char *)kd->argv, cc) != cc)
276 		return (0);
277 	ap = np = kd->argspc;
278 	argv = kd->argv;
279 	len = 0;
280 
281 	/*
282 	 * Loop over pages, filling in the argument vector.
283 	 */
284 	while (argv < kd->argv + narg && *argv != 0) {
285 		addr = (u_long)*argv & ~(kd->nbpg - 1);
286 		if (addr != oaddr) {
287 			if (kvm_ureadm(kd, p, addr, kd->argbuf, kd->nbpg) !=
288 			    kd->nbpg)
289 				return (0);
290 			oaddr = addr;
291 		}
292 		addr = (u_long)*argv & (kd->nbpg - 1);
293 		cp = kd->argbuf + addr;
294 		cc = kd->nbpg - addr;
295 		if (maxcnt > 0 && cc > maxcnt - len)
296 			cc = maxcnt - len;
297 		ep = memchr(cp, '\0', cc);
298 		if (ep != 0)
299 			cc = ep - cp + 1;
300 		if (len + cc > kd->arglen) {
301 			int off;
302 			char **pp;
303 			char *op = kd->argspc;
304 
305 			kd->arglen *= 2;
306 			kd->argspc = (char *)_kvm_realloc(kd, kd->argspc,
307 			    kd->arglen);
308 			if (kd->argspc == 0)
309 				return (0);
310 			/*
311 			 * Adjust argv pointers in case realloc moved
312 			 * the string space.
313 			 */
314 			off = kd->argspc - op;
315 			for (pp = kd->argv; pp < argv; pp++)
316 				*pp += off;
317 			ap += off;
318 			np += off;
319 		}
320 		memcpy(np, cp, cc);
321 		np += cc;
322 		len += cc;
323 		if (ep != 0) {
324 			*argv++ = ap;
325 			ap = np;
326 		} else
327 			*argv += cc;
328 		if (maxcnt > 0 && len >= maxcnt) {
329 			/*
330 			 * We're stopping prematurely.  Terminate the
331 			 * current string.
332 			 */
333 			if (ep == 0) {
334 				*np = '\0';
335 				*argv++ = ap;
336 			}
337 			break;
338 		}
339 	}
340 	/* Make sure argv is terminated. */
341 	*argv = 0;
342 	return (kd->argv);
343 }
344 
345 static void
346 ps_str_a(struct ps_strings *p, u_long *addr, int *n)
347 {
348 	*addr = (u_long)p->ps_argvstr;
349 	*n = p->ps_nargvstr;
350 }
351 
352 static void
353 ps_str_e(struct ps_strings *p, u_long *addr, int *n)
354 {
355 	*addr = (u_long)p->ps_envstr;
356 	*n = p->ps_nenvstr;
357 }
358 
359 /*
360  * Determine if the proc indicated by p is still active.
361  * This test is not 100% foolproof in theory, but chances of
362  * being wrong are very low.
363  */
364 static int
365 proc_verify(kvm_t *kd, const struct miniproc *p)
366 {
367 	struct proc kernproc;
368 
369 	/*
370 	 * Just read in the whole proc.  It's not that big relative
371 	 * to the cost of the read system call.
372 	 */
373 	if (kvm_read(kd, (u_long)p->p_paddr, &kernproc, sizeof(kernproc)) !=
374 	    sizeof(kernproc))
375 		return (0);
376 	return (p->p_pid == kernproc.p_pid &&
377 	    (kernproc.p_stat != SZOMB || p->p_stat == SZOMB));
378 }
379 
380 static char **
381 kvm_doargv(kvm_t *kd, const struct miniproc *p, int nchr,
382     void (*info)(struct ps_strings *, u_long *, int *))
383 {
384 	static struct ps_strings *ps;
385 	struct ps_strings arginfo;
386 	u_long addr;
387 	char **ap;
388 	int cnt;
389 
390 	if (ps == NULL) {
391 		struct _ps_strings _ps;
392 		int mib[2];
393 		size_t len;
394 
395 		mib[0] = CTL_VM;
396 		mib[1] = VM_PSSTRINGS;
397 		len = sizeof(_ps);
398 		sysctl(mib, 2, &_ps, &len, NULL, 0);
399 		ps = (struct ps_strings *)_ps.val;
400 	}
401 
402 	/*
403 	 * Pointers are stored at the top of the user stack.
404 	 */
405 	if (p->p_stat == SZOMB ||
406 	    kvm_ureadm(kd, p, (u_long)ps, (char *)&arginfo,
407 	    sizeof(arginfo)) != sizeof(arginfo))
408 		return (0);
409 
410 	(*info)(&arginfo, &addr, &cnt);
411 	if (cnt == 0)
412 		return (0);
413 	ap = kvm_argv(kd, p, addr, cnt, nchr);
414 	/*
415 	 * For live kernels, make sure this process didn't go away.
416 	 */
417 	if (ap != 0 && ISALIVE(kd) && !proc_verify(kd, p))
418 		ap = 0;
419 	return (ap);
420 }
421 
422 static char **
423 kvm_arg_sysctl(kvm_t *kd, pid_t pid, int nchr, int env)
424 {
425 	size_t len, orglen;
426 	int mib[4], ret;
427 	char *buf;
428 
429 	orglen = env ? kd->nbpg : 8 * kd->nbpg;	/* XXX - should be ARG_MAX */
430 	if (kd->argbuf == NULL &&
431 	    (kd->argbuf = _kvm_malloc(kd, orglen)) == NULL)
432 		return (NULL);
433 
434 again:
435 	mib[0] = CTL_KERN;
436 	mib[1] = KERN_PROC_ARGS;
437 	mib[2] = (int)pid;
438 	mib[3] = env ? KERN_PROC_ENV : KERN_PROC_ARGV;
439 
440 	len = orglen;
441 	ret = (sysctl(mib, 4, kd->argbuf, &len, NULL, 0) < 0);
442 	if (ret && errno == ENOMEM) {
443 		orglen *= 2;
444 		buf = _kvm_realloc(kd, kd->argbuf, orglen);
445 		if (buf == NULL)
446 			return (NULL);
447 		kd->argbuf = buf;
448 		goto again;
449 	}
450 
451 	if (ret) {
452 		free(kd->argbuf);
453 		kd->argbuf = NULL;
454 		_kvm_syserr(kd, kd->program, "kvm_arg_sysctl");
455 		return (NULL);
456 	}
457 #if 0
458 	for (argv = (char **)kd->argbuf; *argv != NULL; argv++)
459 		if (strlen(*argv) > nchr)
460 			*argv[nchr] = '\0';
461 #endif
462 
463 	return (char **)(kd->argbuf);
464 }
465 
466 /*
467  * Get the command args.  This code is now machine independent.
468  */
469 char **
470 kvm_getargv(kvm_t *kd, const struct kinfo_proc *kp, int nchr)
471 {
472 	struct miniproc p;
473 
474 	if (ISALIVE(kd))
475 		return (kvm_arg_sysctl(kd, kp->p_pid, nchr, 0));
476 	KPTOMINI(kp, &p);
477 	return (kvm_doargv(kd, &p, nchr, ps_str_a));
478 }
479 
480 char **
481 kvm_getenvv(kvm_t *kd, const struct kinfo_proc *kp, int nchr)
482 {
483 	struct miniproc p;
484 
485 	if (ISALIVE(kd))
486 		return (kvm_arg_sysctl(kd, kp->p_pid, nchr, 1));
487 	KPTOMINI(kp, &p);
488 	return (kvm_doargv(kd, &p, nchr, ps_str_e));
489 }
490 
491 /*
492  * Read from user space.  The user context is given by p.
493  */
494 static ssize_t
495 kvm_ureadm(kvm_t *kd, const struct miniproc *p, u_long uva, char *buf,
496     size_t len)
497 {
498 	char *cp = buf;
499 
500 	while (len > 0) {
501 		u_long cnt;
502 		size_t cc;
503 		char *dp;
504 
505 		dp = _kvm_ureadm(kd, p, uva, &cnt);
506 		if (dp == 0) {
507 			_kvm_err(kd, 0, "invalid address (%lx)", uva);
508 			return (0);
509 		}
510 		cc = (size_t)MIN(cnt, len);
511 		bcopy(dp, cp, cc);
512 		cp += cc;
513 		uva += cc;
514 		len -= cc;
515 	}
516 	return (ssize_t)(cp - buf);
517 }
518