1 /*- 2 * SPDX-License-Identifier: BSD-4-Clause 3 * 4 * Copyright (c) 2017 Dell EMC 5 * Copyright (c) 2009 Stanislav Sedov <stas@FreeBSD.org> 6 * Copyright (c) 1988, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Berkeley and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 */ 37 38 #include <sys/cdefs.h> 39 __FBSDID("$FreeBSD$"); 40 41 #include <sys/param.h> 42 #include <sys/elf.h> 43 #include <sys/time.h> 44 #include <sys/resourcevar.h> 45 #define _WANT_UCRED 46 #include <sys/ucred.h> 47 #undef _WANT_UCRED 48 #include <sys/proc.h> 49 #include <sys/user.h> 50 #include <sys/stat.h> 51 #include <sys/vnode.h> 52 #include <sys/socket.h> 53 #define _WANT_SOCKET 54 #include <sys/socketvar.h> 55 #include <sys/domain.h> 56 #include <sys/protosw.h> 57 #include <sys/un.h> 58 #define _WANT_UNPCB 59 #include <sys/unpcb.h> 60 #include <sys/sysctl.h> 61 #include <sys/tty.h> 62 #include <sys/filedesc.h> 63 #include <sys/queue.h> 64 #define _WANT_FILE 65 #include <sys/file.h> 66 #include <sys/conf.h> 67 #include <sys/ksem.h> 68 #include <sys/mman.h> 69 #include <sys/capsicum.h> 70 #include <sys/ptrace.h> 71 #define _KERNEL 72 #include <sys/mount.h> 73 #include <sys/pipe.h> 74 #include <ufs/ufs/quota.h> 75 #include <ufs/ufs/inode.h> 76 #include <fs/devfs/devfs.h> 77 #include <fs/devfs/devfs_int.h> 78 #undef _KERNEL 79 #include <nfs/nfsproto.h> 80 #include <nfsclient/nfs.h> 81 #include <nfsclient/nfsnode.h> 82 83 #include <vm/vm.h> 84 #include <vm/vm_map.h> 85 #include <vm/vm_object.h> 86 87 #include <net/route.h> 88 #include <netinet/in.h> 89 #include <netinet/in_systm.h> 90 #include <netinet/ip.h> 91 #define _WANT_INPCB 92 #include <netinet/in_pcb.h> 93 94 #include <assert.h> 95 #include <ctype.h> 96 #include <err.h> 97 #include <fcntl.h> 98 #include <kvm.h> 99 #include <libutil.h> 100 #include <limits.h> 101 #include <paths.h> 102 #include <pwd.h> 103 #include <stdio.h> 104 #include <stdlib.h> 105 #include <stddef.h> 106 #include <string.h> 107 #include <unistd.h> 108 #include <netdb.h> 109 110 #include <libprocstat.h> 111 #include "libprocstat_internal.h" 112 #include "common_kvm.h" 113 #include "core.h" 114 115 int statfs(const char *, struct statfs *); /* XXX */ 116 117 #define PROCSTAT_KVM 1 118 #define PROCSTAT_SYSCTL 2 119 #define PROCSTAT_CORE 3 120 121 static char **getargv(struct procstat *procstat, struct kinfo_proc *kp, 122 size_t nchr, int env); 123 static char *getmnton(kvm_t *kd, struct mount *m); 124 static struct kinfo_vmentry * kinfo_getvmmap_core(struct procstat_core *core, 125 int *cntp); 126 static Elf_Auxinfo *procstat_getauxv_core(struct procstat_core *core, 127 unsigned int *cntp); 128 static Elf_Auxinfo *procstat_getauxv_sysctl(pid_t pid, unsigned int *cntp); 129 static struct filestat_list *procstat_getfiles_kvm( 130 struct procstat *procstat, struct kinfo_proc *kp, int mmapped); 131 static struct filestat_list *procstat_getfiles_sysctl( 132 struct procstat *procstat, struct kinfo_proc *kp, int mmapped); 133 static int procstat_get_pipe_info_sysctl(struct filestat *fst, 134 struct pipestat *pipe, char *errbuf); 135 static int procstat_get_pipe_info_kvm(kvm_t *kd, struct filestat *fst, 136 struct pipestat *pipe, char *errbuf); 137 static int procstat_get_pts_info_sysctl(struct filestat *fst, 138 struct ptsstat *pts, char *errbuf); 139 static int procstat_get_pts_info_kvm(kvm_t *kd, struct filestat *fst, 140 struct ptsstat *pts, char *errbuf); 141 static int procstat_get_sem_info_sysctl(struct filestat *fst, 142 struct semstat *sem, char *errbuf); 143 static int procstat_get_sem_info_kvm(kvm_t *kd, struct filestat *fst, 144 struct semstat *sem, char *errbuf); 145 static int procstat_get_shm_info_sysctl(struct filestat *fst, 146 struct shmstat *shm, char *errbuf); 147 static int procstat_get_shm_info_kvm(kvm_t *kd, struct filestat *fst, 148 struct shmstat *shm, char *errbuf); 149 static int procstat_get_socket_info_sysctl(struct filestat *fst, 150 struct sockstat *sock, char *errbuf); 151 static int procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst, 152 struct sockstat *sock, char *errbuf); 153 static int to_filestat_flags(int flags); 154 static int procstat_get_vnode_info_kvm(kvm_t *kd, struct filestat *fst, 155 struct vnstat *vn, char *errbuf); 156 static int procstat_get_vnode_info_sysctl(struct filestat *fst, 157 struct vnstat *vn, char *errbuf); 158 static gid_t *procstat_getgroups_core(struct procstat_core *core, 159 unsigned int *count); 160 static gid_t * procstat_getgroups_kvm(kvm_t *kd, struct kinfo_proc *kp, 161 unsigned int *count); 162 static gid_t *procstat_getgroups_sysctl(pid_t pid, unsigned int *count); 163 static struct kinfo_kstack *procstat_getkstack_sysctl(pid_t pid, 164 int *cntp); 165 static int procstat_getosrel_core(struct procstat_core *core, 166 int *osrelp); 167 static int procstat_getosrel_kvm(kvm_t *kd, struct kinfo_proc *kp, 168 int *osrelp); 169 static int procstat_getosrel_sysctl(pid_t pid, int *osrelp); 170 static int procstat_getpathname_core(struct procstat_core *core, 171 char *pathname, size_t maxlen); 172 static int procstat_getpathname_sysctl(pid_t pid, char *pathname, 173 size_t maxlen); 174 static int procstat_getrlimit_core(struct procstat_core *core, int which, 175 struct rlimit* rlimit); 176 static int procstat_getrlimit_kvm(kvm_t *kd, struct kinfo_proc *kp, 177 int which, struct rlimit* rlimit); 178 static int procstat_getrlimit_sysctl(pid_t pid, int which, 179 struct rlimit* rlimit); 180 static int procstat_getumask_core(struct procstat_core *core, 181 unsigned short *maskp); 182 static int procstat_getumask_kvm(kvm_t *kd, struct kinfo_proc *kp, 183 unsigned short *maskp); 184 static int procstat_getumask_sysctl(pid_t pid, unsigned short *maskp); 185 static int vntype2psfsttype(int type); 186 187 void 188 procstat_close(struct procstat *procstat) 189 { 190 191 assert(procstat); 192 if (procstat->type == PROCSTAT_KVM) 193 kvm_close(procstat->kd); 194 else if (procstat->type == PROCSTAT_CORE) 195 procstat_core_close(procstat->core); 196 procstat_freeargv(procstat); 197 procstat_freeenvv(procstat); 198 free(procstat); 199 } 200 201 struct procstat * 202 procstat_open_sysctl(void) 203 { 204 struct procstat *procstat; 205 206 procstat = calloc(1, sizeof(*procstat)); 207 if (procstat == NULL) { 208 warn("malloc()"); 209 return (NULL); 210 } 211 procstat->type = PROCSTAT_SYSCTL; 212 return (procstat); 213 } 214 215 struct procstat * 216 procstat_open_kvm(const char *nlistf, const char *memf) 217 { 218 struct procstat *procstat; 219 kvm_t *kd; 220 char buf[_POSIX2_LINE_MAX]; 221 222 procstat = calloc(1, sizeof(*procstat)); 223 if (procstat == NULL) { 224 warn("malloc()"); 225 return (NULL); 226 } 227 kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf); 228 if (kd == NULL) { 229 warnx("kvm_openfiles(): %s", buf); 230 free(procstat); 231 return (NULL); 232 } 233 procstat->type = PROCSTAT_KVM; 234 procstat->kd = kd; 235 return (procstat); 236 } 237 238 struct procstat * 239 procstat_open_core(const char *filename) 240 { 241 struct procstat *procstat; 242 struct procstat_core *core; 243 244 procstat = calloc(1, sizeof(*procstat)); 245 if (procstat == NULL) { 246 warn("malloc()"); 247 return (NULL); 248 } 249 core = procstat_core_open(filename); 250 if (core == NULL) { 251 free(procstat); 252 return (NULL); 253 } 254 procstat->type = PROCSTAT_CORE; 255 procstat->core = core; 256 return (procstat); 257 } 258 259 struct kinfo_proc * 260 procstat_getprocs(struct procstat *procstat, int what, int arg, 261 unsigned int *count) 262 { 263 struct kinfo_proc *p0, *p; 264 size_t len, olen; 265 int name[4]; 266 int cnt; 267 int error; 268 269 assert(procstat); 270 assert(count); 271 p = NULL; 272 if (procstat->type == PROCSTAT_KVM) { 273 *count = 0; 274 p0 = kvm_getprocs(procstat->kd, what, arg, &cnt); 275 if (p0 == NULL || cnt <= 0) 276 return (NULL); 277 *count = cnt; 278 len = *count * sizeof(*p); 279 p = malloc(len); 280 if (p == NULL) { 281 warnx("malloc(%zu)", len); 282 goto fail; 283 } 284 bcopy(p0, p, len); 285 return (p); 286 } else if (procstat->type == PROCSTAT_SYSCTL) { 287 len = 0; 288 name[0] = CTL_KERN; 289 name[1] = KERN_PROC; 290 name[2] = what; 291 name[3] = arg; 292 error = sysctl(name, nitems(name), NULL, &len, NULL, 0); 293 if (error < 0 && errno != EPERM) { 294 warn("sysctl(kern.proc)"); 295 goto fail; 296 } 297 if (len == 0) { 298 warnx("no processes?"); 299 goto fail; 300 } 301 do { 302 len += len / 10; 303 p = reallocf(p, len); 304 if (p == NULL) { 305 warnx("reallocf(%zu)", len); 306 goto fail; 307 } 308 olen = len; 309 error = sysctl(name, nitems(name), p, &len, NULL, 0); 310 } while (error < 0 && errno == ENOMEM && olen == len); 311 if (error < 0 && errno != EPERM) { 312 warn("sysctl(kern.proc)"); 313 goto fail; 314 } 315 /* Perform simple consistency checks. */ 316 if ((len % sizeof(*p)) != 0 || p->ki_structsize != sizeof(*p)) { 317 warnx("kinfo_proc structure size mismatch (len = %zu)", len); 318 goto fail; 319 } 320 *count = len / sizeof(*p); 321 return (p); 322 } else if (procstat->type == PROCSTAT_CORE) { 323 p = procstat_core_get(procstat->core, PSC_TYPE_PROC, NULL, 324 &len); 325 if ((len % sizeof(*p)) != 0 || p->ki_structsize != sizeof(*p)) { 326 warnx("kinfo_proc structure size mismatch"); 327 goto fail; 328 } 329 *count = len / sizeof(*p); 330 return (p); 331 } else { 332 warnx("unknown access method: %d", procstat->type); 333 return (NULL); 334 } 335 fail: 336 if (p) 337 free(p); 338 return (NULL); 339 } 340 341 void 342 procstat_freeprocs(struct procstat *procstat __unused, struct kinfo_proc *p) 343 { 344 345 if (p != NULL) 346 free(p); 347 p = NULL; 348 } 349 350 struct filestat_list * 351 procstat_getfiles(struct procstat *procstat, struct kinfo_proc *kp, int mmapped) 352 { 353 354 switch(procstat->type) { 355 case PROCSTAT_KVM: 356 return (procstat_getfiles_kvm(procstat, kp, mmapped)); 357 case PROCSTAT_SYSCTL: 358 case PROCSTAT_CORE: 359 return (procstat_getfiles_sysctl(procstat, kp, mmapped)); 360 default: 361 warnx("unknown access method: %d", procstat->type); 362 return (NULL); 363 } 364 } 365 366 void 367 procstat_freefiles(struct procstat *procstat, struct filestat_list *head) 368 { 369 struct filestat *fst, *tmp; 370 371 STAILQ_FOREACH_SAFE(fst, head, next, tmp) { 372 if (fst->fs_path != NULL) 373 free(fst->fs_path); 374 free(fst); 375 } 376 free(head); 377 if (procstat->vmentries != NULL) { 378 free(procstat->vmentries); 379 procstat->vmentries = NULL; 380 } 381 if (procstat->files != NULL) { 382 free(procstat->files); 383 procstat->files = NULL; 384 } 385 } 386 387 static struct filestat * 388 filestat_new_entry(void *typedep, int type, int fd, int fflags, int uflags, 389 int refcount, off_t offset, char *path, cap_rights_t *cap_rightsp) 390 { 391 struct filestat *entry; 392 393 entry = calloc(1, sizeof(*entry)); 394 if (entry == NULL) { 395 warn("malloc()"); 396 return (NULL); 397 } 398 entry->fs_typedep = typedep; 399 entry->fs_fflags = fflags; 400 entry->fs_uflags = uflags; 401 entry->fs_fd = fd; 402 entry->fs_type = type; 403 entry->fs_ref_count = refcount; 404 entry->fs_offset = offset; 405 entry->fs_path = path; 406 if (cap_rightsp != NULL) 407 entry->fs_cap_rights = *cap_rightsp; 408 else 409 cap_rights_init(&entry->fs_cap_rights); 410 return (entry); 411 } 412 413 static struct vnode * 414 getctty(kvm_t *kd, struct kinfo_proc *kp) 415 { 416 struct pgrp pgrp; 417 struct proc proc; 418 struct session sess; 419 int error; 420 421 assert(kp); 422 error = kvm_read_all(kd, (unsigned long)kp->ki_paddr, &proc, 423 sizeof(proc)); 424 if (error == 0) { 425 warnx("can't read proc struct at %p for pid %d", 426 kp->ki_paddr, kp->ki_pid); 427 return (NULL); 428 } 429 if (proc.p_pgrp == NULL) 430 return (NULL); 431 error = kvm_read_all(kd, (unsigned long)proc.p_pgrp, &pgrp, 432 sizeof(pgrp)); 433 if (error == 0) { 434 warnx("can't read pgrp struct at %p for pid %d", 435 proc.p_pgrp, kp->ki_pid); 436 return (NULL); 437 } 438 error = kvm_read_all(kd, (unsigned long)pgrp.pg_session, &sess, 439 sizeof(sess)); 440 if (error == 0) { 441 warnx("can't read session struct at %p for pid %d", 442 pgrp.pg_session, kp->ki_pid); 443 return (NULL); 444 } 445 return (sess.s_ttyvp); 446 } 447 448 static struct filestat_list * 449 procstat_getfiles_kvm(struct procstat *procstat, struct kinfo_proc *kp, int mmapped) 450 { 451 struct file file; 452 struct filedesc filed; 453 struct vm_map_entry vmentry; 454 struct vm_object object; 455 struct vmspace vmspace; 456 vm_map_entry_t entryp; 457 vm_map_t map; 458 vm_object_t objp; 459 struct vnode *vp; 460 struct file **ofiles; 461 struct filestat *entry; 462 struct filestat_list *head; 463 kvm_t *kd; 464 void *data; 465 int i, fflags; 466 int prot, type; 467 unsigned int nfiles; 468 469 assert(procstat); 470 kd = procstat->kd; 471 if (kd == NULL) 472 return (NULL); 473 if (kp->ki_fd == NULL) 474 return (NULL); 475 if (!kvm_read_all(kd, (unsigned long)kp->ki_fd, &filed, 476 sizeof(filed))) { 477 warnx("can't read filedesc at %p", (void *)kp->ki_fd); 478 return (NULL); 479 } 480 481 /* 482 * Allocate list head. 483 */ 484 head = malloc(sizeof(*head)); 485 if (head == NULL) 486 return (NULL); 487 STAILQ_INIT(head); 488 489 /* root directory vnode, if one. */ 490 if (filed.fd_rdir) { 491 entry = filestat_new_entry(filed.fd_rdir, PS_FST_TYPE_VNODE, -1, 492 PS_FST_FFLAG_READ, PS_FST_UFLAG_RDIR, 0, 0, NULL, NULL); 493 if (entry != NULL) 494 STAILQ_INSERT_TAIL(head, entry, next); 495 } 496 /* current working directory vnode. */ 497 if (filed.fd_cdir) { 498 entry = filestat_new_entry(filed.fd_cdir, PS_FST_TYPE_VNODE, -1, 499 PS_FST_FFLAG_READ, PS_FST_UFLAG_CDIR, 0, 0, NULL, NULL); 500 if (entry != NULL) 501 STAILQ_INSERT_TAIL(head, entry, next); 502 } 503 /* jail root, if any. */ 504 if (filed.fd_jdir) { 505 entry = filestat_new_entry(filed.fd_jdir, PS_FST_TYPE_VNODE, -1, 506 PS_FST_FFLAG_READ, PS_FST_UFLAG_JAIL, 0, 0, NULL, NULL); 507 if (entry != NULL) 508 STAILQ_INSERT_TAIL(head, entry, next); 509 } 510 /* ktrace vnode, if one */ 511 if (kp->ki_tracep) { 512 entry = filestat_new_entry(kp->ki_tracep, PS_FST_TYPE_VNODE, -1, 513 PS_FST_FFLAG_READ | PS_FST_FFLAG_WRITE, 514 PS_FST_UFLAG_TRACE, 0, 0, NULL, NULL); 515 if (entry != NULL) 516 STAILQ_INSERT_TAIL(head, entry, next); 517 } 518 /* text vnode, if one */ 519 if (kp->ki_textvp) { 520 entry = filestat_new_entry(kp->ki_textvp, PS_FST_TYPE_VNODE, -1, 521 PS_FST_FFLAG_READ, PS_FST_UFLAG_TEXT, 0, 0, NULL, NULL); 522 if (entry != NULL) 523 STAILQ_INSERT_TAIL(head, entry, next); 524 } 525 /* Controlling terminal. */ 526 if ((vp = getctty(kd, kp)) != NULL) { 527 entry = filestat_new_entry(vp, PS_FST_TYPE_VNODE, -1, 528 PS_FST_FFLAG_READ | PS_FST_FFLAG_WRITE, 529 PS_FST_UFLAG_CTTY, 0, 0, NULL, NULL); 530 if (entry != NULL) 531 STAILQ_INSERT_TAIL(head, entry, next); 532 } 533 534 nfiles = filed.fd_lastfile + 1; 535 ofiles = malloc(nfiles * sizeof(struct file *)); 536 if (ofiles == NULL) { 537 warn("malloc(%zu)", nfiles * sizeof(struct file *)); 538 goto do_mmapped; 539 } 540 if (!kvm_read_all(kd, (unsigned long)filed.fd_ofiles, ofiles, 541 nfiles * sizeof(struct file *))) { 542 warnx("cannot read file structures at %p", 543 (void *)filed.fd_ofiles); 544 free(ofiles); 545 goto do_mmapped; 546 } 547 for (i = 0; i <= filed.fd_lastfile; i++) { 548 if (ofiles[i] == NULL) 549 continue; 550 if (!kvm_read_all(kd, (unsigned long)ofiles[i], &file, 551 sizeof(struct file))) { 552 warnx("can't read file %d at %p", i, 553 (void *)ofiles[i]); 554 continue; 555 } 556 switch (file.f_type) { 557 case DTYPE_VNODE: 558 type = PS_FST_TYPE_VNODE; 559 data = file.f_vnode; 560 break; 561 case DTYPE_SOCKET: 562 type = PS_FST_TYPE_SOCKET; 563 data = file.f_data; 564 break; 565 case DTYPE_PIPE: 566 type = PS_FST_TYPE_PIPE; 567 data = file.f_data; 568 break; 569 case DTYPE_FIFO: 570 type = PS_FST_TYPE_FIFO; 571 data = file.f_vnode; 572 break; 573 #ifdef DTYPE_PTS 574 case DTYPE_PTS: 575 type = PS_FST_TYPE_PTS; 576 data = file.f_data; 577 break; 578 #endif 579 case DTYPE_SEM: 580 type = PS_FST_TYPE_SEM; 581 data = file.f_data; 582 break; 583 case DTYPE_SHM: 584 type = PS_FST_TYPE_SHM; 585 data = file.f_data; 586 break; 587 case DTYPE_PROCDESC: 588 type = PS_FST_TYPE_PROCDESC; 589 data = file.f_data; 590 break; 591 default: 592 continue; 593 } 594 /* XXXRW: No capability rights support for kvm yet. */ 595 entry = filestat_new_entry(data, type, i, 596 to_filestat_flags(file.f_flag), 0, 0, 0, NULL, NULL); 597 if (entry != NULL) 598 STAILQ_INSERT_TAIL(head, entry, next); 599 } 600 free(ofiles); 601 602 do_mmapped: 603 604 /* 605 * Process mmapped files if requested. 606 */ 607 if (mmapped) { 608 if (!kvm_read_all(kd, (unsigned long)kp->ki_vmspace, &vmspace, 609 sizeof(vmspace))) { 610 warnx("can't read vmspace at %p", 611 (void *)kp->ki_vmspace); 612 goto exit; 613 } 614 map = &vmspace.vm_map; 615 616 for (entryp = map->header.next; 617 entryp != &kp->ki_vmspace->vm_map.header; 618 entryp = vmentry.next) { 619 if (!kvm_read_all(kd, (unsigned long)entryp, &vmentry, 620 sizeof(vmentry))) { 621 warnx("can't read vm_map_entry at %p", 622 (void *)entryp); 623 continue; 624 } 625 if (vmentry.eflags & MAP_ENTRY_IS_SUB_MAP) 626 continue; 627 if ((objp = vmentry.object.vm_object) == NULL) 628 continue; 629 for (; objp; objp = object.backing_object) { 630 if (!kvm_read_all(kd, (unsigned long)objp, 631 &object, sizeof(object))) { 632 warnx("can't read vm_object at %p", 633 (void *)objp); 634 break; 635 } 636 } 637 638 /* We want only vnode objects. */ 639 if (object.type != OBJT_VNODE) 640 continue; 641 642 prot = vmentry.protection; 643 fflags = 0; 644 if (prot & VM_PROT_READ) 645 fflags = PS_FST_FFLAG_READ; 646 if ((vmentry.eflags & MAP_ENTRY_COW) == 0 && 647 prot & VM_PROT_WRITE) 648 fflags |= PS_FST_FFLAG_WRITE; 649 650 /* 651 * Create filestat entry. 652 */ 653 entry = filestat_new_entry(object.handle, 654 PS_FST_TYPE_VNODE, -1, fflags, 655 PS_FST_UFLAG_MMAP, 0, 0, NULL, NULL); 656 if (entry != NULL) 657 STAILQ_INSERT_TAIL(head, entry, next); 658 } 659 } 660 exit: 661 return (head); 662 } 663 664 /* 665 * kinfo types to filestat translation. 666 */ 667 static int 668 kinfo_type2fst(int kftype) 669 { 670 static struct { 671 int kf_type; 672 int fst_type; 673 } kftypes2fst[] = { 674 { KF_TYPE_PROCDESC, PS_FST_TYPE_PROCDESC }, 675 { KF_TYPE_CRYPTO, PS_FST_TYPE_CRYPTO }, 676 { KF_TYPE_FIFO, PS_FST_TYPE_FIFO }, 677 { KF_TYPE_KQUEUE, PS_FST_TYPE_KQUEUE }, 678 { KF_TYPE_MQUEUE, PS_FST_TYPE_MQUEUE }, 679 { KF_TYPE_NONE, PS_FST_TYPE_NONE }, 680 { KF_TYPE_PIPE, PS_FST_TYPE_PIPE }, 681 { KF_TYPE_PTS, PS_FST_TYPE_PTS }, 682 { KF_TYPE_SEM, PS_FST_TYPE_SEM }, 683 { KF_TYPE_SHM, PS_FST_TYPE_SHM }, 684 { KF_TYPE_SOCKET, PS_FST_TYPE_SOCKET }, 685 { KF_TYPE_VNODE, PS_FST_TYPE_VNODE }, 686 { KF_TYPE_UNKNOWN, PS_FST_TYPE_UNKNOWN } 687 }; 688 #define NKFTYPES (sizeof(kftypes2fst) / sizeof(*kftypes2fst)) 689 unsigned int i; 690 691 for (i = 0; i < NKFTYPES; i++) 692 if (kftypes2fst[i].kf_type == kftype) 693 break; 694 if (i == NKFTYPES) 695 return (PS_FST_TYPE_UNKNOWN); 696 return (kftypes2fst[i].fst_type); 697 } 698 699 /* 700 * kinfo flags to filestat translation. 701 */ 702 static int 703 kinfo_fflags2fst(int kfflags) 704 { 705 static struct { 706 int kf_flag; 707 int fst_flag; 708 } kfflags2fst[] = { 709 { KF_FLAG_APPEND, PS_FST_FFLAG_APPEND }, 710 { KF_FLAG_ASYNC, PS_FST_FFLAG_ASYNC }, 711 { KF_FLAG_CREAT, PS_FST_FFLAG_CREAT }, 712 { KF_FLAG_DIRECT, PS_FST_FFLAG_DIRECT }, 713 { KF_FLAG_EXCL, PS_FST_FFLAG_EXCL }, 714 { KF_FLAG_EXEC, PS_FST_FFLAG_EXEC }, 715 { KF_FLAG_EXLOCK, PS_FST_FFLAG_EXLOCK }, 716 { KF_FLAG_FSYNC, PS_FST_FFLAG_SYNC }, 717 { KF_FLAG_HASLOCK, PS_FST_FFLAG_HASLOCK }, 718 { KF_FLAG_NOFOLLOW, PS_FST_FFLAG_NOFOLLOW }, 719 { KF_FLAG_NONBLOCK, PS_FST_FFLAG_NONBLOCK }, 720 { KF_FLAG_READ, PS_FST_FFLAG_READ }, 721 { KF_FLAG_SHLOCK, PS_FST_FFLAG_SHLOCK }, 722 { KF_FLAG_TRUNC, PS_FST_FFLAG_TRUNC }, 723 { KF_FLAG_WRITE, PS_FST_FFLAG_WRITE } 724 }; 725 #define NKFFLAGS (sizeof(kfflags2fst) / sizeof(*kfflags2fst)) 726 unsigned int i; 727 int flags; 728 729 flags = 0; 730 for (i = 0; i < NKFFLAGS; i++) 731 if ((kfflags & kfflags2fst[i].kf_flag) != 0) 732 flags |= kfflags2fst[i].fst_flag; 733 return (flags); 734 } 735 736 static int 737 kinfo_uflags2fst(int fd) 738 { 739 740 switch (fd) { 741 case KF_FD_TYPE_CTTY: 742 return (PS_FST_UFLAG_CTTY); 743 case KF_FD_TYPE_CWD: 744 return (PS_FST_UFLAG_CDIR); 745 case KF_FD_TYPE_JAIL: 746 return (PS_FST_UFLAG_JAIL); 747 case KF_FD_TYPE_TEXT: 748 return (PS_FST_UFLAG_TEXT); 749 case KF_FD_TYPE_TRACE: 750 return (PS_FST_UFLAG_TRACE); 751 case KF_FD_TYPE_ROOT: 752 return (PS_FST_UFLAG_RDIR); 753 } 754 return (0); 755 } 756 757 static struct kinfo_file * 758 kinfo_getfile_core(struct procstat_core *core, int *cntp) 759 { 760 int cnt; 761 size_t len; 762 char *buf, *bp, *eb; 763 struct kinfo_file *kif, *kp, *kf; 764 765 buf = procstat_core_get(core, PSC_TYPE_FILES, NULL, &len); 766 if (buf == NULL) 767 return (NULL); 768 /* 769 * XXXMG: The code below is just copy&past from libutil. 770 * The code duplication can be avoided if libutil 771 * is extended to provide something like: 772 * struct kinfo_file *kinfo_getfile_from_buf(const char *buf, 773 * size_t len, int *cntp); 774 */ 775 776 /* Pass 1: count items */ 777 cnt = 0; 778 bp = buf; 779 eb = buf + len; 780 while (bp < eb) { 781 kf = (struct kinfo_file *)(uintptr_t)bp; 782 if (kf->kf_structsize == 0) 783 break; 784 bp += kf->kf_structsize; 785 cnt++; 786 } 787 788 kif = calloc(cnt, sizeof(*kif)); 789 if (kif == NULL) { 790 free(buf); 791 return (NULL); 792 } 793 bp = buf; 794 eb = buf + len; 795 kp = kif; 796 /* Pass 2: unpack */ 797 while (bp < eb) { 798 kf = (struct kinfo_file *)(uintptr_t)bp; 799 if (kf->kf_structsize == 0) 800 break; 801 /* Copy/expand into pre-zeroed buffer */ 802 memcpy(kp, kf, kf->kf_structsize); 803 /* Advance to next packed record */ 804 bp += kf->kf_structsize; 805 /* Set field size to fixed length, advance */ 806 kp->kf_structsize = sizeof(*kp); 807 kp++; 808 } 809 free(buf); 810 *cntp = cnt; 811 return (kif); /* Caller must free() return value */ 812 } 813 814 static struct filestat_list * 815 procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp, 816 int mmapped) 817 { 818 struct kinfo_file *kif, *files; 819 struct kinfo_vmentry *kve, *vmentries; 820 struct filestat_list *head; 821 struct filestat *entry; 822 char *path; 823 off_t offset; 824 int cnt, fd, fflags; 825 int i, type, uflags; 826 int refcount; 827 cap_rights_t cap_rights; 828 829 assert(kp); 830 if (kp->ki_fd == NULL) 831 return (NULL); 832 switch(procstat->type) { 833 case PROCSTAT_SYSCTL: 834 files = kinfo_getfile(kp->ki_pid, &cnt); 835 break; 836 case PROCSTAT_CORE: 837 files = kinfo_getfile_core(procstat->core, &cnt); 838 break; 839 default: 840 assert(!"invalid type"); 841 } 842 if (files == NULL && errno != EPERM) { 843 warn("kinfo_getfile()"); 844 return (NULL); 845 } 846 procstat->files = files; 847 848 /* 849 * Allocate list head. 850 */ 851 head = malloc(sizeof(*head)); 852 if (head == NULL) 853 return (NULL); 854 STAILQ_INIT(head); 855 for (i = 0; i < cnt; i++) { 856 kif = &files[i]; 857 858 type = kinfo_type2fst(kif->kf_type); 859 fd = kif->kf_fd >= 0 ? kif->kf_fd : -1; 860 fflags = kinfo_fflags2fst(kif->kf_flags); 861 uflags = kinfo_uflags2fst(kif->kf_fd); 862 refcount = kif->kf_ref_count; 863 offset = kif->kf_offset; 864 if (*kif->kf_path != '\0') 865 path = strdup(kif->kf_path); 866 else 867 path = NULL; 868 cap_rights = kif->kf_cap_rights; 869 870 /* 871 * Create filestat entry. 872 */ 873 entry = filestat_new_entry(kif, type, fd, fflags, uflags, 874 refcount, offset, path, &cap_rights); 875 if (entry != NULL) 876 STAILQ_INSERT_TAIL(head, entry, next); 877 } 878 if (mmapped != 0) { 879 vmentries = procstat_getvmmap(procstat, kp, &cnt); 880 procstat->vmentries = vmentries; 881 if (vmentries == NULL || cnt == 0) 882 goto fail; 883 for (i = 0; i < cnt; i++) { 884 kve = &vmentries[i]; 885 if (kve->kve_type != KVME_TYPE_VNODE) 886 continue; 887 fflags = 0; 888 if (kve->kve_protection & KVME_PROT_READ) 889 fflags = PS_FST_FFLAG_READ; 890 if ((kve->kve_flags & KVME_FLAG_COW) == 0 && 891 kve->kve_protection & KVME_PROT_WRITE) 892 fflags |= PS_FST_FFLAG_WRITE; 893 offset = kve->kve_offset; 894 refcount = kve->kve_ref_count; 895 if (*kve->kve_path != '\0') 896 path = strdup(kve->kve_path); 897 else 898 path = NULL; 899 entry = filestat_new_entry(kve, PS_FST_TYPE_VNODE, -1, 900 fflags, PS_FST_UFLAG_MMAP, refcount, offset, path, 901 NULL); 902 if (entry != NULL) 903 STAILQ_INSERT_TAIL(head, entry, next); 904 } 905 } 906 fail: 907 return (head); 908 } 909 910 int 911 procstat_get_pipe_info(struct procstat *procstat, struct filestat *fst, 912 struct pipestat *ps, char *errbuf) 913 { 914 915 assert(ps); 916 if (procstat->type == PROCSTAT_KVM) { 917 return (procstat_get_pipe_info_kvm(procstat->kd, fst, ps, 918 errbuf)); 919 } else if (procstat->type == PROCSTAT_SYSCTL || 920 procstat->type == PROCSTAT_CORE) { 921 return (procstat_get_pipe_info_sysctl(fst, ps, errbuf)); 922 } else { 923 warnx("unknown access method: %d", procstat->type); 924 if (errbuf != NULL) 925 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 926 return (1); 927 } 928 } 929 930 static int 931 procstat_get_pipe_info_kvm(kvm_t *kd, struct filestat *fst, 932 struct pipestat *ps, char *errbuf) 933 { 934 struct pipe pi; 935 void *pipep; 936 937 assert(kd); 938 assert(ps); 939 assert(fst); 940 bzero(ps, sizeof(*ps)); 941 pipep = fst->fs_typedep; 942 if (pipep == NULL) 943 goto fail; 944 if (!kvm_read_all(kd, (unsigned long)pipep, &pi, sizeof(struct pipe))) { 945 warnx("can't read pipe at %p", (void *)pipep); 946 goto fail; 947 } 948 ps->addr = (uintptr_t)pipep; 949 ps->peer = (uintptr_t)pi.pipe_peer; 950 ps->buffer_cnt = pi.pipe_buffer.cnt; 951 return (0); 952 953 fail: 954 if (errbuf != NULL) 955 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 956 return (1); 957 } 958 959 static int 960 procstat_get_pipe_info_sysctl(struct filestat *fst, struct pipestat *ps, 961 char *errbuf __unused) 962 { 963 struct kinfo_file *kif; 964 965 assert(ps); 966 assert(fst); 967 bzero(ps, sizeof(*ps)); 968 kif = fst->fs_typedep; 969 if (kif == NULL) 970 return (1); 971 ps->addr = kif->kf_un.kf_pipe.kf_pipe_addr; 972 ps->peer = kif->kf_un.kf_pipe.kf_pipe_peer; 973 ps->buffer_cnt = kif->kf_un.kf_pipe.kf_pipe_buffer_cnt; 974 return (0); 975 } 976 977 int 978 procstat_get_pts_info(struct procstat *procstat, struct filestat *fst, 979 struct ptsstat *pts, char *errbuf) 980 { 981 982 assert(pts); 983 if (procstat->type == PROCSTAT_KVM) { 984 return (procstat_get_pts_info_kvm(procstat->kd, fst, pts, 985 errbuf)); 986 } else if (procstat->type == PROCSTAT_SYSCTL || 987 procstat->type == PROCSTAT_CORE) { 988 return (procstat_get_pts_info_sysctl(fst, pts, errbuf)); 989 } else { 990 warnx("unknown access method: %d", procstat->type); 991 if (errbuf != NULL) 992 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 993 return (1); 994 } 995 } 996 997 static int 998 procstat_get_pts_info_kvm(kvm_t *kd, struct filestat *fst, 999 struct ptsstat *pts, char *errbuf) 1000 { 1001 struct tty tty; 1002 void *ttyp; 1003 1004 assert(kd); 1005 assert(pts); 1006 assert(fst); 1007 bzero(pts, sizeof(*pts)); 1008 ttyp = fst->fs_typedep; 1009 if (ttyp == NULL) 1010 goto fail; 1011 if (!kvm_read_all(kd, (unsigned long)ttyp, &tty, sizeof(struct tty))) { 1012 warnx("can't read tty at %p", (void *)ttyp); 1013 goto fail; 1014 } 1015 pts->dev = dev2udev(kd, tty.t_dev); 1016 (void)kdevtoname(kd, tty.t_dev, pts->devname); 1017 return (0); 1018 1019 fail: 1020 if (errbuf != NULL) 1021 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1022 return (1); 1023 } 1024 1025 static int 1026 procstat_get_pts_info_sysctl(struct filestat *fst, struct ptsstat *pts, 1027 char *errbuf __unused) 1028 { 1029 struct kinfo_file *kif; 1030 1031 assert(pts); 1032 assert(fst); 1033 bzero(pts, sizeof(*pts)); 1034 kif = fst->fs_typedep; 1035 if (kif == NULL) 1036 return (0); 1037 pts->dev = kif->kf_un.kf_pts.kf_pts_dev; 1038 strlcpy(pts->devname, kif->kf_path, sizeof(pts->devname)); 1039 return (0); 1040 } 1041 1042 int 1043 procstat_get_sem_info(struct procstat *procstat, struct filestat *fst, 1044 struct semstat *sem, char *errbuf) 1045 { 1046 1047 assert(sem); 1048 if (procstat->type == PROCSTAT_KVM) { 1049 return (procstat_get_sem_info_kvm(procstat->kd, fst, sem, 1050 errbuf)); 1051 } else if (procstat->type == PROCSTAT_SYSCTL || 1052 procstat->type == PROCSTAT_CORE) { 1053 return (procstat_get_sem_info_sysctl(fst, sem, errbuf)); 1054 } else { 1055 warnx("unknown access method: %d", procstat->type); 1056 if (errbuf != NULL) 1057 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1058 return (1); 1059 } 1060 } 1061 1062 static int 1063 procstat_get_sem_info_kvm(kvm_t *kd, struct filestat *fst, 1064 struct semstat *sem, char *errbuf) 1065 { 1066 struct ksem ksem; 1067 void *ksemp; 1068 char *path; 1069 int i; 1070 1071 assert(kd); 1072 assert(sem); 1073 assert(fst); 1074 bzero(sem, sizeof(*sem)); 1075 ksemp = fst->fs_typedep; 1076 if (ksemp == NULL) 1077 goto fail; 1078 if (!kvm_read_all(kd, (unsigned long)ksemp, &ksem, 1079 sizeof(struct ksem))) { 1080 warnx("can't read ksem at %p", (void *)ksemp); 1081 goto fail; 1082 } 1083 sem->mode = S_IFREG | ksem.ks_mode; 1084 sem->value = ksem.ks_value; 1085 if (fst->fs_path == NULL && ksem.ks_path != NULL) { 1086 path = malloc(MAXPATHLEN); 1087 for (i = 0; i < MAXPATHLEN - 1; i++) { 1088 if (!kvm_read_all(kd, (unsigned long)ksem.ks_path + i, 1089 path + i, 1)) 1090 break; 1091 if (path[i] == '\0') 1092 break; 1093 } 1094 path[i] = '\0'; 1095 if (i == 0) 1096 free(path); 1097 else 1098 fst->fs_path = path; 1099 } 1100 return (0); 1101 1102 fail: 1103 if (errbuf != NULL) 1104 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1105 return (1); 1106 } 1107 1108 static int 1109 procstat_get_sem_info_sysctl(struct filestat *fst, struct semstat *sem, 1110 char *errbuf __unused) 1111 { 1112 struct kinfo_file *kif; 1113 1114 assert(sem); 1115 assert(fst); 1116 bzero(sem, sizeof(*sem)); 1117 kif = fst->fs_typedep; 1118 if (kif == NULL) 1119 return (0); 1120 sem->value = kif->kf_un.kf_sem.kf_sem_value; 1121 sem->mode = kif->kf_un.kf_sem.kf_sem_mode; 1122 return (0); 1123 } 1124 1125 int 1126 procstat_get_shm_info(struct procstat *procstat, struct filestat *fst, 1127 struct shmstat *shm, char *errbuf) 1128 { 1129 1130 assert(shm); 1131 if (procstat->type == PROCSTAT_KVM) { 1132 return (procstat_get_shm_info_kvm(procstat->kd, fst, shm, 1133 errbuf)); 1134 } else if (procstat->type == PROCSTAT_SYSCTL || 1135 procstat->type == PROCSTAT_CORE) { 1136 return (procstat_get_shm_info_sysctl(fst, shm, errbuf)); 1137 } else { 1138 warnx("unknown access method: %d", procstat->type); 1139 if (errbuf != NULL) 1140 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1141 return (1); 1142 } 1143 } 1144 1145 static int 1146 procstat_get_shm_info_kvm(kvm_t *kd, struct filestat *fst, 1147 struct shmstat *shm, char *errbuf) 1148 { 1149 struct shmfd shmfd; 1150 void *shmfdp; 1151 char *path; 1152 int i; 1153 1154 assert(kd); 1155 assert(shm); 1156 assert(fst); 1157 bzero(shm, sizeof(*shm)); 1158 shmfdp = fst->fs_typedep; 1159 if (shmfdp == NULL) 1160 goto fail; 1161 if (!kvm_read_all(kd, (unsigned long)shmfdp, &shmfd, 1162 sizeof(struct shmfd))) { 1163 warnx("can't read shmfd at %p", (void *)shmfdp); 1164 goto fail; 1165 } 1166 shm->mode = S_IFREG | shmfd.shm_mode; 1167 shm->size = shmfd.shm_size; 1168 if (fst->fs_path == NULL && shmfd.shm_path != NULL) { 1169 path = malloc(MAXPATHLEN); 1170 for (i = 0; i < MAXPATHLEN - 1; i++) { 1171 if (!kvm_read_all(kd, (unsigned long)shmfd.shm_path + i, 1172 path + i, 1)) 1173 break; 1174 if (path[i] == '\0') 1175 break; 1176 } 1177 path[i] = '\0'; 1178 if (i == 0) 1179 free(path); 1180 else 1181 fst->fs_path = path; 1182 } 1183 return (0); 1184 1185 fail: 1186 if (errbuf != NULL) 1187 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1188 return (1); 1189 } 1190 1191 static int 1192 procstat_get_shm_info_sysctl(struct filestat *fst, struct shmstat *shm, 1193 char *errbuf __unused) 1194 { 1195 struct kinfo_file *kif; 1196 1197 assert(shm); 1198 assert(fst); 1199 bzero(shm, sizeof(*shm)); 1200 kif = fst->fs_typedep; 1201 if (kif == NULL) 1202 return (0); 1203 shm->size = kif->kf_un.kf_file.kf_file_size; 1204 shm->mode = kif->kf_un.kf_file.kf_file_mode; 1205 return (0); 1206 } 1207 1208 int 1209 procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst, 1210 struct vnstat *vn, char *errbuf) 1211 { 1212 1213 assert(vn); 1214 if (procstat->type == PROCSTAT_KVM) { 1215 return (procstat_get_vnode_info_kvm(procstat->kd, fst, vn, 1216 errbuf)); 1217 } else if (procstat->type == PROCSTAT_SYSCTL || 1218 procstat->type == PROCSTAT_CORE) { 1219 return (procstat_get_vnode_info_sysctl(fst, vn, errbuf)); 1220 } else { 1221 warnx("unknown access method: %d", procstat->type); 1222 if (errbuf != NULL) 1223 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1224 return (1); 1225 } 1226 } 1227 1228 static int 1229 procstat_get_vnode_info_kvm(kvm_t *kd, struct filestat *fst, 1230 struct vnstat *vn, char *errbuf) 1231 { 1232 /* Filesystem specific handlers. */ 1233 #define FSTYPE(fst) {#fst, fst##_filestat} 1234 struct { 1235 const char *tag; 1236 int (*handler)(kvm_t *kd, struct vnode *vp, 1237 struct vnstat *vn); 1238 } fstypes[] = { 1239 FSTYPE(devfs), 1240 FSTYPE(isofs), 1241 FSTYPE(msdosfs), 1242 FSTYPE(nfs), 1243 FSTYPE(smbfs), 1244 FSTYPE(udf), 1245 FSTYPE(ufs), 1246 #ifdef LIBPROCSTAT_ZFS 1247 FSTYPE(zfs), 1248 #endif 1249 }; 1250 #define NTYPES (sizeof(fstypes) / sizeof(*fstypes)) 1251 struct vnode vnode; 1252 char tagstr[12]; 1253 void *vp; 1254 int error; 1255 unsigned int i; 1256 1257 assert(kd); 1258 assert(vn); 1259 assert(fst); 1260 vp = fst->fs_typedep; 1261 if (vp == NULL) 1262 goto fail; 1263 error = kvm_read_all(kd, (unsigned long)vp, &vnode, sizeof(vnode)); 1264 if (error == 0) { 1265 warnx("can't read vnode at %p", (void *)vp); 1266 goto fail; 1267 } 1268 bzero(vn, sizeof(*vn)); 1269 vn->vn_type = vntype2psfsttype(vnode.v_type); 1270 if (vnode.v_type == VNON || vnode.v_type == VBAD) 1271 return (0); 1272 error = kvm_read_all(kd, (unsigned long)vnode.v_tag, tagstr, 1273 sizeof(tagstr)); 1274 if (error == 0) { 1275 warnx("can't read v_tag at %p", (void *)vp); 1276 goto fail; 1277 } 1278 tagstr[sizeof(tagstr) - 1] = '\0'; 1279 1280 /* 1281 * Find appropriate handler. 1282 */ 1283 for (i = 0; i < NTYPES; i++) 1284 if (!strcmp(fstypes[i].tag, tagstr)) { 1285 if (fstypes[i].handler(kd, &vnode, vn) != 0) { 1286 goto fail; 1287 } 1288 break; 1289 } 1290 if (i == NTYPES) { 1291 if (errbuf != NULL) 1292 snprintf(errbuf, _POSIX2_LINE_MAX, "?(%s)", tagstr); 1293 return (1); 1294 } 1295 vn->vn_mntdir = getmnton(kd, vnode.v_mount); 1296 if ((vnode.v_type == VBLK || vnode.v_type == VCHR) && 1297 vnode.v_rdev != NULL){ 1298 vn->vn_dev = dev2udev(kd, vnode.v_rdev); 1299 (void)kdevtoname(kd, vnode.v_rdev, vn->vn_devname); 1300 } else { 1301 vn->vn_dev = -1; 1302 } 1303 return (0); 1304 1305 fail: 1306 if (errbuf != NULL) 1307 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1308 return (1); 1309 } 1310 1311 /* 1312 * kinfo vnode type to filestat translation. 1313 */ 1314 static int 1315 kinfo_vtype2fst(int kfvtype) 1316 { 1317 static struct { 1318 int kf_vtype; 1319 int fst_vtype; 1320 } kfvtypes2fst[] = { 1321 { KF_VTYPE_VBAD, PS_FST_VTYPE_VBAD }, 1322 { KF_VTYPE_VBLK, PS_FST_VTYPE_VBLK }, 1323 { KF_VTYPE_VCHR, PS_FST_VTYPE_VCHR }, 1324 { KF_VTYPE_VDIR, PS_FST_VTYPE_VDIR }, 1325 { KF_VTYPE_VFIFO, PS_FST_VTYPE_VFIFO }, 1326 { KF_VTYPE_VLNK, PS_FST_VTYPE_VLNK }, 1327 { KF_VTYPE_VNON, PS_FST_VTYPE_VNON }, 1328 { KF_VTYPE_VREG, PS_FST_VTYPE_VREG }, 1329 { KF_VTYPE_VSOCK, PS_FST_VTYPE_VSOCK } 1330 }; 1331 #define NKFVTYPES (sizeof(kfvtypes2fst) / sizeof(*kfvtypes2fst)) 1332 unsigned int i; 1333 1334 for (i = 0; i < NKFVTYPES; i++) 1335 if (kfvtypes2fst[i].kf_vtype == kfvtype) 1336 break; 1337 if (i == NKFVTYPES) 1338 return (PS_FST_VTYPE_UNKNOWN); 1339 return (kfvtypes2fst[i].fst_vtype); 1340 } 1341 1342 static int 1343 procstat_get_vnode_info_sysctl(struct filestat *fst, struct vnstat *vn, 1344 char *errbuf) 1345 { 1346 struct statfs stbuf; 1347 struct kinfo_file *kif; 1348 struct kinfo_vmentry *kve; 1349 char *name, *path; 1350 uint64_t fileid; 1351 uint64_t size; 1352 uint64_t fsid; 1353 uint64_t rdev; 1354 uint16_t mode; 1355 int vntype; 1356 int status; 1357 1358 assert(fst); 1359 assert(vn); 1360 bzero(vn, sizeof(*vn)); 1361 if (fst->fs_typedep == NULL) 1362 return (1); 1363 if (fst->fs_uflags & PS_FST_UFLAG_MMAP) { 1364 kve = fst->fs_typedep; 1365 fileid = kve->kve_vn_fileid; 1366 fsid = kve->kve_vn_fsid; 1367 mode = kve->kve_vn_mode; 1368 path = kve->kve_path; 1369 rdev = kve->kve_vn_rdev; 1370 size = kve->kve_vn_size; 1371 vntype = kinfo_vtype2fst(kve->kve_vn_type); 1372 status = kve->kve_status; 1373 } else { 1374 kif = fst->fs_typedep; 1375 fileid = kif->kf_un.kf_file.kf_file_fileid; 1376 fsid = kif->kf_un.kf_file.kf_file_fsid; 1377 mode = kif->kf_un.kf_file.kf_file_mode; 1378 path = kif->kf_path; 1379 rdev = kif->kf_un.kf_file.kf_file_rdev; 1380 size = kif->kf_un.kf_file.kf_file_size; 1381 vntype = kinfo_vtype2fst(kif->kf_vnode_type); 1382 status = kif->kf_status; 1383 } 1384 vn->vn_type = vntype; 1385 if (vntype == PS_FST_VTYPE_VNON || vntype == PS_FST_VTYPE_VBAD) 1386 return (0); 1387 if ((status & KF_ATTR_VALID) == 0) { 1388 if (errbuf != NULL) { 1389 snprintf(errbuf, _POSIX2_LINE_MAX, 1390 "? (no info available)"); 1391 } 1392 return (1); 1393 } 1394 if (path && *path) { 1395 statfs(path, &stbuf); 1396 vn->vn_mntdir = strdup(stbuf.f_mntonname); 1397 } else 1398 vn->vn_mntdir = strdup("-"); 1399 vn->vn_dev = rdev; 1400 if (vntype == PS_FST_VTYPE_VBLK) { 1401 name = devname(rdev, S_IFBLK); 1402 if (name != NULL) 1403 strlcpy(vn->vn_devname, name, 1404 sizeof(vn->vn_devname)); 1405 } else if (vntype == PS_FST_VTYPE_VCHR) { 1406 name = devname(vn->vn_dev, S_IFCHR); 1407 if (name != NULL) 1408 strlcpy(vn->vn_devname, name, 1409 sizeof(vn->vn_devname)); 1410 } 1411 vn->vn_fsid = fsid; 1412 vn->vn_fileid = fileid; 1413 vn->vn_size = size; 1414 vn->vn_mode = mode; 1415 return (0); 1416 } 1417 1418 int 1419 procstat_get_socket_info(struct procstat *procstat, struct filestat *fst, 1420 struct sockstat *sock, char *errbuf) 1421 { 1422 1423 assert(sock); 1424 if (procstat->type == PROCSTAT_KVM) { 1425 return (procstat_get_socket_info_kvm(procstat->kd, fst, sock, 1426 errbuf)); 1427 } else if (procstat->type == PROCSTAT_SYSCTL || 1428 procstat->type == PROCSTAT_CORE) { 1429 return (procstat_get_socket_info_sysctl(fst, sock, errbuf)); 1430 } else { 1431 warnx("unknown access method: %d", procstat->type); 1432 if (errbuf != NULL) 1433 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1434 return (1); 1435 } 1436 } 1437 1438 static int 1439 procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst, 1440 struct sockstat *sock, char *errbuf) 1441 { 1442 struct domain dom; 1443 struct inpcb inpcb; 1444 struct protosw proto; 1445 struct socket s; 1446 struct unpcb unpcb; 1447 ssize_t len; 1448 void *so; 1449 1450 assert(kd); 1451 assert(sock); 1452 assert(fst); 1453 bzero(sock, sizeof(*sock)); 1454 so = fst->fs_typedep; 1455 if (so == NULL) 1456 goto fail; 1457 sock->so_addr = (uintptr_t)so; 1458 /* fill in socket */ 1459 if (!kvm_read_all(kd, (unsigned long)so, &s, 1460 sizeof(struct socket))) { 1461 warnx("can't read sock at %p", (void *)so); 1462 goto fail; 1463 } 1464 /* fill in protosw entry */ 1465 if (!kvm_read_all(kd, (unsigned long)s.so_proto, &proto, 1466 sizeof(struct protosw))) { 1467 warnx("can't read protosw at %p", (void *)s.so_proto); 1468 goto fail; 1469 } 1470 /* fill in domain */ 1471 if (!kvm_read_all(kd, (unsigned long)proto.pr_domain, &dom, 1472 sizeof(struct domain))) { 1473 warnx("can't read domain at %p", 1474 (void *)proto.pr_domain); 1475 goto fail; 1476 } 1477 if ((len = kvm_read(kd, (unsigned long)dom.dom_name, sock->dname, 1478 sizeof(sock->dname) - 1)) < 0) { 1479 warnx("can't read domain name at %p", (void *)dom.dom_name); 1480 sock->dname[0] = '\0'; 1481 } 1482 else 1483 sock->dname[len] = '\0'; 1484 1485 /* 1486 * Fill in known data. 1487 */ 1488 sock->type = s.so_type; 1489 sock->proto = proto.pr_protocol; 1490 sock->dom_family = dom.dom_family; 1491 sock->so_pcb = (uintptr_t)s.so_pcb; 1492 1493 /* 1494 * Protocol specific data. 1495 */ 1496 switch(dom.dom_family) { 1497 case AF_INET: 1498 case AF_INET6: 1499 if (proto.pr_protocol == IPPROTO_TCP) { 1500 if (s.so_pcb) { 1501 if (kvm_read(kd, (u_long)s.so_pcb, 1502 (char *)&inpcb, sizeof(struct inpcb)) 1503 != sizeof(struct inpcb)) { 1504 warnx("can't read inpcb at %p", 1505 (void *)s.so_pcb); 1506 } else 1507 sock->inp_ppcb = 1508 (uintptr_t)inpcb.inp_ppcb; 1509 sock->sendq = s.so_snd.sb_ccc; 1510 sock->recvq = s.so_rcv.sb_ccc; 1511 } 1512 } 1513 break; 1514 case AF_UNIX: 1515 if (s.so_pcb) { 1516 if (kvm_read(kd, (u_long)s.so_pcb, (char *)&unpcb, 1517 sizeof(struct unpcb)) != sizeof(struct unpcb)){ 1518 warnx("can't read unpcb at %p", 1519 (void *)s.so_pcb); 1520 } else if (unpcb.unp_conn) { 1521 sock->so_rcv_sb_state = s.so_rcv.sb_state; 1522 sock->so_snd_sb_state = s.so_snd.sb_state; 1523 sock->unp_conn = (uintptr_t)unpcb.unp_conn; 1524 sock->sendq = s.so_snd.sb_ccc; 1525 sock->recvq = s.so_rcv.sb_ccc; 1526 } 1527 } 1528 break; 1529 default: 1530 break; 1531 } 1532 return (0); 1533 1534 fail: 1535 if (errbuf != NULL) 1536 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1537 return (1); 1538 } 1539 1540 static int 1541 procstat_get_socket_info_sysctl(struct filestat *fst, struct sockstat *sock, 1542 char *errbuf __unused) 1543 { 1544 struct kinfo_file *kif; 1545 1546 assert(sock); 1547 assert(fst); 1548 bzero(sock, sizeof(*sock)); 1549 kif = fst->fs_typedep; 1550 if (kif == NULL) 1551 return (0); 1552 1553 /* 1554 * Fill in known data. 1555 */ 1556 sock->type = kif->kf_sock_type; 1557 sock->proto = kif->kf_sock_protocol; 1558 sock->dom_family = kif->kf_sock_domain; 1559 sock->so_pcb = kif->kf_un.kf_sock.kf_sock_pcb; 1560 strlcpy(sock->dname, kif->kf_path, sizeof(sock->dname)); 1561 bcopy(&kif->kf_un.kf_sock.kf_sa_local, &sock->sa_local, 1562 kif->kf_un.kf_sock.kf_sa_local.ss_len); 1563 bcopy(&kif->kf_un.kf_sock.kf_sa_peer, &sock->sa_peer, 1564 kif->kf_un.kf_sock.kf_sa_peer.ss_len); 1565 1566 /* 1567 * Protocol specific data. 1568 */ 1569 switch(sock->dom_family) { 1570 case AF_INET: 1571 case AF_INET6: 1572 if (sock->proto == IPPROTO_TCP) { 1573 sock->inp_ppcb = kif->kf_un.kf_sock.kf_sock_inpcb; 1574 sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq; 1575 sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq; 1576 } 1577 break; 1578 case AF_UNIX: 1579 if (kif->kf_un.kf_sock.kf_sock_unpconn != 0) { 1580 sock->so_rcv_sb_state = 1581 kif->kf_un.kf_sock.kf_sock_rcv_sb_state; 1582 sock->so_snd_sb_state = 1583 kif->kf_un.kf_sock.kf_sock_snd_sb_state; 1584 sock->unp_conn = 1585 kif->kf_un.kf_sock.kf_sock_unpconn; 1586 sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq; 1587 sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq; 1588 } 1589 break; 1590 default: 1591 break; 1592 } 1593 return (0); 1594 } 1595 1596 /* 1597 * Descriptor flags to filestat translation. 1598 */ 1599 static int 1600 to_filestat_flags(int flags) 1601 { 1602 static struct { 1603 int flag; 1604 int fst_flag; 1605 } fstflags[] = { 1606 { FREAD, PS_FST_FFLAG_READ }, 1607 { FWRITE, PS_FST_FFLAG_WRITE }, 1608 { O_APPEND, PS_FST_FFLAG_APPEND }, 1609 { O_ASYNC, PS_FST_FFLAG_ASYNC }, 1610 { O_CREAT, PS_FST_FFLAG_CREAT }, 1611 { O_DIRECT, PS_FST_FFLAG_DIRECT }, 1612 { O_EXCL, PS_FST_FFLAG_EXCL }, 1613 { O_EXEC, PS_FST_FFLAG_EXEC }, 1614 { O_EXLOCK, PS_FST_FFLAG_EXLOCK }, 1615 { O_NOFOLLOW, PS_FST_FFLAG_NOFOLLOW }, 1616 { O_NONBLOCK, PS_FST_FFLAG_NONBLOCK }, 1617 { O_SHLOCK, PS_FST_FFLAG_SHLOCK }, 1618 { O_SYNC, PS_FST_FFLAG_SYNC }, 1619 { O_TRUNC, PS_FST_FFLAG_TRUNC } 1620 }; 1621 #define NFSTFLAGS (sizeof(fstflags) / sizeof(*fstflags)) 1622 int fst_flags; 1623 unsigned int i; 1624 1625 fst_flags = 0; 1626 for (i = 0; i < NFSTFLAGS; i++) 1627 if (flags & fstflags[i].flag) 1628 fst_flags |= fstflags[i].fst_flag; 1629 return (fst_flags); 1630 } 1631 1632 /* 1633 * Vnode type to filestate translation. 1634 */ 1635 static int 1636 vntype2psfsttype(int type) 1637 { 1638 static struct { 1639 int vtype; 1640 int fst_vtype; 1641 } vt2fst[] = { 1642 { VBAD, PS_FST_VTYPE_VBAD }, 1643 { VBLK, PS_FST_VTYPE_VBLK }, 1644 { VCHR, PS_FST_VTYPE_VCHR }, 1645 { VDIR, PS_FST_VTYPE_VDIR }, 1646 { VFIFO, PS_FST_VTYPE_VFIFO }, 1647 { VLNK, PS_FST_VTYPE_VLNK }, 1648 { VNON, PS_FST_VTYPE_VNON }, 1649 { VREG, PS_FST_VTYPE_VREG }, 1650 { VSOCK, PS_FST_VTYPE_VSOCK } 1651 }; 1652 #define NVFTYPES (sizeof(vt2fst) / sizeof(*vt2fst)) 1653 unsigned int i, fst_type; 1654 1655 fst_type = PS_FST_VTYPE_UNKNOWN; 1656 for (i = 0; i < NVFTYPES; i++) { 1657 if (type == vt2fst[i].vtype) { 1658 fst_type = vt2fst[i].fst_vtype; 1659 break; 1660 } 1661 } 1662 return (fst_type); 1663 } 1664 1665 static char * 1666 getmnton(kvm_t *kd, struct mount *m) 1667 { 1668 struct mount mnt; 1669 static struct mtab { 1670 struct mtab *next; 1671 struct mount *m; 1672 char mntonname[MNAMELEN + 1]; 1673 } *mhead = NULL; 1674 struct mtab *mt; 1675 1676 for (mt = mhead; mt != NULL; mt = mt->next) 1677 if (m == mt->m) 1678 return (mt->mntonname); 1679 if (!kvm_read_all(kd, (unsigned long)m, &mnt, sizeof(struct mount))) { 1680 warnx("can't read mount table at %p", (void *)m); 1681 return (NULL); 1682 } 1683 if ((mt = malloc(sizeof (struct mtab))) == NULL) 1684 err(1, NULL); 1685 mt->m = m; 1686 bcopy(&mnt.mnt_stat.f_mntonname[0], &mt->mntonname[0], MNAMELEN); 1687 mt->mntonname[MNAMELEN] = '\0'; 1688 mt->next = mhead; 1689 mhead = mt; 1690 return (mt->mntonname); 1691 } 1692 1693 /* 1694 * Auxiliary structures and functions to get process environment or 1695 * command line arguments. 1696 */ 1697 struct argvec { 1698 char *buf; 1699 size_t bufsize; 1700 char **argv; 1701 size_t argc; 1702 }; 1703 1704 static struct argvec * 1705 argvec_alloc(size_t bufsize) 1706 { 1707 struct argvec *av; 1708 1709 av = malloc(sizeof(*av)); 1710 if (av == NULL) 1711 return (NULL); 1712 av->bufsize = bufsize; 1713 av->buf = malloc(av->bufsize); 1714 if (av->buf == NULL) { 1715 free(av); 1716 return (NULL); 1717 } 1718 av->argc = 32; 1719 av->argv = malloc(sizeof(char *) * av->argc); 1720 if (av->argv == NULL) { 1721 free(av->buf); 1722 free(av); 1723 return (NULL); 1724 } 1725 return av; 1726 } 1727 1728 static void 1729 argvec_free(struct argvec * av) 1730 { 1731 1732 free(av->argv); 1733 free(av->buf); 1734 free(av); 1735 } 1736 1737 static char ** 1738 getargv(struct procstat *procstat, struct kinfo_proc *kp, size_t nchr, int env) 1739 { 1740 int error, name[4], argc, i; 1741 struct argvec *av, **avp; 1742 enum psc_type type; 1743 size_t len; 1744 char *p, **argv; 1745 1746 assert(procstat); 1747 assert(kp); 1748 if (procstat->type == PROCSTAT_KVM) { 1749 warnx("can't use kvm access method"); 1750 return (NULL); 1751 } 1752 if (procstat->type != PROCSTAT_SYSCTL && 1753 procstat->type != PROCSTAT_CORE) { 1754 warnx("unknown access method: %d", procstat->type); 1755 return (NULL); 1756 } 1757 1758 if (nchr == 0 || nchr > ARG_MAX) 1759 nchr = ARG_MAX; 1760 1761 avp = (struct argvec **)(env ? &procstat->argv : &procstat->envv); 1762 av = *avp; 1763 1764 if (av == NULL) 1765 { 1766 av = argvec_alloc(nchr); 1767 if (av == NULL) 1768 { 1769 warn("malloc(%zu)", nchr); 1770 return (NULL); 1771 } 1772 *avp = av; 1773 } else if (av->bufsize < nchr) { 1774 av->buf = reallocf(av->buf, nchr); 1775 if (av->buf == NULL) { 1776 warn("malloc(%zu)", nchr); 1777 return (NULL); 1778 } 1779 } 1780 if (procstat->type == PROCSTAT_SYSCTL) { 1781 name[0] = CTL_KERN; 1782 name[1] = KERN_PROC; 1783 name[2] = env ? KERN_PROC_ENV : KERN_PROC_ARGS; 1784 name[3] = kp->ki_pid; 1785 len = nchr; 1786 error = sysctl(name, nitems(name), av->buf, &len, NULL, 0); 1787 if (error != 0 && errno != ESRCH && errno != EPERM) 1788 warn("sysctl(kern.proc.%s)", env ? "env" : "args"); 1789 if (error != 0 || len == 0) 1790 return (NULL); 1791 } else /* procstat->type == PROCSTAT_CORE */ { 1792 type = env ? PSC_TYPE_ENVV : PSC_TYPE_ARGV; 1793 len = nchr; 1794 if (procstat_core_get(procstat->core, type, av->buf, &len) 1795 == NULL) { 1796 return (NULL); 1797 } 1798 } 1799 1800 argv = av->argv; 1801 argc = av->argc; 1802 i = 0; 1803 for (p = av->buf; p < av->buf + len; p += strlen(p) + 1) { 1804 argv[i++] = p; 1805 if (i < argc) 1806 continue; 1807 /* Grow argv. */ 1808 argc += argc; 1809 argv = realloc(argv, sizeof(char *) * argc); 1810 if (argv == NULL) { 1811 warn("malloc(%zu)", sizeof(char *) * argc); 1812 return (NULL); 1813 } 1814 av->argv = argv; 1815 av->argc = argc; 1816 } 1817 argv[i] = NULL; 1818 1819 return (argv); 1820 } 1821 1822 /* 1823 * Return process command line arguments. 1824 */ 1825 char ** 1826 procstat_getargv(struct procstat *procstat, struct kinfo_proc *p, size_t nchr) 1827 { 1828 1829 return (getargv(procstat, p, nchr, 0)); 1830 } 1831 1832 /* 1833 * Free the buffer allocated by procstat_getargv(). 1834 */ 1835 void 1836 procstat_freeargv(struct procstat *procstat) 1837 { 1838 1839 if (procstat->argv != NULL) { 1840 argvec_free(procstat->argv); 1841 procstat->argv = NULL; 1842 } 1843 } 1844 1845 /* 1846 * Return process environment. 1847 */ 1848 char ** 1849 procstat_getenvv(struct procstat *procstat, struct kinfo_proc *p, size_t nchr) 1850 { 1851 1852 return (getargv(procstat, p, nchr, 1)); 1853 } 1854 1855 /* 1856 * Free the buffer allocated by procstat_getenvv(). 1857 */ 1858 void 1859 procstat_freeenvv(struct procstat *procstat) 1860 { 1861 if (procstat->envv != NULL) { 1862 argvec_free(procstat->envv); 1863 procstat->envv = NULL; 1864 } 1865 } 1866 1867 static struct kinfo_vmentry * 1868 kinfo_getvmmap_core(struct procstat_core *core, int *cntp) 1869 { 1870 int cnt; 1871 size_t len; 1872 char *buf, *bp, *eb; 1873 struct kinfo_vmentry *kiv, *kp, *kv; 1874 1875 buf = procstat_core_get(core, PSC_TYPE_VMMAP, NULL, &len); 1876 if (buf == NULL) 1877 return (NULL); 1878 1879 /* 1880 * XXXMG: The code below is just copy&past from libutil. 1881 * The code duplication can be avoided if libutil 1882 * is extended to provide something like: 1883 * struct kinfo_vmentry *kinfo_getvmmap_from_buf(const char *buf, 1884 * size_t len, int *cntp); 1885 */ 1886 1887 /* Pass 1: count items */ 1888 cnt = 0; 1889 bp = buf; 1890 eb = buf + len; 1891 while (bp < eb) { 1892 kv = (struct kinfo_vmentry *)(uintptr_t)bp; 1893 if (kv->kve_structsize == 0) 1894 break; 1895 bp += kv->kve_structsize; 1896 cnt++; 1897 } 1898 1899 kiv = calloc(cnt, sizeof(*kiv)); 1900 if (kiv == NULL) { 1901 free(buf); 1902 return (NULL); 1903 } 1904 bp = buf; 1905 eb = buf + len; 1906 kp = kiv; 1907 /* Pass 2: unpack */ 1908 while (bp < eb) { 1909 kv = (struct kinfo_vmentry *)(uintptr_t)bp; 1910 if (kv->kve_structsize == 0) 1911 break; 1912 /* Copy/expand into pre-zeroed buffer */ 1913 memcpy(kp, kv, kv->kve_structsize); 1914 /* Advance to next packed record */ 1915 bp += kv->kve_structsize; 1916 /* Set field size to fixed length, advance */ 1917 kp->kve_structsize = sizeof(*kp); 1918 kp++; 1919 } 1920 free(buf); 1921 *cntp = cnt; 1922 return (kiv); /* Caller must free() return value */ 1923 } 1924 1925 struct kinfo_vmentry * 1926 procstat_getvmmap(struct procstat *procstat, struct kinfo_proc *kp, 1927 unsigned int *cntp) 1928 { 1929 1930 switch(procstat->type) { 1931 case PROCSTAT_KVM: 1932 warnx("kvm method is not supported"); 1933 return (NULL); 1934 case PROCSTAT_SYSCTL: 1935 return (kinfo_getvmmap(kp->ki_pid, cntp)); 1936 case PROCSTAT_CORE: 1937 return (kinfo_getvmmap_core(procstat->core, cntp)); 1938 default: 1939 warnx("unknown access method: %d", procstat->type); 1940 return (NULL); 1941 } 1942 } 1943 1944 void 1945 procstat_freevmmap(struct procstat *procstat __unused, 1946 struct kinfo_vmentry *vmmap) 1947 { 1948 1949 free(vmmap); 1950 } 1951 1952 static gid_t * 1953 procstat_getgroups_kvm(kvm_t *kd, struct kinfo_proc *kp, unsigned int *cntp) 1954 { 1955 struct proc proc; 1956 struct ucred ucred; 1957 gid_t *groups; 1958 size_t len; 1959 1960 assert(kd != NULL); 1961 assert(kp != NULL); 1962 if (!kvm_read_all(kd, (unsigned long)kp->ki_paddr, &proc, 1963 sizeof(proc))) { 1964 warnx("can't read proc struct at %p for pid %d", 1965 kp->ki_paddr, kp->ki_pid); 1966 return (NULL); 1967 } 1968 if (proc.p_ucred == NOCRED) 1969 return (NULL); 1970 if (!kvm_read_all(kd, (unsigned long)proc.p_ucred, &ucred, 1971 sizeof(ucred))) { 1972 warnx("can't read ucred struct at %p for pid %d", 1973 proc.p_ucred, kp->ki_pid); 1974 return (NULL); 1975 } 1976 len = ucred.cr_ngroups * sizeof(gid_t); 1977 groups = malloc(len); 1978 if (groups == NULL) { 1979 warn("malloc(%zu)", len); 1980 return (NULL); 1981 } 1982 if (!kvm_read_all(kd, (unsigned long)ucred.cr_groups, groups, len)) { 1983 warnx("can't read groups at %p for pid %d", 1984 ucred.cr_groups, kp->ki_pid); 1985 free(groups); 1986 return (NULL); 1987 } 1988 *cntp = ucred.cr_ngroups; 1989 return (groups); 1990 } 1991 1992 static gid_t * 1993 procstat_getgroups_sysctl(pid_t pid, unsigned int *cntp) 1994 { 1995 int mib[4]; 1996 size_t len; 1997 gid_t *groups; 1998 1999 mib[0] = CTL_KERN; 2000 mib[1] = KERN_PROC; 2001 mib[2] = KERN_PROC_GROUPS; 2002 mib[3] = pid; 2003 len = (sysconf(_SC_NGROUPS_MAX) + 1) * sizeof(gid_t); 2004 groups = malloc(len); 2005 if (groups == NULL) { 2006 warn("malloc(%zu)", len); 2007 return (NULL); 2008 } 2009 if (sysctl(mib, nitems(mib), groups, &len, NULL, 0) == -1) { 2010 warn("sysctl: kern.proc.groups: %d", pid); 2011 free(groups); 2012 return (NULL); 2013 } 2014 *cntp = len / sizeof(gid_t); 2015 return (groups); 2016 } 2017 2018 static gid_t * 2019 procstat_getgroups_core(struct procstat_core *core, unsigned int *cntp) 2020 { 2021 size_t len; 2022 gid_t *groups; 2023 2024 groups = procstat_core_get(core, PSC_TYPE_GROUPS, NULL, &len); 2025 if (groups == NULL) 2026 return (NULL); 2027 *cntp = len / sizeof(gid_t); 2028 return (groups); 2029 } 2030 2031 gid_t * 2032 procstat_getgroups(struct procstat *procstat, struct kinfo_proc *kp, 2033 unsigned int *cntp) 2034 { 2035 switch(procstat->type) { 2036 case PROCSTAT_KVM: 2037 return (procstat_getgroups_kvm(procstat->kd, kp, cntp)); 2038 case PROCSTAT_SYSCTL: 2039 return (procstat_getgroups_sysctl(kp->ki_pid, cntp)); 2040 case PROCSTAT_CORE: 2041 return (procstat_getgroups_core(procstat->core, cntp)); 2042 default: 2043 warnx("unknown access method: %d", procstat->type); 2044 return (NULL); 2045 } 2046 } 2047 2048 void 2049 procstat_freegroups(struct procstat *procstat __unused, gid_t *groups) 2050 { 2051 2052 free(groups); 2053 } 2054 2055 static int 2056 procstat_getumask_kvm(kvm_t *kd, struct kinfo_proc *kp, unsigned short *maskp) 2057 { 2058 struct filedesc fd; 2059 2060 assert(kd != NULL); 2061 assert(kp != NULL); 2062 if (kp->ki_fd == NULL) 2063 return (-1); 2064 if (!kvm_read_all(kd, (unsigned long)kp->ki_fd, &fd, sizeof(fd))) { 2065 warnx("can't read filedesc at %p for pid %d", kp->ki_fd, 2066 kp->ki_pid); 2067 return (-1); 2068 } 2069 *maskp = fd.fd_cmask; 2070 return (0); 2071 } 2072 2073 static int 2074 procstat_getumask_sysctl(pid_t pid, unsigned short *maskp) 2075 { 2076 int error; 2077 int mib[4]; 2078 size_t len; 2079 2080 mib[0] = CTL_KERN; 2081 mib[1] = KERN_PROC; 2082 mib[2] = KERN_PROC_UMASK; 2083 mib[3] = pid; 2084 len = sizeof(*maskp); 2085 error = sysctl(mib, nitems(mib), maskp, &len, NULL, 0); 2086 if (error != 0 && errno != ESRCH && errno != EPERM) 2087 warn("sysctl: kern.proc.umask: %d", pid); 2088 return (error); 2089 } 2090 2091 static int 2092 procstat_getumask_core(struct procstat_core *core, unsigned short *maskp) 2093 { 2094 size_t len; 2095 unsigned short *buf; 2096 2097 buf = procstat_core_get(core, PSC_TYPE_UMASK, NULL, &len); 2098 if (buf == NULL) 2099 return (-1); 2100 if (len < sizeof(*maskp)) { 2101 free(buf); 2102 return (-1); 2103 } 2104 *maskp = *buf; 2105 free(buf); 2106 return (0); 2107 } 2108 2109 int 2110 procstat_getumask(struct procstat *procstat, struct kinfo_proc *kp, 2111 unsigned short *maskp) 2112 { 2113 switch(procstat->type) { 2114 case PROCSTAT_KVM: 2115 return (procstat_getumask_kvm(procstat->kd, kp, maskp)); 2116 case PROCSTAT_SYSCTL: 2117 return (procstat_getumask_sysctl(kp->ki_pid, maskp)); 2118 case PROCSTAT_CORE: 2119 return (procstat_getumask_core(procstat->core, maskp)); 2120 default: 2121 warnx("unknown access method: %d", procstat->type); 2122 return (-1); 2123 } 2124 } 2125 2126 static int 2127 procstat_getrlimit_kvm(kvm_t *kd, struct kinfo_proc *kp, int which, 2128 struct rlimit* rlimit) 2129 { 2130 struct proc proc; 2131 unsigned long offset; 2132 2133 assert(kd != NULL); 2134 assert(kp != NULL); 2135 assert(which >= 0 && which < RLIM_NLIMITS); 2136 if (!kvm_read_all(kd, (unsigned long)kp->ki_paddr, &proc, 2137 sizeof(proc))) { 2138 warnx("can't read proc struct at %p for pid %d", 2139 kp->ki_paddr, kp->ki_pid); 2140 return (-1); 2141 } 2142 if (proc.p_limit == NULL) 2143 return (-1); 2144 offset = (unsigned long)proc.p_limit + sizeof(struct rlimit) * which; 2145 if (!kvm_read_all(kd, offset, rlimit, sizeof(*rlimit))) { 2146 warnx("can't read rlimit struct at %p for pid %d", 2147 (void *)offset, kp->ki_pid); 2148 return (-1); 2149 } 2150 return (0); 2151 } 2152 2153 static int 2154 procstat_getrlimit_sysctl(pid_t pid, int which, struct rlimit* rlimit) 2155 { 2156 int error, name[5]; 2157 size_t len; 2158 2159 name[0] = CTL_KERN; 2160 name[1] = KERN_PROC; 2161 name[2] = KERN_PROC_RLIMIT; 2162 name[3] = pid; 2163 name[4] = which; 2164 len = sizeof(struct rlimit); 2165 error = sysctl(name, nitems(name), rlimit, &len, NULL, 0); 2166 if (error < 0 && errno != ESRCH) { 2167 warn("sysctl: kern.proc.rlimit: %d", pid); 2168 return (-1); 2169 } 2170 if (error < 0 || len != sizeof(struct rlimit)) 2171 return (-1); 2172 return (0); 2173 } 2174 2175 static int 2176 procstat_getrlimit_core(struct procstat_core *core, int which, 2177 struct rlimit* rlimit) 2178 { 2179 size_t len; 2180 struct rlimit* rlimits; 2181 2182 if (which < 0 || which >= RLIM_NLIMITS) { 2183 errno = EINVAL; 2184 warn("getrlimit: which"); 2185 return (-1); 2186 } 2187 rlimits = procstat_core_get(core, PSC_TYPE_RLIMIT, NULL, &len); 2188 if (rlimits == NULL) 2189 return (-1); 2190 if (len < sizeof(struct rlimit) * RLIM_NLIMITS) { 2191 free(rlimits); 2192 return (-1); 2193 } 2194 *rlimit = rlimits[which]; 2195 free(rlimits); 2196 return (0); 2197 } 2198 2199 int 2200 procstat_getrlimit(struct procstat *procstat, struct kinfo_proc *kp, int which, 2201 struct rlimit* rlimit) 2202 { 2203 switch(procstat->type) { 2204 case PROCSTAT_KVM: 2205 return (procstat_getrlimit_kvm(procstat->kd, kp, which, 2206 rlimit)); 2207 case PROCSTAT_SYSCTL: 2208 return (procstat_getrlimit_sysctl(kp->ki_pid, which, rlimit)); 2209 case PROCSTAT_CORE: 2210 return (procstat_getrlimit_core(procstat->core, which, rlimit)); 2211 default: 2212 warnx("unknown access method: %d", procstat->type); 2213 return (-1); 2214 } 2215 } 2216 2217 static int 2218 procstat_getpathname_sysctl(pid_t pid, char *pathname, size_t maxlen) 2219 { 2220 int error, name[4]; 2221 size_t len; 2222 2223 name[0] = CTL_KERN; 2224 name[1] = KERN_PROC; 2225 name[2] = KERN_PROC_PATHNAME; 2226 name[3] = pid; 2227 len = maxlen; 2228 error = sysctl(name, nitems(name), pathname, &len, NULL, 0); 2229 if (error != 0 && errno != ESRCH) 2230 warn("sysctl: kern.proc.pathname: %d", pid); 2231 if (len == 0) 2232 pathname[0] = '\0'; 2233 return (error); 2234 } 2235 2236 static int 2237 procstat_getpathname_core(struct procstat_core *core, char *pathname, 2238 size_t maxlen) 2239 { 2240 struct kinfo_file *files; 2241 int cnt, i, result; 2242 2243 files = kinfo_getfile_core(core, &cnt); 2244 if (files == NULL) 2245 return (-1); 2246 result = -1; 2247 for (i = 0; i < cnt; i++) { 2248 if (files[i].kf_fd != KF_FD_TYPE_TEXT) 2249 continue; 2250 strncpy(pathname, files[i].kf_path, maxlen); 2251 result = 0; 2252 break; 2253 } 2254 free(files); 2255 return (result); 2256 } 2257 2258 int 2259 procstat_getpathname(struct procstat *procstat, struct kinfo_proc *kp, 2260 char *pathname, size_t maxlen) 2261 { 2262 switch(procstat->type) { 2263 case PROCSTAT_KVM: 2264 /* XXX: Return empty string. */ 2265 if (maxlen > 0) 2266 pathname[0] = '\0'; 2267 return (0); 2268 case PROCSTAT_SYSCTL: 2269 return (procstat_getpathname_sysctl(kp->ki_pid, pathname, 2270 maxlen)); 2271 case PROCSTAT_CORE: 2272 return (procstat_getpathname_core(procstat->core, pathname, 2273 maxlen)); 2274 default: 2275 warnx("unknown access method: %d", procstat->type); 2276 return (-1); 2277 } 2278 } 2279 2280 static int 2281 procstat_getosrel_kvm(kvm_t *kd, struct kinfo_proc *kp, int *osrelp) 2282 { 2283 struct proc proc; 2284 2285 assert(kd != NULL); 2286 assert(kp != NULL); 2287 if (!kvm_read_all(kd, (unsigned long)kp->ki_paddr, &proc, 2288 sizeof(proc))) { 2289 warnx("can't read proc struct at %p for pid %d", 2290 kp->ki_paddr, kp->ki_pid); 2291 return (-1); 2292 } 2293 *osrelp = proc.p_osrel; 2294 return (0); 2295 } 2296 2297 static int 2298 procstat_getosrel_sysctl(pid_t pid, int *osrelp) 2299 { 2300 int error, name[4]; 2301 size_t len; 2302 2303 name[0] = CTL_KERN; 2304 name[1] = KERN_PROC; 2305 name[2] = KERN_PROC_OSREL; 2306 name[3] = pid; 2307 len = sizeof(*osrelp); 2308 error = sysctl(name, nitems(name), osrelp, &len, NULL, 0); 2309 if (error != 0 && errno != ESRCH) 2310 warn("sysctl: kern.proc.osrel: %d", pid); 2311 return (error); 2312 } 2313 2314 static int 2315 procstat_getosrel_core(struct procstat_core *core, int *osrelp) 2316 { 2317 size_t len; 2318 int *buf; 2319 2320 buf = procstat_core_get(core, PSC_TYPE_OSREL, NULL, &len); 2321 if (buf == NULL) 2322 return (-1); 2323 if (len < sizeof(*osrelp)) { 2324 free(buf); 2325 return (-1); 2326 } 2327 *osrelp = *buf; 2328 free(buf); 2329 return (0); 2330 } 2331 2332 int 2333 procstat_getosrel(struct procstat *procstat, struct kinfo_proc *kp, int *osrelp) 2334 { 2335 switch(procstat->type) { 2336 case PROCSTAT_KVM: 2337 return (procstat_getosrel_kvm(procstat->kd, kp, osrelp)); 2338 case PROCSTAT_SYSCTL: 2339 return (procstat_getosrel_sysctl(kp->ki_pid, osrelp)); 2340 case PROCSTAT_CORE: 2341 return (procstat_getosrel_core(procstat->core, osrelp)); 2342 default: 2343 warnx("unknown access method: %d", procstat->type); 2344 return (-1); 2345 } 2346 } 2347 2348 #define PROC_AUXV_MAX 256 2349 2350 #if __ELF_WORD_SIZE == 64 2351 static const char *elf32_sv_names[] = { 2352 "Linux ELF32", 2353 "FreeBSD ELF32", 2354 }; 2355 2356 static int 2357 is_elf32_sysctl(pid_t pid) 2358 { 2359 int error, name[4]; 2360 size_t len, i; 2361 static char sv_name[256]; 2362 2363 name[0] = CTL_KERN; 2364 name[1] = KERN_PROC; 2365 name[2] = KERN_PROC_SV_NAME; 2366 name[3] = pid; 2367 len = sizeof(sv_name); 2368 error = sysctl(name, nitems(name), sv_name, &len, NULL, 0); 2369 if (error != 0 || len == 0) 2370 return (0); 2371 for (i = 0; i < sizeof(elf32_sv_names) / sizeof(*elf32_sv_names); i++) { 2372 if (strncmp(sv_name, elf32_sv_names[i], sizeof(sv_name)) == 0) 2373 return (1); 2374 } 2375 return (0); 2376 } 2377 2378 static Elf_Auxinfo * 2379 procstat_getauxv32_sysctl(pid_t pid, unsigned int *cntp) 2380 { 2381 Elf_Auxinfo *auxv; 2382 Elf32_Auxinfo *auxv32; 2383 void *ptr; 2384 size_t len; 2385 unsigned int i, count; 2386 int name[4]; 2387 2388 name[0] = CTL_KERN; 2389 name[1] = KERN_PROC; 2390 name[2] = KERN_PROC_AUXV; 2391 name[3] = pid; 2392 len = PROC_AUXV_MAX * sizeof(Elf32_Auxinfo); 2393 auxv = NULL; 2394 auxv32 = malloc(len); 2395 if (auxv32 == NULL) { 2396 warn("malloc(%zu)", len); 2397 goto out; 2398 } 2399 if (sysctl(name, nitems(name), auxv32, &len, NULL, 0) == -1) { 2400 if (errno != ESRCH && errno != EPERM) 2401 warn("sysctl: kern.proc.auxv: %d: %d", pid, errno); 2402 goto out; 2403 } 2404 count = len / sizeof(Elf_Auxinfo); 2405 auxv = malloc(count * sizeof(Elf_Auxinfo)); 2406 if (auxv == NULL) { 2407 warn("malloc(%zu)", count * sizeof(Elf_Auxinfo)); 2408 goto out; 2409 } 2410 for (i = 0; i < count; i++) { 2411 /* 2412 * XXX: We expect that values for a_type on a 32-bit platform 2413 * are directly mapped to values on 64-bit one, which is not 2414 * necessarily true. 2415 */ 2416 auxv[i].a_type = auxv32[i].a_type; 2417 ptr = &auxv32[i].a_un; 2418 auxv[i].a_un.a_val = *((uint32_t *)ptr); 2419 } 2420 *cntp = count; 2421 out: 2422 free(auxv32); 2423 return (auxv); 2424 } 2425 #endif /* __ELF_WORD_SIZE == 64 */ 2426 2427 static Elf_Auxinfo * 2428 procstat_getauxv_sysctl(pid_t pid, unsigned int *cntp) 2429 { 2430 Elf_Auxinfo *auxv; 2431 int name[4]; 2432 size_t len; 2433 2434 #if __ELF_WORD_SIZE == 64 2435 if (is_elf32_sysctl(pid)) 2436 return (procstat_getauxv32_sysctl(pid, cntp)); 2437 #endif 2438 name[0] = CTL_KERN; 2439 name[1] = KERN_PROC; 2440 name[2] = KERN_PROC_AUXV; 2441 name[3] = pid; 2442 len = PROC_AUXV_MAX * sizeof(Elf_Auxinfo); 2443 auxv = malloc(len); 2444 if (auxv == NULL) { 2445 warn("malloc(%zu)", len); 2446 return (NULL); 2447 } 2448 if (sysctl(name, nitems(name), auxv, &len, NULL, 0) == -1) { 2449 if (errno != ESRCH && errno != EPERM) 2450 warn("sysctl: kern.proc.auxv: %d: %d", pid, errno); 2451 free(auxv); 2452 return (NULL); 2453 } 2454 *cntp = len / sizeof(Elf_Auxinfo); 2455 return (auxv); 2456 } 2457 2458 static Elf_Auxinfo * 2459 procstat_getauxv_core(struct procstat_core *core, unsigned int *cntp) 2460 { 2461 Elf_Auxinfo *auxv; 2462 size_t len; 2463 2464 auxv = procstat_core_get(core, PSC_TYPE_AUXV, NULL, &len); 2465 if (auxv == NULL) 2466 return (NULL); 2467 *cntp = len / sizeof(Elf_Auxinfo); 2468 return (auxv); 2469 } 2470 2471 Elf_Auxinfo * 2472 procstat_getauxv(struct procstat *procstat, struct kinfo_proc *kp, 2473 unsigned int *cntp) 2474 { 2475 switch(procstat->type) { 2476 case PROCSTAT_KVM: 2477 warnx("kvm method is not supported"); 2478 return (NULL); 2479 case PROCSTAT_SYSCTL: 2480 return (procstat_getauxv_sysctl(kp->ki_pid, cntp)); 2481 case PROCSTAT_CORE: 2482 return (procstat_getauxv_core(procstat->core, cntp)); 2483 default: 2484 warnx("unknown access method: %d", procstat->type); 2485 return (NULL); 2486 } 2487 } 2488 2489 void 2490 procstat_freeauxv(struct procstat *procstat __unused, Elf_Auxinfo *auxv) 2491 { 2492 2493 free(auxv); 2494 } 2495 2496 static struct ptrace_lwpinfo * 2497 procstat_getptlwpinfo_core(struct procstat_core *core, unsigned int *cntp) 2498 { 2499 void *buf; 2500 struct ptrace_lwpinfo *pl; 2501 unsigned int cnt; 2502 size_t len; 2503 2504 cnt = procstat_core_note_count(core, PSC_TYPE_PTLWPINFO); 2505 if (cnt == 0) 2506 return (NULL); 2507 2508 len = cnt * sizeof(*pl); 2509 buf = calloc(1, len); 2510 pl = procstat_core_get(core, PSC_TYPE_PTLWPINFO, buf, &len); 2511 if (pl == NULL) { 2512 free(buf); 2513 return (NULL); 2514 } 2515 *cntp = len / sizeof(*pl); 2516 return (pl); 2517 } 2518 2519 struct ptrace_lwpinfo * 2520 procstat_getptlwpinfo(struct procstat *procstat, unsigned int *cntp) 2521 { 2522 switch (procstat->type) { 2523 case PROCSTAT_KVM: 2524 warnx("kvm method is not supported"); 2525 return (NULL); 2526 case PROCSTAT_SYSCTL: 2527 warnx("sysctl method is not supported"); 2528 return (NULL); 2529 case PROCSTAT_CORE: 2530 return (procstat_getptlwpinfo_core(procstat->core, cntp)); 2531 default: 2532 warnx("unknown access method: %d", procstat->type); 2533 return (NULL); 2534 } 2535 } 2536 2537 void 2538 procstat_freeptlwpinfo(struct procstat *procstat __unused, 2539 struct ptrace_lwpinfo *pl) 2540 { 2541 free(pl); 2542 } 2543 2544 static struct kinfo_kstack * 2545 procstat_getkstack_sysctl(pid_t pid, int *cntp) 2546 { 2547 struct kinfo_kstack *kkstp; 2548 int error, name[4]; 2549 size_t len; 2550 2551 name[0] = CTL_KERN; 2552 name[1] = KERN_PROC; 2553 name[2] = KERN_PROC_KSTACK; 2554 name[3] = pid; 2555 2556 len = 0; 2557 error = sysctl(name, nitems(name), NULL, &len, NULL, 0); 2558 if (error < 0 && errno != ESRCH && errno != EPERM && errno != ENOENT) { 2559 warn("sysctl: kern.proc.kstack: %d", pid); 2560 return (NULL); 2561 } 2562 if (error == -1 && errno == ENOENT) { 2563 warnx("sysctl: kern.proc.kstack unavailable" 2564 " (options DDB or options STACK required in kernel)"); 2565 return (NULL); 2566 } 2567 if (error == -1) 2568 return (NULL); 2569 kkstp = malloc(len); 2570 if (kkstp == NULL) { 2571 warn("malloc(%zu)", len); 2572 return (NULL); 2573 } 2574 if (sysctl(name, nitems(name), kkstp, &len, NULL, 0) == -1) { 2575 warn("sysctl: kern.proc.pid: %d", pid); 2576 free(kkstp); 2577 return (NULL); 2578 } 2579 *cntp = len / sizeof(*kkstp); 2580 2581 return (kkstp); 2582 } 2583 2584 struct kinfo_kstack * 2585 procstat_getkstack(struct procstat *procstat, struct kinfo_proc *kp, 2586 unsigned int *cntp) 2587 { 2588 switch(procstat->type) { 2589 case PROCSTAT_KVM: 2590 warnx("kvm method is not supported"); 2591 return (NULL); 2592 case PROCSTAT_SYSCTL: 2593 return (procstat_getkstack_sysctl(kp->ki_pid, cntp)); 2594 case PROCSTAT_CORE: 2595 warnx("core method is not supported"); 2596 return (NULL); 2597 default: 2598 warnx("unknown access method: %d", procstat->type); 2599 return (NULL); 2600 } 2601 } 2602 2603 void 2604 procstat_freekstack(struct procstat *procstat __unused, 2605 struct kinfo_kstack *kkstp) 2606 { 2607 2608 free(kkstp); 2609 } 2610