diff options
author | tedu <tedu@openbsd.org> | 2013-03-23 10:46:04 +0000 |
---|---|---|
committer | tedu <tedu@openbsd.org> | 2013-03-23 10:46:04 +0000 |
commit | c38420897fe46b95accfcf17e0fa3c24bb3dc2c4 (patch) | |
tree | 9c5725c66c8a98eb048b798197720b640a9cb4a4 /usr.sbin/procmap | |
parent | Fix a bug in ld --gc-sections: it strips out .note sections, while (diff) | |
download | wireguard-openbsd-c38420897fe46b95accfcf17e0fa3c24bb3dc2c4.tar.xz wireguard-openbsd-c38420897fe46b95accfcf17e0fa3c24bb3dc2c4.zip |
rework the main loop so we can drop kmem privs a little later,
prepping for a coming kernel change. we need to call sysctl for
all the procs to get their vmspace pointer, then we drop, then
we go grovelling. ok deraadt
Diffstat (limited to 'usr.sbin/procmap')
-rw-r--r-- | usr.sbin/procmap/procmap.c | 68 |
1 files changed, 47 insertions, 21 deletions
diff --git a/usr.sbin/procmap/procmap.c b/usr.sbin/procmap/procmap.c index 80e7471deb9..cbfae94dc79 100644 --- a/usr.sbin/procmap/procmap.c +++ b/usr.sbin/procmap/procmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: procmap.c,v 1.44 2013/03/20 15:24:17 tedu Exp $ */ +/* $OpenBSD: procmap.c,v 1.45 2013/03/23 10:46:04 tedu Exp $ */ /* $NetBSD: pmap.c,v 1.1 2002/09/01 20:32:44 atatat Exp $ */ /* @@ -202,12 +202,14 @@ int main(int argc, char *argv[]) { char errbuf[_POSIX2_LINE_MAX], *kmem = NULL, *kernel = NULL; - struct kinfo_proc *kproc; + struct kinfo_proc *kprocs, *kproc; struct sum total_sum; - int many, ch, rc; + int many, ch, rc, i, nprocs; kvm_t *kd; pid_t pid = -1; gid_t gid; + int mib[2]; + size_t len; while ((ch = getopt(argc, argv, "AaD:dlmM:N:p:Prsvx")) != -1) { switch (ch) { @@ -279,22 +281,26 @@ main(int argc, char *argv[]) /* start by opening libkvm */ kd = kvm_openfiles(kernel, kmem, NULL, O_RDONLY, errbuf); - if (kernel == NULL && kmem == NULL) - if (setresgid(gid, gid, gid) == -1) - err(1, "setresgid"); - if (kd == NULL) errx(1, "%s", errbuf); - /* get "bootstrap" addresses from kernel */ - load_symbols(kd); - - memset(&total_sum, 0, sizeof(total_sum)); + nprocs = 0; + mib[0] = CTL_KERN; + mib[1] = KERN_NPROCS; + len = sizeof(nprocs); + sysctl(mib, 2, &nprocs, &len, NULL, 0); + kprocs = calloc(nprocs, sizeof(struct kinfo_proc)); + if (!kprocs) + err(1, "calloc"); + /* + * we need to do this to get secret pointers via sysctl + * before we drop the kmem group + */ + i = 0; do { - struct sum sum; - - memset(&sum, 0, sizeof(sum)); + if (i == nprocs) + errx(1, "too many procs at once"); if (pid == -1) { if (argc == 0) @@ -307,9 +313,7 @@ main(int argc, char *argv[]) } /* find the process id */ - if (pid == 0) - kproc = NULL; - else { + if (pid != 0) { kproc = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &rc); if (kproc == NULL || rc == 0) { @@ -318,21 +322,43 @@ main(int argc, char *argv[]) pid = -1; continue; } + memcpy(&kprocs[i], kproc, sizeof(struct kinfo_proc)); } + pid = -1; + + i++; + } while (argc > 0); + + nprocs = i; + + if (kernel == NULL && kmem == NULL) + if (setresgid(gid, gid, gid) == -1) + err(1, "setresgid"); + + /* get "bootstrap" addresses from kernel */ + load_symbols(kd); + + memset(&total_sum, 0, sizeof(total_sum)); + + for (i = 0; i < nprocs; i++) { + struct sum sum; + + memset(&sum, 0, sizeof(sum)); + + kproc = &kprocs[i]; /* dump it */ if (many) { if (kproc) - printf("process %d:\n", pid); + printf("process %d:\n", kproc->p_pid); else printf("kernel:\n"); } - process_map(kd, pid, kproc, &sum); + process_map(kd, kproc ? kproc->p_pid : 0, kproc, &sum); if (print_amap) print_sum(&sum, &total_sum); - pid = -1; - } while (argc > 0); + } if (print_amap) print_sum(&total_sum, NULL); |