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 case DTYPE_DEV: 592 type = PS_FST_TYPE_DEV; 593 data = file.f_data; 594 break; 595 default: 596 continue; 597 } 598 /* XXXRW: No capability rights support for kvm yet. */ 599 entry = filestat_new_entry(data, type, i, 600 to_filestat_flags(file.f_flag), 0, 0, 0, NULL, NULL); 601 if (entry != NULL) 602 STAILQ_INSERT_TAIL(head, entry, next); 603 } 604 free(ofiles); 605 606 do_mmapped: 607 608 /* 609 * Process mmapped files if requested. 610 */ 611 if (mmapped) { 612 if (!kvm_read_all(kd, (unsigned long)kp->ki_vmspace, &vmspace, 613 sizeof(vmspace))) { 614 warnx("can't read vmspace at %p", 615 (void *)kp->ki_vmspace); 616 goto exit; 617 } 618 map = &vmspace.vm_map; 619 620 for (entryp = map->header.next; 621 entryp != &kp->ki_vmspace->vm_map.header; 622 entryp = vmentry.next) { 623 if (!kvm_read_all(kd, (unsigned long)entryp, &vmentry, 624 sizeof(vmentry))) { 625 warnx("can't read vm_map_entry at %p", 626 (void *)entryp); 627 continue; 628 } 629 if (vmentry.eflags & MAP_ENTRY_IS_SUB_MAP) 630 continue; 631 if ((objp = vmentry.object.vm_object) == NULL) 632 continue; 633 for (; objp; objp = object.backing_object) { 634 if (!kvm_read_all(kd, (unsigned long)objp, 635 &object, sizeof(object))) { 636 warnx("can't read vm_object at %p", 637 (void *)objp); 638 break; 639 } 640 } 641 642 /* We want only vnode objects. */ 643 if (object.type != OBJT_VNODE) 644 continue; 645 646 prot = vmentry.protection; 647 fflags = 0; 648 if (prot & VM_PROT_READ) 649 fflags = PS_FST_FFLAG_READ; 650 if ((vmentry.eflags & MAP_ENTRY_COW) == 0 && 651 prot & VM_PROT_WRITE) 652 fflags |= PS_FST_FFLAG_WRITE; 653 654 /* 655 * Create filestat entry. 656 */ 657 entry = filestat_new_entry(object.handle, 658 PS_FST_TYPE_VNODE, -1, fflags, 659 PS_FST_UFLAG_MMAP, 0, 0, NULL, NULL); 660 if (entry != NULL) 661 STAILQ_INSERT_TAIL(head, entry, next); 662 } 663 } 664 exit: 665 return (head); 666 } 667 668 /* 669 * kinfo types to filestat translation. 670 */ 671 static int 672 kinfo_type2fst(int kftype) 673 { 674 static struct { 675 int kf_type; 676 int fst_type; 677 } kftypes2fst[] = { 678 { KF_TYPE_PROCDESC, PS_FST_TYPE_PROCDESC }, 679 { KF_TYPE_CRYPTO, PS_FST_TYPE_CRYPTO }, 680 { KF_TYPE_DEV, PS_FST_TYPE_DEV }, 681 { KF_TYPE_FIFO, PS_FST_TYPE_FIFO }, 682 { KF_TYPE_KQUEUE, PS_FST_TYPE_KQUEUE }, 683 { KF_TYPE_MQUEUE, PS_FST_TYPE_MQUEUE }, 684 { KF_TYPE_NONE, PS_FST_TYPE_NONE }, 685 { KF_TYPE_PIPE, PS_FST_TYPE_PIPE }, 686 { KF_TYPE_PTS, PS_FST_TYPE_PTS }, 687 { KF_TYPE_SEM, PS_FST_TYPE_SEM }, 688 { KF_TYPE_SHM, PS_FST_TYPE_SHM }, 689 { KF_TYPE_SOCKET, PS_FST_TYPE_SOCKET }, 690 { KF_TYPE_VNODE, PS_FST_TYPE_VNODE }, 691 { KF_TYPE_UNKNOWN, PS_FST_TYPE_UNKNOWN } 692 }; 693 #define NKFTYPES (sizeof(kftypes2fst) / sizeof(*kftypes2fst)) 694 unsigned int i; 695 696 for (i = 0; i < NKFTYPES; i++) 697 if (kftypes2fst[i].kf_type == kftype) 698 break; 699 if (i == NKFTYPES) 700 return (PS_FST_TYPE_UNKNOWN); 701 return (kftypes2fst[i].fst_type); 702 } 703 704 /* 705 * kinfo flags to filestat translation. 706 */ 707 static int 708 kinfo_fflags2fst(int kfflags) 709 { 710 static struct { 711 int kf_flag; 712 int fst_flag; 713 } kfflags2fst[] = { 714 { KF_FLAG_APPEND, PS_FST_FFLAG_APPEND }, 715 { KF_FLAG_ASYNC, PS_FST_FFLAG_ASYNC }, 716 { KF_FLAG_CREAT, PS_FST_FFLAG_CREAT }, 717 { KF_FLAG_DIRECT, PS_FST_FFLAG_DIRECT }, 718 { KF_FLAG_EXCL, PS_FST_FFLAG_EXCL }, 719 { KF_FLAG_EXEC, PS_FST_FFLAG_EXEC }, 720 { KF_FLAG_EXLOCK, PS_FST_FFLAG_EXLOCK }, 721 { KF_FLAG_FSYNC, PS_FST_FFLAG_SYNC }, 722 { KF_FLAG_HASLOCK, PS_FST_FFLAG_HASLOCK }, 723 { KF_FLAG_NOFOLLOW, PS_FST_FFLAG_NOFOLLOW }, 724 { KF_FLAG_NONBLOCK, PS_FST_FFLAG_NONBLOCK }, 725 { KF_FLAG_READ, PS_FST_FFLAG_READ }, 726 { KF_FLAG_SHLOCK, PS_FST_FFLAG_SHLOCK }, 727 { KF_FLAG_TRUNC, PS_FST_FFLAG_TRUNC }, 728 { KF_FLAG_WRITE, PS_FST_FFLAG_WRITE } 729 }; 730 #define NKFFLAGS (sizeof(kfflags2fst) / sizeof(*kfflags2fst)) 731 unsigned int i; 732 int flags; 733 734 flags = 0; 735 for (i = 0; i < NKFFLAGS; i++) 736 if ((kfflags & kfflags2fst[i].kf_flag) != 0) 737 flags |= kfflags2fst[i].fst_flag; 738 return (flags); 739 } 740 741 static int 742 kinfo_uflags2fst(int fd) 743 { 744 745 switch (fd) { 746 case KF_FD_TYPE_CTTY: 747 return (PS_FST_UFLAG_CTTY); 748 case KF_FD_TYPE_CWD: 749 return (PS_FST_UFLAG_CDIR); 750 case KF_FD_TYPE_JAIL: 751 return (PS_FST_UFLAG_JAIL); 752 case KF_FD_TYPE_TEXT: 753 return (PS_FST_UFLAG_TEXT); 754 case KF_FD_TYPE_TRACE: 755 return (PS_FST_UFLAG_TRACE); 756 case KF_FD_TYPE_ROOT: 757 return (PS_FST_UFLAG_RDIR); 758 } 759 return (0); 760 } 761 762 static struct kinfo_file * 763 kinfo_getfile_core(struct procstat_core *core, int *cntp) 764 { 765 int cnt; 766 size_t len; 767 char *buf, *bp, *eb; 768 struct kinfo_file *kif, *kp, *kf; 769 770 buf = procstat_core_get(core, PSC_TYPE_FILES, NULL, &len); 771 if (buf == NULL) 772 return (NULL); 773 /* 774 * XXXMG: The code below is just copy&past from libutil. 775 * The code duplication can be avoided if libutil 776 * is extended to provide something like: 777 * struct kinfo_file *kinfo_getfile_from_buf(const char *buf, 778 * size_t len, int *cntp); 779 */ 780 781 /* Pass 1: count items */ 782 cnt = 0; 783 bp = buf; 784 eb = buf + len; 785 while (bp < eb) { 786 kf = (struct kinfo_file *)(uintptr_t)bp; 787 if (kf->kf_structsize == 0) 788 break; 789 bp += kf->kf_structsize; 790 cnt++; 791 } 792 793 kif = calloc(cnt, sizeof(*kif)); 794 if (kif == NULL) { 795 free(buf); 796 return (NULL); 797 } 798 bp = buf; 799 eb = buf + len; 800 kp = kif; 801 /* Pass 2: unpack */ 802 while (bp < eb) { 803 kf = (struct kinfo_file *)(uintptr_t)bp; 804 if (kf->kf_structsize == 0) 805 break; 806 /* Copy/expand into pre-zeroed buffer */ 807 memcpy(kp, kf, kf->kf_structsize); 808 /* Advance to next packed record */ 809 bp += kf->kf_structsize; 810 /* Set field size to fixed length, advance */ 811 kp->kf_structsize = sizeof(*kp); 812 kp++; 813 } 814 free(buf); 815 *cntp = cnt; 816 return (kif); /* Caller must free() return value */ 817 } 818 819 static struct filestat_list * 820 procstat_getfiles_sysctl(struct procstat *procstat, struct kinfo_proc *kp, 821 int mmapped) 822 { 823 struct kinfo_file *kif, *files; 824 struct kinfo_vmentry *kve, *vmentries; 825 struct filestat_list *head; 826 struct filestat *entry; 827 char *path; 828 off_t offset; 829 int cnt, fd, fflags; 830 int i, type, uflags; 831 int refcount; 832 cap_rights_t cap_rights; 833 834 assert(kp); 835 if (kp->ki_fd == NULL) 836 return (NULL); 837 switch(procstat->type) { 838 case PROCSTAT_SYSCTL: 839 files = kinfo_getfile(kp->ki_pid, &cnt); 840 break; 841 case PROCSTAT_CORE: 842 files = kinfo_getfile_core(procstat->core, &cnt); 843 break; 844 default: 845 assert(!"invalid type"); 846 } 847 if (files == NULL && errno != EPERM) { 848 warn("kinfo_getfile()"); 849 return (NULL); 850 } 851 procstat->files = files; 852 853 /* 854 * Allocate list head. 855 */ 856 head = malloc(sizeof(*head)); 857 if (head == NULL) 858 return (NULL); 859 STAILQ_INIT(head); 860 for (i = 0; i < cnt; i++) { 861 kif = &files[i]; 862 863 type = kinfo_type2fst(kif->kf_type); 864 fd = kif->kf_fd >= 0 ? kif->kf_fd : -1; 865 fflags = kinfo_fflags2fst(kif->kf_flags); 866 uflags = kinfo_uflags2fst(kif->kf_fd); 867 refcount = kif->kf_ref_count; 868 offset = kif->kf_offset; 869 if (*kif->kf_path != '\0') 870 path = strdup(kif->kf_path); 871 else 872 path = NULL; 873 cap_rights = kif->kf_cap_rights; 874 875 /* 876 * Create filestat entry. 877 */ 878 entry = filestat_new_entry(kif, type, fd, fflags, uflags, 879 refcount, offset, path, &cap_rights); 880 if (entry != NULL) 881 STAILQ_INSERT_TAIL(head, entry, next); 882 } 883 if (mmapped != 0) { 884 vmentries = procstat_getvmmap(procstat, kp, &cnt); 885 procstat->vmentries = vmentries; 886 if (vmentries == NULL || cnt == 0) 887 goto fail; 888 for (i = 0; i < cnt; i++) { 889 kve = &vmentries[i]; 890 if (kve->kve_type != KVME_TYPE_VNODE) 891 continue; 892 fflags = 0; 893 if (kve->kve_protection & KVME_PROT_READ) 894 fflags = PS_FST_FFLAG_READ; 895 if ((kve->kve_flags & KVME_FLAG_COW) == 0 && 896 kve->kve_protection & KVME_PROT_WRITE) 897 fflags |= PS_FST_FFLAG_WRITE; 898 offset = kve->kve_offset; 899 refcount = kve->kve_ref_count; 900 if (*kve->kve_path != '\0') 901 path = strdup(kve->kve_path); 902 else 903 path = NULL; 904 entry = filestat_new_entry(kve, PS_FST_TYPE_VNODE, -1, 905 fflags, PS_FST_UFLAG_MMAP, refcount, offset, path, 906 NULL); 907 if (entry != NULL) 908 STAILQ_INSERT_TAIL(head, entry, next); 909 } 910 } 911 fail: 912 return (head); 913 } 914 915 int 916 procstat_get_pipe_info(struct procstat *procstat, struct filestat *fst, 917 struct pipestat *ps, char *errbuf) 918 { 919 920 assert(ps); 921 if (procstat->type == PROCSTAT_KVM) { 922 return (procstat_get_pipe_info_kvm(procstat->kd, fst, ps, 923 errbuf)); 924 } else if (procstat->type == PROCSTAT_SYSCTL || 925 procstat->type == PROCSTAT_CORE) { 926 return (procstat_get_pipe_info_sysctl(fst, ps, errbuf)); 927 } else { 928 warnx("unknown access method: %d", procstat->type); 929 if (errbuf != NULL) 930 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 931 return (1); 932 } 933 } 934 935 static int 936 procstat_get_pipe_info_kvm(kvm_t *kd, struct filestat *fst, 937 struct pipestat *ps, char *errbuf) 938 { 939 struct pipe pi; 940 void *pipep; 941 942 assert(kd); 943 assert(ps); 944 assert(fst); 945 bzero(ps, sizeof(*ps)); 946 pipep = fst->fs_typedep; 947 if (pipep == NULL) 948 goto fail; 949 if (!kvm_read_all(kd, (unsigned long)pipep, &pi, sizeof(struct pipe))) { 950 warnx("can't read pipe at %p", (void *)pipep); 951 goto fail; 952 } 953 ps->addr = (uintptr_t)pipep; 954 ps->peer = (uintptr_t)pi.pipe_peer; 955 ps->buffer_cnt = pi.pipe_buffer.cnt; 956 return (0); 957 958 fail: 959 if (errbuf != NULL) 960 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 961 return (1); 962 } 963 964 static int 965 procstat_get_pipe_info_sysctl(struct filestat *fst, struct pipestat *ps, 966 char *errbuf __unused) 967 { 968 struct kinfo_file *kif; 969 970 assert(ps); 971 assert(fst); 972 bzero(ps, sizeof(*ps)); 973 kif = fst->fs_typedep; 974 if (kif == NULL) 975 return (1); 976 ps->addr = kif->kf_un.kf_pipe.kf_pipe_addr; 977 ps->peer = kif->kf_un.kf_pipe.kf_pipe_peer; 978 ps->buffer_cnt = kif->kf_un.kf_pipe.kf_pipe_buffer_cnt; 979 return (0); 980 } 981 982 int 983 procstat_get_pts_info(struct procstat *procstat, struct filestat *fst, 984 struct ptsstat *pts, char *errbuf) 985 { 986 987 assert(pts); 988 if (procstat->type == PROCSTAT_KVM) { 989 return (procstat_get_pts_info_kvm(procstat->kd, fst, pts, 990 errbuf)); 991 } else if (procstat->type == PROCSTAT_SYSCTL || 992 procstat->type == PROCSTAT_CORE) { 993 return (procstat_get_pts_info_sysctl(fst, pts, errbuf)); 994 } else { 995 warnx("unknown access method: %d", procstat->type); 996 if (errbuf != NULL) 997 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 998 return (1); 999 } 1000 } 1001 1002 static int 1003 procstat_get_pts_info_kvm(kvm_t *kd, struct filestat *fst, 1004 struct ptsstat *pts, char *errbuf) 1005 { 1006 struct tty tty; 1007 void *ttyp; 1008 1009 assert(kd); 1010 assert(pts); 1011 assert(fst); 1012 bzero(pts, sizeof(*pts)); 1013 ttyp = fst->fs_typedep; 1014 if (ttyp == NULL) 1015 goto fail; 1016 if (!kvm_read_all(kd, (unsigned long)ttyp, &tty, sizeof(struct tty))) { 1017 warnx("can't read tty at %p", (void *)ttyp); 1018 goto fail; 1019 } 1020 pts->dev = dev2udev(kd, tty.t_dev); 1021 (void)kdevtoname(kd, tty.t_dev, pts->devname); 1022 return (0); 1023 1024 fail: 1025 if (errbuf != NULL) 1026 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1027 return (1); 1028 } 1029 1030 static int 1031 procstat_get_pts_info_sysctl(struct filestat *fst, struct ptsstat *pts, 1032 char *errbuf __unused) 1033 { 1034 struct kinfo_file *kif; 1035 1036 assert(pts); 1037 assert(fst); 1038 bzero(pts, sizeof(*pts)); 1039 kif = fst->fs_typedep; 1040 if (kif == NULL) 1041 return (0); 1042 pts->dev = kif->kf_un.kf_pts.kf_pts_dev; 1043 strlcpy(pts->devname, kif->kf_path, sizeof(pts->devname)); 1044 return (0); 1045 } 1046 1047 int 1048 procstat_get_sem_info(struct procstat *procstat, struct filestat *fst, 1049 struct semstat *sem, char *errbuf) 1050 { 1051 1052 assert(sem); 1053 if (procstat->type == PROCSTAT_KVM) { 1054 return (procstat_get_sem_info_kvm(procstat->kd, fst, sem, 1055 errbuf)); 1056 } else if (procstat->type == PROCSTAT_SYSCTL || 1057 procstat->type == PROCSTAT_CORE) { 1058 return (procstat_get_sem_info_sysctl(fst, sem, errbuf)); 1059 } else { 1060 warnx("unknown access method: %d", procstat->type); 1061 if (errbuf != NULL) 1062 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1063 return (1); 1064 } 1065 } 1066 1067 static int 1068 procstat_get_sem_info_kvm(kvm_t *kd, struct filestat *fst, 1069 struct semstat *sem, char *errbuf) 1070 { 1071 struct ksem ksem; 1072 void *ksemp; 1073 char *path; 1074 int i; 1075 1076 assert(kd); 1077 assert(sem); 1078 assert(fst); 1079 bzero(sem, sizeof(*sem)); 1080 ksemp = fst->fs_typedep; 1081 if (ksemp == NULL) 1082 goto fail; 1083 if (!kvm_read_all(kd, (unsigned long)ksemp, &ksem, 1084 sizeof(struct ksem))) { 1085 warnx("can't read ksem at %p", (void *)ksemp); 1086 goto fail; 1087 } 1088 sem->mode = S_IFREG | ksem.ks_mode; 1089 sem->value = ksem.ks_value; 1090 if (fst->fs_path == NULL && ksem.ks_path != NULL) { 1091 path = malloc(MAXPATHLEN); 1092 for (i = 0; i < MAXPATHLEN - 1; i++) { 1093 if (!kvm_read_all(kd, (unsigned long)ksem.ks_path + i, 1094 path + i, 1)) 1095 break; 1096 if (path[i] == '\0') 1097 break; 1098 } 1099 path[i] = '\0'; 1100 if (i == 0) 1101 free(path); 1102 else 1103 fst->fs_path = path; 1104 } 1105 return (0); 1106 1107 fail: 1108 if (errbuf != NULL) 1109 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1110 return (1); 1111 } 1112 1113 static int 1114 procstat_get_sem_info_sysctl(struct filestat *fst, struct semstat *sem, 1115 char *errbuf __unused) 1116 { 1117 struct kinfo_file *kif; 1118 1119 assert(sem); 1120 assert(fst); 1121 bzero(sem, sizeof(*sem)); 1122 kif = fst->fs_typedep; 1123 if (kif == NULL) 1124 return (0); 1125 sem->value = kif->kf_un.kf_sem.kf_sem_value; 1126 sem->mode = kif->kf_un.kf_sem.kf_sem_mode; 1127 return (0); 1128 } 1129 1130 int 1131 procstat_get_shm_info(struct procstat *procstat, struct filestat *fst, 1132 struct shmstat *shm, char *errbuf) 1133 { 1134 1135 assert(shm); 1136 if (procstat->type == PROCSTAT_KVM) { 1137 return (procstat_get_shm_info_kvm(procstat->kd, fst, shm, 1138 errbuf)); 1139 } else if (procstat->type == PROCSTAT_SYSCTL || 1140 procstat->type == PROCSTAT_CORE) { 1141 return (procstat_get_shm_info_sysctl(fst, shm, errbuf)); 1142 } else { 1143 warnx("unknown access method: %d", procstat->type); 1144 if (errbuf != NULL) 1145 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1146 return (1); 1147 } 1148 } 1149 1150 static int 1151 procstat_get_shm_info_kvm(kvm_t *kd, struct filestat *fst, 1152 struct shmstat *shm, char *errbuf) 1153 { 1154 struct shmfd shmfd; 1155 void *shmfdp; 1156 char *path; 1157 int i; 1158 1159 assert(kd); 1160 assert(shm); 1161 assert(fst); 1162 bzero(shm, sizeof(*shm)); 1163 shmfdp = fst->fs_typedep; 1164 if (shmfdp == NULL) 1165 goto fail; 1166 if (!kvm_read_all(kd, (unsigned long)shmfdp, &shmfd, 1167 sizeof(struct shmfd))) { 1168 warnx("can't read shmfd at %p", (void *)shmfdp); 1169 goto fail; 1170 } 1171 shm->mode = S_IFREG | shmfd.shm_mode; 1172 shm->size = shmfd.shm_size; 1173 if (fst->fs_path == NULL && shmfd.shm_path != NULL) { 1174 path = malloc(MAXPATHLEN); 1175 for (i = 0; i < MAXPATHLEN - 1; i++) { 1176 if (!kvm_read_all(kd, (unsigned long)shmfd.shm_path + i, 1177 path + i, 1)) 1178 break; 1179 if (path[i] == '\0') 1180 break; 1181 } 1182 path[i] = '\0'; 1183 if (i == 0) 1184 free(path); 1185 else 1186 fst->fs_path = path; 1187 } 1188 return (0); 1189 1190 fail: 1191 if (errbuf != NULL) 1192 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1193 return (1); 1194 } 1195 1196 static int 1197 procstat_get_shm_info_sysctl(struct filestat *fst, struct shmstat *shm, 1198 char *errbuf __unused) 1199 { 1200 struct kinfo_file *kif; 1201 1202 assert(shm); 1203 assert(fst); 1204 bzero(shm, sizeof(*shm)); 1205 kif = fst->fs_typedep; 1206 if (kif == NULL) 1207 return (0); 1208 shm->size = kif->kf_un.kf_file.kf_file_size; 1209 shm->mode = kif->kf_un.kf_file.kf_file_mode; 1210 return (0); 1211 } 1212 1213 int 1214 procstat_get_vnode_info(struct procstat *procstat, struct filestat *fst, 1215 struct vnstat *vn, char *errbuf) 1216 { 1217 1218 assert(vn); 1219 if (procstat->type == PROCSTAT_KVM) { 1220 return (procstat_get_vnode_info_kvm(procstat->kd, fst, vn, 1221 errbuf)); 1222 } else if (procstat->type == PROCSTAT_SYSCTL || 1223 procstat->type == PROCSTAT_CORE) { 1224 return (procstat_get_vnode_info_sysctl(fst, vn, errbuf)); 1225 } else { 1226 warnx("unknown access method: %d", procstat->type); 1227 if (errbuf != NULL) 1228 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1229 return (1); 1230 } 1231 } 1232 1233 static int 1234 procstat_get_vnode_info_kvm(kvm_t *kd, struct filestat *fst, 1235 struct vnstat *vn, char *errbuf) 1236 { 1237 /* Filesystem specific handlers. */ 1238 #define FSTYPE(fst) {#fst, fst##_filestat} 1239 struct { 1240 const char *tag; 1241 int (*handler)(kvm_t *kd, struct vnode *vp, 1242 struct vnstat *vn); 1243 } fstypes[] = { 1244 FSTYPE(devfs), 1245 FSTYPE(isofs), 1246 FSTYPE(msdosfs), 1247 FSTYPE(nfs), 1248 FSTYPE(smbfs), 1249 FSTYPE(udf), 1250 FSTYPE(ufs), 1251 #ifdef LIBPROCSTAT_ZFS 1252 FSTYPE(zfs), 1253 #endif 1254 }; 1255 #define NTYPES (sizeof(fstypes) / sizeof(*fstypes)) 1256 struct vnode vnode; 1257 char tagstr[12]; 1258 void *vp; 1259 int error; 1260 unsigned int i; 1261 1262 assert(kd); 1263 assert(vn); 1264 assert(fst); 1265 vp = fst->fs_typedep; 1266 if (vp == NULL) 1267 goto fail; 1268 error = kvm_read_all(kd, (unsigned long)vp, &vnode, sizeof(vnode)); 1269 if (error == 0) { 1270 warnx("can't read vnode at %p", (void *)vp); 1271 goto fail; 1272 } 1273 bzero(vn, sizeof(*vn)); 1274 vn->vn_type = vntype2psfsttype(vnode.v_type); 1275 if (vnode.v_type == VNON || vnode.v_type == VBAD) 1276 return (0); 1277 error = kvm_read_all(kd, (unsigned long)vnode.v_tag, tagstr, 1278 sizeof(tagstr)); 1279 if (error == 0) { 1280 warnx("can't read v_tag at %p", (void *)vp); 1281 goto fail; 1282 } 1283 tagstr[sizeof(tagstr) - 1] = '\0'; 1284 1285 /* 1286 * Find appropriate handler. 1287 */ 1288 for (i = 0; i < NTYPES; i++) 1289 if (!strcmp(fstypes[i].tag, tagstr)) { 1290 if (fstypes[i].handler(kd, &vnode, vn) != 0) { 1291 goto fail; 1292 } 1293 break; 1294 } 1295 if (i == NTYPES) { 1296 if (errbuf != NULL) 1297 snprintf(errbuf, _POSIX2_LINE_MAX, "?(%s)", tagstr); 1298 return (1); 1299 } 1300 vn->vn_mntdir = getmnton(kd, vnode.v_mount); 1301 if ((vnode.v_type == VBLK || vnode.v_type == VCHR) && 1302 vnode.v_rdev != NULL){ 1303 vn->vn_dev = dev2udev(kd, vnode.v_rdev); 1304 (void)kdevtoname(kd, vnode.v_rdev, vn->vn_devname); 1305 } else { 1306 vn->vn_dev = -1; 1307 } 1308 return (0); 1309 1310 fail: 1311 if (errbuf != NULL) 1312 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1313 return (1); 1314 } 1315 1316 /* 1317 * kinfo vnode type to filestat translation. 1318 */ 1319 static int 1320 kinfo_vtype2fst(int kfvtype) 1321 { 1322 static struct { 1323 int kf_vtype; 1324 int fst_vtype; 1325 } kfvtypes2fst[] = { 1326 { KF_VTYPE_VBAD, PS_FST_VTYPE_VBAD }, 1327 { KF_VTYPE_VBLK, PS_FST_VTYPE_VBLK }, 1328 { KF_VTYPE_VCHR, PS_FST_VTYPE_VCHR }, 1329 { KF_VTYPE_VDIR, PS_FST_VTYPE_VDIR }, 1330 { KF_VTYPE_VFIFO, PS_FST_VTYPE_VFIFO }, 1331 { KF_VTYPE_VLNK, PS_FST_VTYPE_VLNK }, 1332 { KF_VTYPE_VNON, PS_FST_VTYPE_VNON }, 1333 { KF_VTYPE_VREG, PS_FST_VTYPE_VREG }, 1334 { KF_VTYPE_VSOCK, PS_FST_VTYPE_VSOCK } 1335 }; 1336 #define NKFVTYPES (sizeof(kfvtypes2fst) / sizeof(*kfvtypes2fst)) 1337 unsigned int i; 1338 1339 for (i = 0; i < NKFVTYPES; i++) 1340 if (kfvtypes2fst[i].kf_vtype == kfvtype) 1341 break; 1342 if (i == NKFVTYPES) 1343 return (PS_FST_VTYPE_UNKNOWN); 1344 return (kfvtypes2fst[i].fst_vtype); 1345 } 1346 1347 static int 1348 procstat_get_vnode_info_sysctl(struct filestat *fst, struct vnstat *vn, 1349 char *errbuf) 1350 { 1351 struct statfs stbuf; 1352 struct kinfo_file *kif; 1353 struct kinfo_vmentry *kve; 1354 char *name, *path; 1355 uint64_t fileid; 1356 uint64_t size; 1357 uint64_t fsid; 1358 uint64_t rdev; 1359 uint16_t mode; 1360 int vntype; 1361 int status; 1362 1363 assert(fst); 1364 assert(vn); 1365 bzero(vn, sizeof(*vn)); 1366 if (fst->fs_typedep == NULL) 1367 return (1); 1368 if (fst->fs_uflags & PS_FST_UFLAG_MMAP) { 1369 kve = fst->fs_typedep; 1370 fileid = kve->kve_vn_fileid; 1371 fsid = kve->kve_vn_fsid; 1372 mode = kve->kve_vn_mode; 1373 path = kve->kve_path; 1374 rdev = kve->kve_vn_rdev; 1375 size = kve->kve_vn_size; 1376 vntype = kinfo_vtype2fst(kve->kve_vn_type); 1377 status = kve->kve_status; 1378 } else { 1379 kif = fst->fs_typedep; 1380 fileid = kif->kf_un.kf_file.kf_file_fileid; 1381 fsid = kif->kf_un.kf_file.kf_file_fsid; 1382 mode = kif->kf_un.kf_file.kf_file_mode; 1383 path = kif->kf_path; 1384 rdev = kif->kf_un.kf_file.kf_file_rdev; 1385 size = kif->kf_un.kf_file.kf_file_size; 1386 vntype = kinfo_vtype2fst(kif->kf_vnode_type); 1387 status = kif->kf_status; 1388 } 1389 vn->vn_type = vntype; 1390 if (vntype == PS_FST_VTYPE_VNON || vntype == PS_FST_VTYPE_VBAD) 1391 return (0); 1392 if ((status & KF_ATTR_VALID) == 0) { 1393 if (errbuf != NULL) { 1394 snprintf(errbuf, _POSIX2_LINE_MAX, 1395 "? (no info available)"); 1396 } 1397 return (1); 1398 } 1399 if (path && *path) { 1400 statfs(path, &stbuf); 1401 vn->vn_mntdir = strdup(stbuf.f_mntonname); 1402 } else 1403 vn->vn_mntdir = strdup("-"); 1404 vn->vn_dev = rdev; 1405 if (vntype == PS_FST_VTYPE_VBLK) { 1406 name = devname(rdev, S_IFBLK); 1407 if (name != NULL) 1408 strlcpy(vn->vn_devname, name, 1409 sizeof(vn->vn_devname)); 1410 } else if (vntype == PS_FST_VTYPE_VCHR) { 1411 name = devname(vn->vn_dev, S_IFCHR); 1412 if (name != NULL) 1413 strlcpy(vn->vn_devname, name, 1414 sizeof(vn->vn_devname)); 1415 } 1416 vn->vn_fsid = fsid; 1417 vn->vn_fileid = fileid; 1418 vn->vn_size = size; 1419 vn->vn_mode = mode; 1420 return (0); 1421 } 1422 1423 int 1424 procstat_get_socket_info(struct procstat *procstat, struct filestat *fst, 1425 struct sockstat *sock, char *errbuf) 1426 { 1427 1428 assert(sock); 1429 if (procstat->type == PROCSTAT_KVM) { 1430 return (procstat_get_socket_info_kvm(procstat->kd, fst, sock, 1431 errbuf)); 1432 } else if (procstat->type == PROCSTAT_SYSCTL || 1433 procstat->type == PROCSTAT_CORE) { 1434 return (procstat_get_socket_info_sysctl(fst, sock, errbuf)); 1435 } else { 1436 warnx("unknown access method: %d", procstat->type); 1437 if (errbuf != NULL) 1438 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1439 return (1); 1440 } 1441 } 1442 1443 static int 1444 procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst, 1445 struct sockstat *sock, char *errbuf) 1446 { 1447 struct domain dom; 1448 struct inpcb inpcb; 1449 struct protosw proto; 1450 struct socket s; 1451 struct unpcb unpcb; 1452 ssize_t len; 1453 void *so; 1454 1455 assert(kd); 1456 assert(sock); 1457 assert(fst); 1458 bzero(sock, sizeof(*sock)); 1459 so = fst->fs_typedep; 1460 if (so == NULL) 1461 goto fail; 1462 sock->so_addr = (uintptr_t)so; 1463 /* fill in socket */ 1464 if (!kvm_read_all(kd, (unsigned long)so, &s, 1465 sizeof(struct socket))) { 1466 warnx("can't read sock at %p", (void *)so); 1467 goto fail; 1468 } 1469 /* fill in protosw entry */ 1470 if (!kvm_read_all(kd, (unsigned long)s.so_proto, &proto, 1471 sizeof(struct protosw))) { 1472 warnx("can't read protosw at %p", (void *)s.so_proto); 1473 goto fail; 1474 } 1475 /* fill in domain */ 1476 if (!kvm_read_all(kd, (unsigned long)proto.pr_domain, &dom, 1477 sizeof(struct domain))) { 1478 warnx("can't read domain at %p", 1479 (void *)proto.pr_domain); 1480 goto fail; 1481 } 1482 if ((len = kvm_read(kd, (unsigned long)dom.dom_name, sock->dname, 1483 sizeof(sock->dname) - 1)) < 0) { 1484 warnx("can't read domain name at %p", (void *)dom.dom_name); 1485 sock->dname[0] = '\0'; 1486 } 1487 else 1488 sock->dname[len] = '\0'; 1489 1490 /* 1491 * Fill in known data. 1492 */ 1493 sock->type = s.so_type; 1494 sock->proto = proto.pr_protocol; 1495 sock->dom_family = dom.dom_family; 1496 sock->so_pcb = (uintptr_t)s.so_pcb; 1497 1498 /* 1499 * Protocol specific data. 1500 */ 1501 switch(dom.dom_family) { 1502 case AF_INET: 1503 case AF_INET6: 1504 if (proto.pr_protocol == IPPROTO_TCP) { 1505 if (s.so_pcb) { 1506 if (kvm_read(kd, (u_long)s.so_pcb, 1507 (char *)&inpcb, sizeof(struct inpcb)) 1508 != sizeof(struct inpcb)) { 1509 warnx("can't read inpcb at %p", 1510 (void *)s.so_pcb); 1511 } else 1512 sock->inp_ppcb = 1513 (uintptr_t)inpcb.inp_ppcb; 1514 sock->sendq = s.so_snd.sb_ccc; 1515 sock->recvq = s.so_rcv.sb_ccc; 1516 } 1517 } 1518 break; 1519 case AF_UNIX: 1520 if (s.so_pcb) { 1521 if (kvm_read(kd, (u_long)s.so_pcb, (char *)&unpcb, 1522 sizeof(struct unpcb)) != sizeof(struct unpcb)){ 1523 warnx("can't read unpcb at %p", 1524 (void *)s.so_pcb); 1525 } else if (unpcb.unp_conn) { 1526 sock->so_rcv_sb_state = s.so_rcv.sb_state; 1527 sock->so_snd_sb_state = s.so_snd.sb_state; 1528 sock->unp_conn = (uintptr_t)unpcb.unp_conn; 1529 sock->sendq = s.so_snd.sb_ccc; 1530 sock->recvq = s.so_rcv.sb_ccc; 1531 } 1532 } 1533 break; 1534 default: 1535 break; 1536 } 1537 return (0); 1538 1539 fail: 1540 if (errbuf != NULL) 1541 snprintf(errbuf, _POSIX2_LINE_MAX, "error"); 1542 return (1); 1543 } 1544 1545 static int 1546 procstat_get_socket_info_sysctl(struct filestat *fst, struct sockstat *sock, 1547 char *errbuf __unused) 1548 { 1549 struct kinfo_file *kif; 1550 1551 assert(sock); 1552 assert(fst); 1553 bzero(sock, sizeof(*sock)); 1554 kif = fst->fs_typedep; 1555 if (kif == NULL) 1556 return (0); 1557 1558 /* 1559 * Fill in known data. 1560 */ 1561 sock->type = kif->kf_sock_type; 1562 sock->proto = kif->kf_sock_protocol; 1563 sock->dom_family = kif->kf_sock_domain; 1564 sock->so_pcb = kif->kf_un.kf_sock.kf_sock_pcb; 1565 strlcpy(sock->dname, kif->kf_path, sizeof(sock->dname)); 1566 bcopy(&kif->kf_un.kf_sock.kf_sa_local, &sock->sa_local, 1567 kif->kf_un.kf_sock.kf_sa_local.ss_len); 1568 bcopy(&kif->kf_un.kf_sock.kf_sa_peer, &sock->sa_peer, 1569 kif->kf_un.kf_sock.kf_sa_peer.ss_len); 1570 1571 /* 1572 * Protocol specific data. 1573 */ 1574 switch(sock->dom_family) { 1575 case AF_INET: 1576 case AF_INET6: 1577 if (sock->proto == IPPROTO_TCP) { 1578 sock->inp_ppcb = kif->kf_un.kf_sock.kf_sock_inpcb; 1579 sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq; 1580 sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq; 1581 } 1582 break; 1583 case AF_UNIX: 1584 if (kif->kf_un.kf_sock.kf_sock_unpconn != 0) { 1585 sock->so_rcv_sb_state = 1586 kif->kf_un.kf_sock.kf_sock_rcv_sb_state; 1587 sock->so_snd_sb_state = 1588 kif->kf_un.kf_sock.kf_sock_snd_sb_state; 1589 sock->unp_conn = 1590 kif->kf_un.kf_sock.kf_sock_unpconn; 1591 sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq; 1592 sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq; 1593 } 1594 break; 1595 default: 1596 break; 1597 } 1598 return (0); 1599 } 1600 1601 /* 1602 * Descriptor flags to filestat translation. 1603 */ 1604 static int 1605 to_filestat_flags(int flags) 1606 { 1607 static struct { 1608 int flag; 1609 int fst_flag; 1610 } fstflags[] = { 1611 { FREAD, PS_FST_FFLAG_READ }, 1612 { FWRITE, PS_FST_FFLAG_WRITE }, 1613 { O_APPEND, PS_FST_FFLAG_APPEND }, 1614 { O_ASYNC, PS_FST_FFLAG_ASYNC }, 1615 { O_CREAT, PS_FST_FFLAG_CREAT }, 1616 { O_DIRECT, PS_FST_FFLAG_DIRECT }, 1617 { O_EXCL, PS_FST_FFLAG_EXCL }, 1618 { O_EXEC, PS_FST_FFLAG_EXEC }, 1619 { O_EXLOCK, PS_FST_FFLAG_EXLOCK }, 1620 { O_NOFOLLOW, PS_FST_FFLAG_NOFOLLOW }, 1621 { O_NONBLOCK, PS_FST_FFLAG_NONBLOCK }, 1622 { O_SHLOCK, PS_FST_FFLAG_SHLOCK }, 1623 { O_SYNC, PS_FST_FFLAG_SYNC }, 1624 { O_TRUNC, PS_FST_FFLAG_TRUNC } 1625 }; 1626 #define NFSTFLAGS (sizeof(fstflags) / sizeof(*fstflags)) 1627 int fst_flags; 1628 unsigned int i; 1629 1630 fst_flags = 0; 1631 for (i = 0; i < NFSTFLAGS; i++) 1632 if (flags & fstflags[i].flag) 1633 fst_flags |= fstflags[i].fst_flag; 1634 return (fst_flags); 1635 } 1636 1637 /* 1638 * Vnode type to filestate translation. 1639 */ 1640 static int 1641 vntype2psfsttype(int type) 1642 { 1643 static struct { 1644 int vtype; 1645 int fst_vtype; 1646 } vt2fst[] = { 1647 { VBAD, PS_FST_VTYPE_VBAD }, 1648 { VBLK, PS_FST_VTYPE_VBLK }, 1649 { VCHR, PS_FST_VTYPE_VCHR }, 1650 { VDIR, PS_FST_VTYPE_VDIR }, 1651 { VFIFO, PS_FST_VTYPE_VFIFO }, 1652 { VLNK, PS_FST_VTYPE_VLNK }, 1653 { VNON, PS_FST_VTYPE_VNON }, 1654 { VREG, PS_FST_VTYPE_VREG }, 1655 { VSOCK, PS_FST_VTYPE_VSOCK } 1656 }; 1657 #define NVFTYPES (sizeof(vt2fst) / sizeof(*vt2fst)) 1658 unsigned int i, fst_type; 1659 1660 fst_type = PS_FST_VTYPE_UNKNOWN; 1661 for (i = 0; i < NVFTYPES; i++) { 1662 if (type == vt2fst[i].vtype) { 1663 fst_type = vt2fst[i].fst_vtype; 1664 break; 1665 } 1666 } 1667 return (fst_type); 1668 } 1669 1670 static char * 1671 getmnton(kvm_t *kd, struct mount *m) 1672 { 1673 struct mount mnt; 1674 static struct mtab { 1675 struct mtab *next; 1676 struct mount *m; 1677 char mntonname[MNAMELEN + 1]; 1678 } *mhead = NULL; 1679 struct mtab *mt; 1680 1681 for (mt = mhead; mt != NULL; mt = mt->next) 1682 if (m == mt->m) 1683 return (mt->mntonname); 1684 if (!kvm_read_all(kd, (unsigned long)m, &mnt, sizeof(struct mount))) { 1685 warnx("can't read mount table at %p", (void *)m); 1686 return (NULL); 1687 } 1688 if ((mt = malloc(sizeof (struct mtab))) == NULL) 1689 err(1, NULL); 1690 mt->m = m; 1691 bcopy(&mnt.mnt_stat.f_mntonname[0], &mt->mntonname[0], MNAMELEN); 1692 mt->mntonname[MNAMELEN] = '\0'; 1693 mt->next = mhead; 1694 mhead = mt; 1695 return (mt->mntonname); 1696 } 1697 1698 /* 1699 * Auxiliary structures and functions to get process environment or 1700 * command line arguments. 1701 */ 1702 struct argvec { 1703 char *buf; 1704 size_t bufsize; 1705 char **argv; 1706 size_t argc; 1707 }; 1708 1709 static struct argvec * 1710 argvec_alloc(size_t bufsize) 1711 { 1712 struct argvec *av; 1713 1714 av = malloc(sizeof(*av)); 1715 if (av == NULL) 1716 return (NULL); 1717 av->bufsize = bufsize; 1718 av->buf = malloc(av->bufsize); 1719 if (av->buf == NULL) { 1720 free(av); 1721 return (NULL); 1722 } 1723 av->argc = 32; 1724 av->argv = malloc(sizeof(char *) * av->argc); 1725 if (av->argv == NULL) { 1726 free(av->buf); 1727 free(av); 1728 return (NULL); 1729 } 1730 return av; 1731 } 1732 1733 static void 1734 argvec_free(struct argvec * av) 1735 { 1736 1737 free(av->argv); 1738 free(av->buf); 1739 free(av); 1740 } 1741 1742 static char ** 1743 getargv(struct procstat *procstat, struct kinfo_proc *kp, size_t nchr, int env) 1744 { 1745 int error, name[4], argc, i; 1746 struct argvec *av, **avp; 1747 enum psc_type type; 1748 size_t len; 1749 char *p, **argv; 1750 1751 assert(procstat); 1752 assert(kp); 1753 if (procstat->type == PROCSTAT_KVM) { 1754 warnx("can't use kvm access method"); 1755 return (NULL); 1756 } 1757 if (procstat->type != PROCSTAT_SYSCTL && 1758 procstat->type != PROCSTAT_CORE) { 1759 warnx("unknown access method: %d", procstat->type); 1760 return (NULL); 1761 } 1762 1763 if (nchr == 0 || nchr > ARG_MAX) 1764 nchr = ARG_MAX; 1765 1766 avp = (struct argvec **)(env ? &procstat->argv : &procstat->envv); 1767 av = *avp; 1768 1769 if (av == NULL) 1770 { 1771 av = argvec_alloc(nchr); 1772 if (av == NULL) 1773 { 1774 warn("malloc(%zu)", nchr); 1775 return (NULL); 1776 } 1777 *avp = av; 1778 } else if (av->bufsize < nchr) { 1779 av->buf = reallocf(av->buf, nchr); 1780 if (av->buf == NULL) { 1781 warn("malloc(%zu)", nchr); 1782 return (NULL); 1783 } 1784 } 1785 if (procstat->type == PROCSTAT_SYSCTL) { 1786 name[0] = CTL_KERN; 1787 name[1] = KERN_PROC; 1788 name[2] = env ? KERN_PROC_ENV : KERN_PROC_ARGS; 1789 name[3] = kp->ki_pid; 1790 len = nchr; 1791 error = sysctl(name, nitems(name), av->buf, &len, NULL, 0); 1792 if (error != 0 && errno != ESRCH && errno != EPERM) 1793 warn("sysctl(kern.proc.%s)", env ? "env" : "args"); 1794 if (error != 0 || len == 0) 1795 return (NULL); 1796 } else /* procstat->type == PROCSTAT_CORE */ { 1797 type = env ? PSC_TYPE_ENVV : PSC_TYPE_ARGV; 1798 len = nchr; 1799 if (procstat_core_get(procstat->core, type, av->buf, &len) 1800 == NULL) { 1801 return (NULL); 1802 } 1803 } 1804 1805 argv = av->argv; 1806 argc = av->argc; 1807 i = 0; 1808 for (p = av->buf; p < av->buf + len; p += strlen(p) + 1) { 1809 argv[i++] = p; 1810 if (i < argc) 1811 continue; 1812 /* Grow argv. */ 1813 argc += argc; 1814 argv = realloc(argv, sizeof(char *) * argc); 1815 if (argv == NULL) { 1816 warn("malloc(%zu)", sizeof(char *) * argc); 1817 return (NULL); 1818 } 1819 av->argv = argv; 1820 av->argc = argc; 1821 } 1822 argv[i] = NULL; 1823 1824 return (argv); 1825 } 1826 1827 /* 1828 * Return process command line arguments. 1829 */ 1830 char ** 1831 procstat_getargv(struct procstat *procstat, struct kinfo_proc *p, size_t nchr) 1832 { 1833 1834 return (getargv(procstat, p, nchr, 0)); 1835 } 1836 1837 /* 1838 * Free the buffer allocated by procstat_getargv(). 1839 */ 1840 void 1841 procstat_freeargv(struct procstat *procstat) 1842 { 1843 1844 if (procstat->argv != NULL) { 1845 argvec_free(procstat->argv); 1846 procstat->argv = NULL; 1847 } 1848 } 1849 1850 /* 1851 * Return process environment. 1852 */ 1853 char ** 1854 procstat_getenvv(struct procstat *procstat, struct kinfo_proc *p, size_t nchr) 1855 { 1856 1857 return (getargv(procstat, p, nchr, 1)); 1858 } 1859 1860 /* 1861 * Free the buffer allocated by procstat_getenvv(). 1862 */ 1863 void 1864 procstat_freeenvv(struct procstat *procstat) 1865 { 1866 if (procstat->envv != NULL) { 1867 argvec_free(procstat->envv); 1868 procstat->envv = NULL; 1869 } 1870 } 1871 1872 static struct kinfo_vmentry * 1873 kinfo_getvmmap_core(struct procstat_core *core, int *cntp) 1874 { 1875 int cnt; 1876 size_t len; 1877 char *buf, *bp, *eb; 1878 struct kinfo_vmentry *kiv, *kp, *kv; 1879 1880 buf = procstat_core_get(core, PSC_TYPE_VMMAP, NULL, &len); 1881 if (buf == NULL) 1882 return (NULL); 1883 1884 /* 1885 * XXXMG: The code below is just copy&past from libutil. 1886 * The code duplication can be avoided if libutil 1887 * is extended to provide something like: 1888 * struct kinfo_vmentry *kinfo_getvmmap_from_buf(const char *buf, 1889 * size_t len, int *cntp); 1890 */ 1891 1892 /* Pass 1: count items */ 1893 cnt = 0; 1894 bp = buf; 1895 eb = buf + len; 1896 while (bp < eb) { 1897 kv = (struct kinfo_vmentry *)(uintptr_t)bp; 1898 if (kv->kve_structsize == 0) 1899 break; 1900 bp += kv->kve_structsize; 1901 cnt++; 1902 } 1903 1904 kiv = calloc(cnt, sizeof(*kiv)); 1905 if (kiv == NULL) { 1906 free(buf); 1907 return (NULL); 1908 } 1909 bp = buf; 1910 eb = buf + len; 1911 kp = kiv; 1912 /* Pass 2: unpack */ 1913 while (bp < eb) { 1914 kv = (struct kinfo_vmentry *)(uintptr_t)bp; 1915 if (kv->kve_structsize == 0) 1916 break; 1917 /* Copy/expand into pre-zeroed buffer */ 1918 memcpy(kp, kv, kv->kve_structsize); 1919 /* Advance to next packed record */ 1920 bp += kv->kve_structsize; 1921 /* Set field size to fixed length, advance */ 1922 kp->kve_structsize = sizeof(*kp); 1923 kp++; 1924 } 1925 free(buf); 1926 *cntp = cnt; 1927 return (kiv); /* Caller must free() return value */ 1928 } 1929 1930 struct kinfo_vmentry * 1931 procstat_getvmmap(struct procstat *procstat, struct kinfo_proc *kp, 1932 unsigned int *cntp) 1933 { 1934 1935 switch(procstat->type) { 1936 case PROCSTAT_KVM: 1937 warnx("kvm method is not supported"); 1938 return (NULL); 1939 case PROCSTAT_SYSCTL: 1940 return (kinfo_getvmmap(kp->ki_pid, cntp)); 1941 case PROCSTAT_CORE: 1942 return (kinfo_getvmmap_core(procstat->core, cntp)); 1943 default: 1944 warnx("unknown access method: %d", procstat->type); 1945 return (NULL); 1946 } 1947 } 1948 1949 void 1950 procstat_freevmmap(struct procstat *procstat __unused, 1951 struct kinfo_vmentry *vmmap) 1952 { 1953 1954 free(vmmap); 1955 } 1956 1957 static gid_t * 1958 procstat_getgroups_kvm(kvm_t *kd, struct kinfo_proc *kp, unsigned int *cntp) 1959 { 1960 struct proc proc; 1961 struct ucred ucred; 1962 gid_t *groups; 1963 size_t len; 1964 1965 assert(kd != NULL); 1966 assert(kp != NULL); 1967 if (!kvm_read_all(kd, (unsigned long)kp->ki_paddr, &proc, 1968 sizeof(proc))) { 1969 warnx("can't read proc struct at %p for pid %d", 1970 kp->ki_paddr, kp->ki_pid); 1971 return (NULL); 1972 } 1973 if (proc.p_ucred == NOCRED) 1974 return (NULL); 1975 if (!kvm_read_all(kd, (unsigned long)proc.p_ucred, &ucred, 1976 sizeof(ucred))) { 1977 warnx("can't read ucred struct at %p for pid %d", 1978 proc.p_ucred, kp->ki_pid); 1979 return (NULL); 1980 } 1981 len = ucred.cr_ngroups * sizeof(gid_t); 1982 groups = malloc(len); 1983 if (groups == NULL) { 1984 warn("malloc(%zu)", len); 1985 return (NULL); 1986 } 1987 if (!kvm_read_all(kd, (unsigned long)ucred.cr_groups, groups, len)) { 1988 warnx("can't read groups at %p for pid %d", 1989 ucred.cr_groups, kp->ki_pid); 1990 free(groups); 1991 return (NULL); 1992 } 1993 *cntp = ucred.cr_ngroups; 1994 return (groups); 1995 } 1996 1997 static gid_t * 1998 procstat_getgroups_sysctl(pid_t pid, unsigned int *cntp) 1999 { 2000 int mib[4]; 2001 size_t len; 2002 gid_t *groups; 2003 2004 mib[0] = CTL_KERN; 2005 mib[1] = KERN_PROC; 2006 mib[2] = KERN_PROC_GROUPS; 2007 mib[3] = pid; 2008 len = (sysconf(_SC_NGROUPS_MAX) + 1) * sizeof(gid_t); 2009 groups = malloc(len); 2010 if (groups == NULL) { 2011 warn("malloc(%zu)", len); 2012 return (NULL); 2013 } 2014 if (sysctl(mib, nitems(mib), groups, &len, NULL, 0) == -1) { 2015 warn("sysctl: kern.proc.groups: %d", pid); 2016 free(groups); 2017 return (NULL); 2018 } 2019 *cntp = len / sizeof(gid_t); 2020 return (groups); 2021 } 2022 2023 static gid_t * 2024 procstat_getgroups_core(struct procstat_core *core, unsigned int *cntp) 2025 { 2026 size_t len; 2027 gid_t *groups; 2028 2029 groups = procstat_core_get(core, PSC_TYPE_GROUPS, NULL, &len); 2030 if (groups == NULL) 2031 return (NULL); 2032 *cntp = len / sizeof(gid_t); 2033 return (groups); 2034 } 2035 2036 gid_t * 2037 procstat_getgroups(struct procstat *procstat, struct kinfo_proc *kp, 2038 unsigned int *cntp) 2039 { 2040 switch(procstat->type) { 2041 case PROCSTAT_KVM: 2042 return (procstat_getgroups_kvm(procstat->kd, kp, cntp)); 2043 case PROCSTAT_SYSCTL: 2044 return (procstat_getgroups_sysctl(kp->ki_pid, cntp)); 2045 case PROCSTAT_CORE: 2046 return (procstat_getgroups_core(procstat->core, cntp)); 2047 default: 2048 warnx("unknown access method: %d", procstat->type); 2049 return (NULL); 2050 } 2051 } 2052 2053 void 2054 procstat_freegroups(struct procstat *procstat __unused, gid_t *groups) 2055 { 2056 2057 free(groups); 2058 } 2059 2060 static int 2061 procstat_getumask_kvm(kvm_t *kd, struct kinfo_proc *kp, unsigned short *maskp) 2062 { 2063 struct filedesc fd; 2064 2065 assert(kd != NULL); 2066 assert(kp != NULL); 2067 if (kp->ki_fd == NULL) 2068 return (-1); 2069 if (!kvm_read_all(kd, (unsigned long)kp->ki_fd, &fd, sizeof(fd))) { 2070 warnx("can't read filedesc at %p for pid %d", kp->ki_fd, 2071 kp->ki_pid); 2072 return (-1); 2073 } 2074 *maskp = fd.fd_cmask; 2075 return (0); 2076 } 2077 2078 static int 2079 procstat_getumask_sysctl(pid_t pid, unsigned short *maskp) 2080 { 2081 int error; 2082 int mib[4]; 2083 size_t len; 2084 2085 mib[0] = CTL_KERN; 2086 mib[1] = KERN_PROC; 2087 mib[2] = KERN_PROC_UMASK; 2088 mib[3] = pid; 2089 len = sizeof(*maskp); 2090 error = sysctl(mib, nitems(mib), maskp, &len, NULL, 0); 2091 if (error != 0 && errno != ESRCH && errno != EPERM) 2092 warn("sysctl: kern.proc.umask: %d", pid); 2093 return (error); 2094 } 2095 2096 static int 2097 procstat_getumask_core(struct procstat_core *core, unsigned short *maskp) 2098 { 2099 size_t len; 2100 unsigned short *buf; 2101 2102 buf = procstat_core_get(core, PSC_TYPE_UMASK, NULL, &len); 2103 if (buf == NULL) 2104 return (-1); 2105 if (len < sizeof(*maskp)) { 2106 free(buf); 2107 return (-1); 2108 } 2109 *maskp = *buf; 2110 free(buf); 2111 return (0); 2112 } 2113 2114 int 2115 procstat_getumask(struct procstat *procstat, struct kinfo_proc *kp, 2116 unsigned short *maskp) 2117 { 2118 switch(procstat->type) { 2119 case PROCSTAT_KVM: 2120 return (procstat_getumask_kvm(procstat->kd, kp, maskp)); 2121 case PROCSTAT_SYSCTL: 2122 return (procstat_getumask_sysctl(kp->ki_pid, maskp)); 2123 case PROCSTAT_CORE: 2124 return (procstat_getumask_core(procstat->core, maskp)); 2125 default: 2126 warnx("unknown access method: %d", procstat->type); 2127 return (-1); 2128 } 2129 } 2130 2131 static int 2132 procstat_getrlimit_kvm(kvm_t *kd, struct kinfo_proc *kp, int which, 2133 struct rlimit* rlimit) 2134 { 2135 struct proc proc; 2136 unsigned long offset; 2137 2138 assert(kd != NULL); 2139 assert(kp != NULL); 2140 assert(which >= 0 && which < RLIM_NLIMITS); 2141 if (!kvm_read_all(kd, (unsigned long)kp->ki_paddr, &proc, 2142 sizeof(proc))) { 2143 warnx("can't read proc struct at %p for pid %d", 2144 kp->ki_paddr, kp->ki_pid); 2145 return (-1); 2146 } 2147 if (proc.p_limit == NULL) 2148 return (-1); 2149 offset = (unsigned long)proc.p_limit + sizeof(struct rlimit) * which; 2150 if (!kvm_read_all(kd, offset, rlimit, sizeof(*rlimit))) { 2151 warnx("can't read rlimit struct at %p for pid %d", 2152 (void *)offset, kp->ki_pid); 2153 return (-1); 2154 } 2155 return (0); 2156 } 2157 2158 static int 2159 procstat_getrlimit_sysctl(pid_t pid, int which, struct rlimit* rlimit) 2160 { 2161 int error, name[5]; 2162 size_t len; 2163 2164 name[0] = CTL_KERN; 2165 name[1] = KERN_PROC; 2166 name[2] = KERN_PROC_RLIMIT; 2167 name[3] = pid; 2168 name[4] = which; 2169 len = sizeof(struct rlimit); 2170 error = sysctl(name, nitems(name), rlimit, &len, NULL, 0); 2171 if (error < 0 && errno != ESRCH) { 2172 warn("sysctl: kern.proc.rlimit: %d", pid); 2173 return (-1); 2174 } 2175 if (error < 0 || len != sizeof(struct rlimit)) 2176 return (-1); 2177 return (0); 2178 } 2179 2180 static int 2181 procstat_getrlimit_core(struct procstat_core *core, int which, 2182 struct rlimit* rlimit) 2183 { 2184 size_t len; 2185 struct rlimit* rlimits; 2186 2187 if (which < 0 || which >= RLIM_NLIMITS) { 2188 errno = EINVAL; 2189 warn("getrlimit: which"); 2190 return (-1); 2191 } 2192 rlimits = procstat_core_get(core, PSC_TYPE_RLIMIT, NULL, &len); 2193 if (rlimits == NULL) 2194 return (-1); 2195 if (len < sizeof(struct rlimit) * RLIM_NLIMITS) { 2196 free(rlimits); 2197 return (-1); 2198 } 2199 *rlimit = rlimits[which]; 2200 free(rlimits); 2201 return (0); 2202 } 2203 2204 int 2205 procstat_getrlimit(struct procstat *procstat, struct kinfo_proc *kp, int which, 2206 struct rlimit* rlimit) 2207 { 2208 switch(procstat->type) { 2209 case PROCSTAT_KVM: 2210 return (procstat_getrlimit_kvm(procstat->kd, kp, which, 2211 rlimit)); 2212 case PROCSTAT_SYSCTL: 2213 return (procstat_getrlimit_sysctl(kp->ki_pid, which, rlimit)); 2214 case PROCSTAT_CORE: 2215 return (procstat_getrlimit_core(procstat->core, which, rlimit)); 2216 default: 2217 warnx("unknown access method: %d", procstat->type); 2218 return (-1); 2219 } 2220 } 2221 2222 static int 2223 procstat_getpathname_sysctl(pid_t pid, char *pathname, size_t maxlen) 2224 { 2225 int error, name[4]; 2226 size_t len; 2227 2228 name[0] = CTL_KERN; 2229 name[1] = KERN_PROC; 2230 name[2] = KERN_PROC_PATHNAME; 2231 name[3] = pid; 2232 len = maxlen; 2233 error = sysctl(name, nitems(name), pathname, &len, NULL, 0); 2234 if (error != 0 && errno != ESRCH) 2235 warn("sysctl: kern.proc.pathname: %d", pid); 2236 if (len == 0) 2237 pathname[0] = '\0'; 2238 return (error); 2239 } 2240 2241 static int 2242 procstat_getpathname_core(struct procstat_core *core, char *pathname, 2243 size_t maxlen) 2244 { 2245 struct kinfo_file *files; 2246 int cnt, i, result; 2247 2248 files = kinfo_getfile_core(core, &cnt); 2249 if (files == NULL) 2250 return (-1); 2251 result = -1; 2252 for (i = 0; i < cnt; i++) { 2253 if (files[i].kf_fd != KF_FD_TYPE_TEXT) 2254 continue; 2255 strncpy(pathname, files[i].kf_path, maxlen); 2256 result = 0; 2257 break; 2258 } 2259 free(files); 2260 return (result); 2261 } 2262 2263 int 2264 procstat_getpathname(struct procstat *procstat, struct kinfo_proc *kp, 2265 char *pathname, size_t maxlen) 2266 { 2267 switch(procstat->type) { 2268 case PROCSTAT_KVM: 2269 /* XXX: Return empty string. */ 2270 if (maxlen > 0) 2271 pathname[0] = '\0'; 2272 return (0); 2273 case PROCSTAT_SYSCTL: 2274 return (procstat_getpathname_sysctl(kp->ki_pid, pathname, 2275 maxlen)); 2276 case PROCSTAT_CORE: 2277 return (procstat_getpathname_core(procstat->core, pathname, 2278 maxlen)); 2279 default: 2280 warnx("unknown access method: %d", procstat->type); 2281 return (-1); 2282 } 2283 } 2284 2285 static int 2286 procstat_getosrel_kvm(kvm_t *kd, struct kinfo_proc *kp, int *osrelp) 2287 { 2288 struct proc proc; 2289 2290 assert(kd != NULL); 2291 assert(kp != NULL); 2292 if (!kvm_read_all(kd, (unsigned long)kp->ki_paddr, &proc, 2293 sizeof(proc))) { 2294 warnx("can't read proc struct at %p for pid %d", 2295 kp->ki_paddr, kp->ki_pid); 2296 return (-1); 2297 } 2298 *osrelp = proc.p_osrel; 2299 return (0); 2300 } 2301 2302 static int 2303 procstat_getosrel_sysctl(pid_t pid, int *osrelp) 2304 { 2305 int error, name[4]; 2306 size_t len; 2307 2308 name[0] = CTL_KERN; 2309 name[1] = KERN_PROC; 2310 name[2] = KERN_PROC_OSREL; 2311 name[3] = pid; 2312 len = sizeof(*osrelp); 2313 error = sysctl(name, nitems(name), osrelp, &len, NULL, 0); 2314 if (error != 0 && errno != ESRCH) 2315 warn("sysctl: kern.proc.osrel: %d", pid); 2316 return (error); 2317 } 2318 2319 static int 2320 procstat_getosrel_core(struct procstat_core *core, int *osrelp) 2321 { 2322 size_t len; 2323 int *buf; 2324 2325 buf = procstat_core_get(core, PSC_TYPE_OSREL, NULL, &len); 2326 if (buf == NULL) 2327 return (-1); 2328 if (len < sizeof(*osrelp)) { 2329 free(buf); 2330 return (-1); 2331 } 2332 *osrelp = *buf; 2333 free(buf); 2334 return (0); 2335 } 2336 2337 int 2338 procstat_getosrel(struct procstat *procstat, struct kinfo_proc *kp, int *osrelp) 2339 { 2340 switch(procstat->type) { 2341 case PROCSTAT_KVM: 2342 return (procstat_getosrel_kvm(procstat->kd, kp, osrelp)); 2343 case PROCSTAT_SYSCTL: 2344 return (procstat_getosrel_sysctl(kp->ki_pid, osrelp)); 2345 case PROCSTAT_CORE: 2346 return (procstat_getosrel_core(procstat->core, osrelp)); 2347 default: 2348 warnx("unknown access method: %d", procstat->type); 2349 return (-1); 2350 } 2351 } 2352 2353 #define PROC_AUXV_MAX 256 2354 2355 #if __ELF_WORD_SIZE == 64 2356 static const char *elf32_sv_names[] = { 2357 "Linux ELF32", 2358 "FreeBSD ELF32", 2359 }; 2360 2361 static int 2362 is_elf32_sysctl(pid_t pid) 2363 { 2364 int error, name[4]; 2365 size_t len, i; 2366 static char sv_name[256]; 2367 2368 name[0] = CTL_KERN; 2369 name[1] = KERN_PROC; 2370 name[2] = KERN_PROC_SV_NAME; 2371 name[3] = pid; 2372 len = sizeof(sv_name); 2373 error = sysctl(name, nitems(name), sv_name, &len, NULL, 0); 2374 if (error != 0 || len == 0) 2375 return (0); 2376 for (i = 0; i < sizeof(elf32_sv_names) / sizeof(*elf32_sv_names); i++) { 2377 if (strncmp(sv_name, elf32_sv_names[i], sizeof(sv_name)) == 0) 2378 return (1); 2379 } 2380 return (0); 2381 } 2382 2383 static Elf_Auxinfo * 2384 procstat_getauxv32_sysctl(pid_t pid, unsigned int *cntp) 2385 { 2386 Elf_Auxinfo *auxv; 2387 Elf32_Auxinfo *auxv32; 2388 void *ptr; 2389 size_t len; 2390 unsigned int i, count; 2391 int name[4]; 2392 2393 name[0] = CTL_KERN; 2394 name[1] = KERN_PROC; 2395 name[2] = KERN_PROC_AUXV; 2396 name[3] = pid; 2397 len = PROC_AUXV_MAX * sizeof(Elf32_Auxinfo); 2398 auxv = NULL; 2399 auxv32 = malloc(len); 2400 if (auxv32 == NULL) { 2401 warn("malloc(%zu)", len); 2402 goto out; 2403 } 2404 if (sysctl(name, nitems(name), auxv32, &len, NULL, 0) == -1) { 2405 if (errno != ESRCH && errno != EPERM) 2406 warn("sysctl: kern.proc.auxv: %d: %d", pid, errno); 2407 goto out; 2408 } 2409 count = len / sizeof(Elf_Auxinfo); 2410 auxv = malloc(count * sizeof(Elf_Auxinfo)); 2411 if (auxv == NULL) { 2412 warn("malloc(%zu)", count * sizeof(Elf_Auxinfo)); 2413 goto out; 2414 } 2415 for (i = 0; i < count; i++) { 2416 /* 2417 * XXX: We expect that values for a_type on a 32-bit platform 2418 * are directly mapped to values on 64-bit one, which is not 2419 * necessarily true. 2420 */ 2421 auxv[i].a_type = auxv32[i].a_type; 2422 ptr = &auxv32[i].a_un; 2423 auxv[i].a_un.a_val = *((uint32_t *)ptr); 2424 } 2425 *cntp = count; 2426 out: 2427 free(auxv32); 2428 return (auxv); 2429 } 2430 #endif /* __ELF_WORD_SIZE == 64 */ 2431 2432 static Elf_Auxinfo * 2433 procstat_getauxv_sysctl(pid_t pid, unsigned int *cntp) 2434 { 2435 Elf_Auxinfo *auxv; 2436 int name[4]; 2437 size_t len; 2438 2439 #if __ELF_WORD_SIZE == 64 2440 if (is_elf32_sysctl(pid)) 2441 return (procstat_getauxv32_sysctl(pid, cntp)); 2442 #endif 2443 name[0] = CTL_KERN; 2444 name[1] = KERN_PROC; 2445 name[2] = KERN_PROC_AUXV; 2446 name[3] = pid; 2447 len = PROC_AUXV_MAX * sizeof(Elf_Auxinfo); 2448 auxv = malloc(len); 2449 if (auxv == NULL) { 2450 warn("malloc(%zu)", len); 2451 return (NULL); 2452 } 2453 if (sysctl(name, nitems(name), auxv, &len, NULL, 0) == -1) { 2454 if (errno != ESRCH && errno != EPERM) 2455 warn("sysctl: kern.proc.auxv: %d: %d", pid, errno); 2456 free(auxv); 2457 return (NULL); 2458 } 2459 *cntp = len / sizeof(Elf_Auxinfo); 2460 return (auxv); 2461 } 2462 2463 static Elf_Auxinfo * 2464 procstat_getauxv_core(struct procstat_core *core, unsigned int *cntp) 2465 { 2466 Elf_Auxinfo *auxv; 2467 size_t len; 2468 2469 auxv = procstat_core_get(core, PSC_TYPE_AUXV, NULL, &len); 2470 if (auxv == NULL) 2471 return (NULL); 2472 *cntp = len / sizeof(Elf_Auxinfo); 2473 return (auxv); 2474 } 2475 2476 Elf_Auxinfo * 2477 procstat_getauxv(struct procstat *procstat, struct kinfo_proc *kp, 2478 unsigned int *cntp) 2479 { 2480 switch(procstat->type) { 2481 case PROCSTAT_KVM: 2482 warnx("kvm method is not supported"); 2483 return (NULL); 2484 case PROCSTAT_SYSCTL: 2485 return (procstat_getauxv_sysctl(kp->ki_pid, cntp)); 2486 case PROCSTAT_CORE: 2487 return (procstat_getauxv_core(procstat->core, cntp)); 2488 default: 2489 warnx("unknown access method: %d", procstat->type); 2490 return (NULL); 2491 } 2492 } 2493 2494 void 2495 procstat_freeauxv(struct procstat *procstat __unused, Elf_Auxinfo *auxv) 2496 { 2497 2498 free(auxv); 2499 } 2500 2501 static struct ptrace_lwpinfo * 2502 procstat_getptlwpinfo_core(struct procstat_core *core, unsigned int *cntp) 2503 { 2504 void *buf; 2505 struct ptrace_lwpinfo *pl; 2506 unsigned int cnt; 2507 size_t len; 2508 2509 cnt = procstat_core_note_count(core, PSC_TYPE_PTLWPINFO); 2510 if (cnt == 0) 2511 return (NULL); 2512 2513 len = cnt * sizeof(*pl); 2514 buf = calloc(1, len); 2515 pl = procstat_core_get(core, PSC_TYPE_PTLWPINFO, buf, &len); 2516 if (pl == NULL) { 2517 free(buf); 2518 return (NULL); 2519 } 2520 *cntp = len / sizeof(*pl); 2521 return (pl); 2522 } 2523 2524 struct ptrace_lwpinfo * 2525 procstat_getptlwpinfo(struct procstat *procstat, unsigned int *cntp) 2526 { 2527 switch (procstat->type) { 2528 case PROCSTAT_KVM: 2529 warnx("kvm method is not supported"); 2530 return (NULL); 2531 case PROCSTAT_SYSCTL: 2532 warnx("sysctl method is not supported"); 2533 return (NULL); 2534 case PROCSTAT_CORE: 2535 return (procstat_getptlwpinfo_core(procstat->core, cntp)); 2536 default: 2537 warnx("unknown access method: %d", procstat->type); 2538 return (NULL); 2539 } 2540 } 2541 2542 void 2543 procstat_freeptlwpinfo(struct procstat *procstat __unused, 2544 struct ptrace_lwpinfo *pl) 2545 { 2546 free(pl); 2547 } 2548 2549 static struct kinfo_kstack * 2550 procstat_getkstack_sysctl(pid_t pid, int *cntp) 2551 { 2552 struct kinfo_kstack *kkstp; 2553 int error, name[4]; 2554 size_t len; 2555 2556 name[0] = CTL_KERN; 2557 name[1] = KERN_PROC; 2558 name[2] = KERN_PROC_KSTACK; 2559 name[3] = pid; 2560 2561 len = 0; 2562 error = sysctl(name, nitems(name), NULL, &len, NULL, 0); 2563 if (error < 0 && errno != ESRCH && errno != EPERM && errno != ENOENT) { 2564 warn("sysctl: kern.proc.kstack: %d", pid); 2565 return (NULL); 2566 } 2567 if (error == -1 && errno == ENOENT) { 2568 warnx("sysctl: kern.proc.kstack unavailable" 2569 " (options DDB or options STACK required in kernel)"); 2570 return (NULL); 2571 } 2572 if (error == -1) 2573 return (NULL); 2574 kkstp = malloc(len); 2575 if (kkstp == NULL) { 2576 warn("malloc(%zu)", len); 2577 return (NULL); 2578 } 2579 if (sysctl(name, nitems(name), kkstp, &len, NULL, 0) == -1) { 2580 warn("sysctl: kern.proc.pid: %d", pid); 2581 free(kkstp); 2582 return (NULL); 2583 } 2584 *cntp = len / sizeof(*kkstp); 2585 2586 return (kkstp); 2587 } 2588 2589 struct kinfo_kstack * 2590 procstat_getkstack(struct procstat *procstat, struct kinfo_proc *kp, 2591 unsigned int *cntp) 2592 { 2593 switch(procstat->type) { 2594 case PROCSTAT_KVM: 2595 warnx("kvm method is not supported"); 2596 return (NULL); 2597 case PROCSTAT_SYSCTL: 2598 return (procstat_getkstack_sysctl(kp->ki_pid, cntp)); 2599 case PROCSTAT_CORE: 2600 warnx("core method is not supported"); 2601 return (NULL); 2602 default: 2603 warnx("unknown access method: %d", procstat->type); 2604 return (NULL); 2605 } 2606 } 2607 2608 void 2609 procstat_freekstack(struct procstat *procstat __unused, 2610 struct kinfo_kstack *kkstp) 2611 { 2612 2613 free(kkstp); 2614 } 2615