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