1 /* $NetBSD: procfs_vnops.c,v 1.227 2022/01/17 11:20:00 bouyer Exp $ */ 2 3 /*- 4 * Copyright (c) 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * Copyright (c) 1993, 1995 34 * The Regents of the University of California. All rights reserved. 35 * 36 * This code is derived from software contributed to Berkeley by 37 * Jan-Simon Pendry. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 3. Neither the name of the University nor the names of its contributors 48 * may be used to endorse or promote products derived from this software 49 * without specific prior written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * SUCH DAMAGE. 62 * 63 * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 64 */ 65 66 /* 67 * Copyright (c) 1993 Jan-Simon Pendry 68 * 69 * This code is derived from software contributed to Berkeley by 70 * Jan-Simon Pendry. 71 * 72 * Redistribution and use in source and binary forms, with or without 73 * modification, are permitted provided that the following conditions 74 * are met: 75 * 1. Redistributions of source code must retain the above copyright 76 * notice, this list of conditions and the following disclaimer. 77 * 2. Redistributions in binary form must reproduce the above copyright 78 * notice, this list of conditions and the following disclaimer in the 79 * documentation and/or other materials provided with the distribution. 80 * 3. All advertising materials mentioning features or use of this software 81 * must display the following acknowledgement: 82 * This product includes software developed by the University of 83 * California, Berkeley and its contributors. 84 * 4. Neither the name of the University nor the names of its contributors 85 * may be used to endorse or promote products derived from this software 86 * without specific prior written permission. 87 * 88 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 89 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 90 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 91 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 92 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 93 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 94 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 95 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 96 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 97 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 98 * SUCH DAMAGE. 99 * 100 * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 101 */ 102 103 /* 104 * procfs vnode interface 105 */ 106 107 #include <sys/cdefs.h> 108 __KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.227 2022/01/17 11:20:00 bouyer Exp $"); 109 110 #include <sys/param.h> 111 #include <sys/atomic.h> 112 #include <sys/systm.h> 113 #include <sys/time.h> 114 #include <sys/kernel.h> 115 #include <sys/file.h> 116 #include <sys/filedesc.h> 117 #include <sys/proc.h> 118 #include <sys/vnode.h> 119 #include <sys/namei.h> 120 #include <sys/malloc.h> 121 #include <sys/mount.h> 122 #include <sys/dirent.h> 123 #include <sys/resourcevar.h> 124 #include <sys/stat.h> 125 #include <sys/ptrace.h> 126 #include <sys/kauth.h> 127 #include <sys/exec.h> 128 129 #include <uvm/uvm_extern.h> /* for PAGE_SIZE */ 130 131 #include <machine/reg.h> 132 133 #include <miscfs/genfs/genfs.h> 134 #include <miscfs/procfs/procfs.h> 135 136 /* 137 * Vnode Operations. 138 * 139 */ 140 141 static int procfs_validfile_linux(struct lwp *, struct mount *); 142 static int procfs_root_readdir_callback(struct proc *, void *); 143 static void procfs_dir(pfstype, struct lwp *, struct proc *, char **, char *, 144 size_t); 145 146 /* 147 * This is a list of the valid names in the 148 * process-specific sub-directories. It is 149 * used in procfs_lookup and procfs_readdir 150 */ 151 static const struct proc_target { 152 u_char pt_type; 153 u_char pt_namlen; 154 const char *pt_name; 155 pfstype pt_pfstype; 156 int (*pt_valid)(struct lwp *, struct mount *); 157 } proc_targets[] = { 158 #define N(s) sizeof(s)-1, s 159 /* name type validp */ 160 { DT_DIR, N("."), PFSproc, NULL }, 161 { DT_DIR, N(".."), PFSroot, NULL }, 162 { DT_DIR, N("fd"), PFSfd, NULL }, 163 { DT_DIR, N("task"), PFStask, procfs_validfile_linux }, 164 { DT_LNK, N("cwd"), PFScwd, NULL }, 165 { DT_REG, N("emul"), PFSemul, NULL }, 166 { DT_LNK, N("root"), PFSchroot, NULL }, 167 { DT_REG, N("auxv"), PFSauxv, procfs_validauxv }, 168 { DT_REG, N("cmdline"), PFScmdline, NULL }, 169 { DT_REG, N("environ"), PFSenviron, NULL }, 170 { DT_LNK, N("exe"), PFSexe, procfs_validfile }, 171 { DT_REG, N("file"), PFSfile, procfs_validfile }, 172 { DT_REG, N("fpregs"), PFSfpregs, procfs_validfpregs }, 173 { DT_REG, N("limit"), PFSlimit, NULL }, 174 { DT_REG, N("map"), PFSmap, procfs_validmap }, 175 { DT_REG, N("maps"), PFSmaps, procfs_validmap }, 176 { DT_REG, N("mem"), PFSmem, NULL }, 177 { DT_REG, N("note"), PFSnote, NULL }, 178 { DT_REG, N("notepg"), PFSnotepg, NULL }, 179 { DT_REG, N("regs"), PFSregs, procfs_validregs }, 180 { DT_REG, N("stat"), PFSstat, procfs_validfile_linux }, 181 { DT_REG, N("statm"), PFSstatm, procfs_validfile_linux }, 182 { DT_REG, N("status"), PFSstatus, NULL }, 183 #ifdef __HAVE_PROCFS_MACHDEP 184 PROCFS_MACHDEP_NODETYPE_DEFNS 185 #endif 186 #undef N 187 }; 188 static const int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]); 189 190 /* 191 * List of files in the root directory. Note: the validate function will 192 * be called with p == NULL for these ones. 193 */ 194 static const struct proc_target proc_root_targets[] = { 195 #define N(s) sizeof(s)-1, s 196 /* name type validp */ 197 { DT_REG, N("meminfo"), PFSmeminfo, procfs_validfile_linux }, 198 { DT_REG, N("cpuinfo"), PFScpuinfo, procfs_validfile_linux }, 199 { DT_REG, N("uptime"), PFSuptime, procfs_validfile_linux }, 200 { DT_REG, N("mounts"), PFSmounts, procfs_validfile_linux }, 201 { DT_REG, N("devices"), PFSdevices, procfs_validfile_linux }, 202 { DT_REG, N("stat"), PFScpustat, procfs_validfile_linux }, 203 { DT_REG, N("loadavg"), PFSloadavg, procfs_validfile_linux }, 204 { DT_REG, N("version"), PFSversion, procfs_validfile_linux }, 205 #undef N 206 }; 207 static const int nproc_root_targets = 208 sizeof(proc_root_targets) / sizeof(proc_root_targets[0]); 209 210 int procfs_lookup(void *); 211 int procfs_open(void *); 212 int procfs_close(void *); 213 int procfs_access(void *); 214 int procfs_getattr(void *); 215 int procfs_setattr(void *); 216 int procfs_link(void *); 217 int procfs_symlink(void *); 218 int procfs_readdir(void *); 219 int procfs_readlink(void *); 220 int procfs_inactive(void *); 221 int procfs_reclaim(void *); 222 int procfs_print(void *); 223 int procfs_pathconf(void *); 224 int procfs_getpages(void *); 225 226 static uint8_t fttodt(file_t *); 227 static int atoi(const char *, size_t); 228 229 /* 230 * procfs vnode operations. 231 */ 232 int (**procfs_vnodeop_p)(void *); 233 const struct vnodeopv_entry_desc procfs_vnodeop_entries[] = { 234 { &vop_default_desc, vn_default_error }, 235 { &vop_parsepath_desc, genfs_parsepath }, /* parsepath */ 236 { &vop_lookup_desc, procfs_lookup }, /* lookup */ 237 { &vop_create_desc, genfs_eopnotsupp }, /* create */ 238 { &vop_mknod_desc, genfs_eopnotsupp }, /* mknod */ 239 { &vop_open_desc, procfs_open }, /* open */ 240 { &vop_close_desc, procfs_close }, /* close */ 241 { &vop_access_desc, procfs_access }, /* access */ 242 { &vop_accessx_desc, genfs_accessx }, /* accessx */ 243 { &vop_getattr_desc, procfs_getattr }, /* getattr */ 244 { &vop_setattr_desc, procfs_setattr }, /* setattr */ 245 { &vop_read_desc, procfs_rw }, /* read */ 246 { &vop_write_desc, procfs_rw }, /* write */ 247 { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ 248 { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ 249 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ 250 { &vop_ioctl_desc, genfs_enoioctl }, /* ioctl */ 251 { &vop_poll_desc, genfs_poll }, /* poll */ 252 { &vop_kqfilter_desc, genfs_kqfilter }, /* kqfilter */ 253 { &vop_revoke_desc, genfs_revoke }, /* revoke */ 254 { &vop_fsync_desc, genfs_nullop }, /* fsync */ 255 { &vop_seek_desc, genfs_nullop }, /* seek */ 256 { &vop_remove_desc, genfs_eopnotsupp }, /* remove */ 257 { &vop_link_desc, procfs_link }, /* link */ 258 { &vop_rename_desc, genfs_eopnotsupp }, /* rename */ 259 { &vop_mkdir_desc, genfs_eopnotsupp }, /* mkdir */ 260 { &vop_rmdir_desc, genfs_eopnotsupp }, /* rmdir */ 261 { &vop_symlink_desc, procfs_symlink }, /* symlink */ 262 { &vop_readdir_desc, procfs_readdir }, /* readdir */ 263 { &vop_readlink_desc, procfs_readlink }, /* readlink */ 264 { &vop_abortop_desc, genfs_abortop }, /* abortop */ 265 { &vop_inactive_desc, procfs_inactive }, /* inactive */ 266 { &vop_reclaim_desc, procfs_reclaim }, /* reclaim */ 267 { &vop_lock_desc, genfs_lock }, /* lock */ 268 { &vop_unlock_desc, genfs_unlock }, /* unlock */ 269 { &vop_bmap_desc, genfs_eopnotsupp }, /* bmap */ 270 { &vop_strategy_desc, genfs_badop }, /* strategy */ 271 { &vop_print_desc, procfs_print }, /* print */ 272 { &vop_islocked_desc, genfs_islocked }, /* islocked */ 273 { &vop_pathconf_desc, procfs_pathconf }, /* pathconf */ 274 { &vop_advlock_desc, genfs_einval }, /* advlock */ 275 { &vop_getpages_desc, procfs_getpages }, /* getpages */ 276 { &vop_putpages_desc, genfs_null_putpages }, /* putpages */ 277 { NULL, NULL } 278 }; 279 const struct vnodeopv_desc procfs_vnodeop_opv_desc = 280 { &procfs_vnodeop_p, procfs_vnodeop_entries }; 281 /* 282 * set things up for doing i/o on 283 * the pfsnode (vp). (vp) is locked 284 * on entry, and should be left locked 285 * on exit. 286 * 287 * for procfs we don't need to do anything 288 * in particular for i/o. all that is done 289 * is to support exclusive open on process 290 * memory images. 291 */ 292 int 293 procfs_open(void *v) 294 { 295 struct vop_open_args /* { 296 struct vnode *a_vp; 297 int a_mode; 298 kauth_cred_t a_cred; 299 } */ *ap = v; 300 struct vnode *vp = ap->a_vp; 301 struct pfsnode *pfs = VTOPFS(vp); 302 struct lwp *l1; 303 struct proc *p2; 304 int error; 305 306 if ((error = 307 procfs_proc_lock(vp->v_mount, pfs->pfs_pid, &p2, ENOENT)) != 0) 308 return error; 309 310 l1 = curlwp; /* tracer */ 311 312 #define M2K(m) (((m) & FREAD) && ((m) & FWRITE) ? \ 313 KAUTH_REQ_PROCESS_PROCFS_RW : \ 314 (m) & FWRITE ? KAUTH_REQ_PROCESS_PROCFS_WRITE : \ 315 KAUTH_REQ_PROCESS_PROCFS_READ) 316 317 mutex_enter(p2->p_lock); 318 error = kauth_authorize_process(l1->l_cred, KAUTH_PROCESS_PROCFS, 319 p2, pfs, KAUTH_ARG(M2K(ap->a_mode)), NULL); 320 mutex_exit(p2->p_lock); 321 if (error) { 322 procfs_proc_unlock(p2); 323 return (error); 324 } 325 326 #undef M2K 327 328 switch (pfs->pfs_type) { 329 case PFSmem: 330 if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) || 331 ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))) { 332 error = EBUSY; 333 break; 334 } 335 336 if (!proc_isunder(p2, l1)) { 337 error = EPERM; 338 break; 339 } 340 341 if (ap->a_mode & FWRITE) 342 pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL); 343 344 break; 345 346 case PFSregs: 347 case PFSfpregs: 348 if (!proc_isunder(p2, l1)) { 349 error = EPERM; 350 break; 351 } 352 break; 353 354 default: 355 break; 356 } 357 358 procfs_proc_unlock(p2); 359 return (error); 360 } 361 362 /* 363 * close the pfsnode (vp) after doing i/o. 364 * (vp) is not locked on entry or exit. 365 * 366 * nothing to do for procfs other than undo 367 * any exclusive open flag (see _open above). 368 */ 369 int 370 procfs_close(void *v) 371 { 372 struct vop_close_args /* { 373 struct vnode *a_vp; 374 int a_fflag; 375 kauth_cred_t a_cred; 376 } */ *ap = v; 377 struct pfsnode *pfs = VTOPFS(ap->a_vp); 378 379 switch (pfs->pfs_type) { 380 case PFSmem: 381 if ((ap->a_fflag & FWRITE) && (pfs->pfs_flags & O_EXCL)) 382 pfs->pfs_flags &= ~(FWRITE|O_EXCL); 383 break; 384 385 default: 386 break; 387 } 388 389 return (0); 390 } 391 392 /* 393 * _inactive is called when the pfsnode 394 * is vrele'd and the reference count goes 395 * to zero. (vp) will be on the vnode free 396 * list, so to get it back vget() must be 397 * used. 398 * 399 * (vp) is locked on entry, but must be unlocked on exit. 400 */ 401 int 402 procfs_inactive(void *v) 403 { 404 struct vop_inactive_v2_args /* { 405 struct vnode *a_vp; 406 bool *a_recycle; 407 } */ *ap = v; 408 struct vnode *vp = ap->a_vp; 409 struct pfsnode *pfs = VTOPFS(vp); 410 411 mutex_enter(&proc_lock); 412 *ap->a_recycle = (procfs_proc_find(vp->v_mount, pfs->pfs_pid) == NULL); 413 mutex_exit(&proc_lock); 414 415 return (0); 416 } 417 418 /* 419 * _reclaim is called when getnewvnode() 420 * wants to make use of an entry on the vnode 421 * free list. at this time the filesystem needs 422 * to free any private data and remove the node 423 * from any private lists. 424 */ 425 int 426 procfs_reclaim(void *v) 427 { 428 struct vop_reclaim_v2_args /* { 429 struct vnode *a_vp; 430 } */ *ap = v; 431 struct vnode *vp = ap->a_vp; 432 struct pfsnode *pfs = VTOPFS(vp); 433 434 VOP_UNLOCK(vp); 435 436 /* 437 * To interlock with procfs_revoke_vnodes(). 438 */ 439 mutex_enter(vp->v_interlock); 440 vp->v_data = NULL; 441 mutex_exit(vp->v_interlock); 442 kmem_free(pfs, sizeof(*pfs)); 443 return 0; 444 } 445 446 /* 447 * Return POSIX pathconf information applicable to special devices. 448 */ 449 int 450 procfs_pathconf(void *v) 451 { 452 struct vop_pathconf_args /* { 453 struct vnode *a_vp; 454 int a_name; 455 register_t *a_retval; 456 } */ *ap = v; 457 458 switch (ap->a_name) { 459 case _PC_LINK_MAX: 460 *ap->a_retval = LINK_MAX; 461 return (0); 462 case _PC_MAX_CANON: 463 *ap->a_retval = MAX_CANON; 464 return (0); 465 case _PC_MAX_INPUT: 466 *ap->a_retval = MAX_INPUT; 467 return (0); 468 case _PC_PIPE_BUF: 469 *ap->a_retval = PIPE_BUF; 470 return (0); 471 case _PC_CHOWN_RESTRICTED: 472 *ap->a_retval = 1; 473 return (0); 474 case _PC_VDISABLE: 475 *ap->a_retval = _POSIX_VDISABLE; 476 return (0); 477 case _PC_SYNC_IO: 478 *ap->a_retval = 1; 479 return (0); 480 default: 481 return genfs_pathconf(ap); 482 } 483 /* NOTREACHED */ 484 } 485 486 /* 487 * _print is used for debugging. 488 * just print a readable description 489 * of (vp). 490 */ 491 int 492 procfs_print(void *v) 493 { 494 struct vop_print_args /* { 495 struct vnode *a_vp; 496 } */ *ap = v; 497 struct pfsnode *pfs = VTOPFS(ap->a_vp); 498 499 printf("tag VT_PROCFS, type %d, pid %d, mode %x, flags %lx\n", 500 pfs->pfs_type, pfs->pfs_pid, pfs->pfs_mode, pfs->pfs_flags); 501 return 0; 502 } 503 504 int 505 procfs_link(void *v) 506 { 507 struct vop_link_v2_args /* { 508 struct vnode *a_dvp; 509 struct vnode *a_vp; 510 struct componentname *a_cnp; 511 } */ *ap = v; 512 513 VOP_ABORTOP(ap->a_dvp, ap->a_cnp); 514 return (EROFS); 515 } 516 517 int 518 procfs_symlink(void *v) 519 { 520 struct vop_symlink_v3_args /* { 521 struct vnode *a_dvp; 522 struct vnode **a_vpp; 523 struct componentname *a_cnp; 524 struct vattr *a_vap; 525 char *a_target; 526 } */ *ap = v; 527 528 VOP_ABORTOP(ap->a_dvp, ap->a_cnp); 529 return (EROFS); 530 } 531 532 /* 533 * Works out the path to the target process's current 534 * working directory or chroot. If the caller is in a chroot and 535 * can't "reach" the target's cwd or root (or some other error 536 * occurs), a "/" is returned for the path. 537 */ 538 static void 539 procfs_dir(pfstype t, struct lwp *caller, struct proc *target, char **bpp, 540 char *path, size_t len) 541 { 542 struct cwdinfo *cwdi; 543 struct vnode *vp, *rvp; 544 char *bp; 545 546 /* 547 * Lock target cwdi and take a reference to the vnode 548 * we are interested in to prevent it from disappearing 549 * before getcwd_common() below. 550 */ 551 rw_enter(&target->p_cwdi->cwdi_lock, RW_READER); 552 switch (t) { 553 case PFScwd: 554 vp = target->p_cwdi->cwdi_cdir; 555 break; 556 case PFSchroot: 557 vp = target->p_cwdi->cwdi_rdir; 558 break; 559 default: 560 rw_exit(&target->p_cwdi->cwdi_lock); 561 return; 562 } 563 if (vp != NULL) 564 vref(vp); 565 rw_exit(&target->p_cwdi->cwdi_lock); 566 567 cwdi = caller->l_proc->p_cwdi; 568 rw_enter(&cwdi->cwdi_lock, RW_READER); 569 570 rvp = cwdi->cwdi_rdir; 571 bp = bpp ? *bpp : NULL; 572 573 /* 574 * XXX: this horrible kludge avoids locking panics when 575 * attempting to lookup links that point to within procfs 576 */ 577 if (vp != NULL && vp->v_tag == VT_PROCFS) { 578 if (bpp) { 579 *--bp = '/'; 580 *bpp = bp; 581 } 582 vrele(vp); 583 rw_exit(&cwdi->cwdi_lock); 584 return; 585 } 586 587 if (rvp == NULL) 588 rvp = rootvnode; 589 if (vp == NULL || getcwd_common(vp, rvp, bp ? &bp : NULL, path, 590 len / 2, 0, caller) != 0) { 591 if (bpp) { 592 bp = *bpp; 593 *--bp = '/'; 594 } 595 } 596 597 if (bpp) 598 *bpp = bp; 599 600 if (vp != NULL) 601 vrele(vp); 602 rw_exit(&cwdi->cwdi_lock); 603 } 604 605 /* 606 * Invent attributes for pfsnode (vp) and store 607 * them in (vap). 608 * Directories lengths are returned as zero since 609 * any real length would require the genuine size 610 * to be computed, and nothing cares anyway. 611 * 612 * this is relatively minimal for procfs. 613 */ 614 int 615 procfs_getattr(void *v) 616 { 617 struct vop_getattr_args /* { 618 struct vnode *a_vp; 619 struct vattr *a_vap; 620 kauth_cred_t a_cred; 621 } */ *ap = v; 622 struct vnode *vp = ap->a_vp; 623 struct pfsnode *pfs = VTOPFS(vp); 624 struct vattr *vap = ap->a_vap; 625 struct proc *procp; 626 char *path, *bp, bf[16]; 627 int error; 628 629 /* first check the process still exists */ 630 switch (pfs->pfs_type) { 631 case PFSroot: 632 case PFScurproc: 633 case PFSself: 634 procp = NULL; 635 break; 636 637 default: 638 error = 639 procfs_proc_lock(vp->v_mount, pfs->pfs_pid, &procp, ENOENT); 640 if (error != 0) 641 return (error); 642 break; 643 } 644 645 switch (pfs->pfs_type) { 646 case PFStask: 647 if (pfs->pfs_fd == -1) { 648 path = NULL; 649 break; 650 } 651 /*FALLTHROUGH*/ 652 case PFScwd: 653 case PFSchroot: 654 path = malloc(MAXPATHLEN + 4, M_TEMP, M_WAITOK); 655 if (path == NULL && procp != NULL) { 656 procfs_proc_unlock(procp); 657 return (ENOMEM); 658 } 659 break; 660 661 default: 662 path = NULL; 663 break; 664 } 665 666 if (procp != NULL) { 667 mutex_enter(procp->p_lock); 668 error = kauth_authorize_process(kauth_cred_get(), 669 KAUTH_PROCESS_CANSEE, procp, 670 KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL); 671 mutex_exit(procp->p_lock); 672 if (error != 0) { 673 procfs_proc_unlock(procp); 674 if (path != NULL) 675 free(path, M_TEMP); 676 return (ENOENT); 677 } 678 } 679 680 error = 0; 681 682 /* start by zeroing out the attributes */ 683 vattr_null(vap); 684 685 /* next do all the common fields */ 686 vap->va_type = ap->a_vp->v_type; 687 vap->va_mode = pfs->pfs_mode; 688 vap->va_fileid = pfs->pfs_fileno; 689 vap->va_flags = 0; 690 vap->va_blocksize = PAGE_SIZE; 691 692 /* 693 * Make all times be current TOD. 694 * 695 * It would be possible to get the process start 696 * time from the p_stats structure, but there's 697 * no "file creation" time stamp anyway, and the 698 * p_stats structure is not addressable if u. gets 699 * swapped out for that process. 700 */ 701 getnanotime(&vap->va_ctime); 702 vap->va_atime = vap->va_mtime = vap->va_ctime; 703 if (procp) 704 TIMEVAL_TO_TIMESPEC(&procp->p_stats->p_start, 705 &vap->va_birthtime); 706 else 707 getnanotime(&vap->va_birthtime); 708 709 switch (pfs->pfs_type) { 710 case PFSmem: 711 case PFSregs: 712 case PFSfpregs: 713 #if defined(__HAVE_PROCFS_MACHDEP) && defined(PROCFS_MACHDEP_PROTECT_CASES) 714 PROCFS_MACHDEP_PROTECT_CASES 715 #endif 716 /* 717 * If the process has exercised some setuid or setgid 718 * privilege, then rip away read/write permission so 719 * that only root can gain access. 720 */ 721 if (procp->p_flag & PK_SUGID) 722 vap->va_mode &= ~(S_IRUSR|S_IWUSR); 723 /* FALLTHROUGH */ 724 case PFSstatus: 725 case PFSstat: 726 case PFSnote: 727 case PFSnotepg: 728 case PFScmdline: 729 case PFSenviron: 730 case PFSemul: 731 case PFSstatm: 732 733 case PFSmap: 734 case PFSmaps: 735 case PFSlimit: 736 case PFSauxv: 737 vap->va_nlink = 1; 738 vap->va_uid = kauth_cred_geteuid(procp->p_cred); 739 vap->va_gid = kauth_cred_getegid(procp->p_cred); 740 break; 741 case PFScwd: 742 case PFSchroot: 743 case PFSmeminfo: 744 case PFSdevices: 745 case PFScpuinfo: 746 case PFSuptime: 747 case PFSmounts: 748 case PFScpustat: 749 case PFSloadavg: 750 case PFSversion: 751 case PFSexe: 752 case PFSself: 753 case PFScurproc: 754 case PFSroot: 755 vap->va_nlink = 1; 756 vap->va_uid = vap->va_gid = 0; 757 break; 758 759 case PFSproc: 760 case PFStask: 761 case PFSfile: 762 case PFSfd: 763 break; 764 765 default: 766 panic("%s: %d/1", __func__, pfs->pfs_type); 767 } 768 769 /* 770 * now do the object specific fields 771 * 772 * The size could be set from struct reg, but it's hardly 773 * worth the trouble, and it puts some (potentially) machine 774 * dependent data into this machine-independent code. If it 775 * becomes important then this function should break out into 776 * a per-file stat function in the corresponding .c file. 777 */ 778 779 switch (pfs->pfs_type) { 780 case PFSroot: 781 vap->va_bytes = vap->va_size = DEV_BSIZE; 782 break; 783 784 case PFSself: 785 case PFScurproc: 786 vap->va_bytes = vap->va_size = 787 snprintf(bf, sizeof(bf), "%ld", (long)curproc->p_pid); 788 break; 789 case PFStask: 790 if (pfs->pfs_fd != -1) { 791 vap->va_nlink = 1; 792 vap->va_uid = 0; 793 vap->va_gid = 0; 794 vap->va_bytes = vap->va_size = 795 snprintf(bf, sizeof(bf), ".."); 796 break; 797 } 798 /*FALLTHROUGH*/ 799 case PFSfd: 800 if (pfs->pfs_fd != -1) { 801 file_t *fp; 802 803 fp = fd_getfile2(procp, pfs->pfs_fd); 804 if (fp == NULL) { 805 error = EBADF; 806 break; 807 } 808 vap->va_nlink = 1; 809 vap->va_uid = kauth_cred_geteuid(fp->f_cred); 810 vap->va_gid = kauth_cred_getegid(fp->f_cred); 811 switch (fp->f_type) { 812 case DTYPE_VNODE: 813 vap->va_bytes = vap->va_size = 814 fp->f_vnode->v_size; 815 break; 816 default: 817 vap->va_bytes = vap->va_size = 0; 818 break; 819 } 820 closef(fp); 821 break; 822 } 823 /*FALLTHROUGH*/ 824 case PFSproc: 825 vap->va_nlink = 2; 826 vap->va_uid = kauth_cred_geteuid(procp->p_cred); 827 vap->va_gid = kauth_cred_getegid(procp->p_cred); 828 vap->va_bytes = vap->va_size = DEV_BSIZE; 829 break; 830 831 case PFSfile: 832 error = EOPNOTSUPP; 833 break; 834 835 case PFSmem: 836 vap->va_bytes = vap->va_size = 837 ctob(procp->p_vmspace->vm_tsize + 838 procp->p_vmspace->vm_dsize + 839 procp->p_vmspace->vm_ssize); 840 break; 841 842 case PFSauxv: 843 vap->va_bytes = vap->va_size = procp->p_execsw->es_arglen; 844 break; 845 846 #if defined(PT_GETREGS) || defined(PT_SETREGS) 847 case PFSregs: 848 vap->va_bytes = vap->va_size = sizeof(struct reg); 849 break; 850 #endif 851 852 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) 853 case PFSfpregs: 854 vap->va_bytes = vap->va_size = sizeof(struct fpreg); 855 break; 856 #endif 857 858 case PFSstatus: 859 case PFSstat: 860 case PFSnote: 861 case PFSnotepg: 862 case PFScmdline: 863 case PFSenviron: 864 case PFSmeminfo: 865 case PFSdevices: 866 case PFScpuinfo: 867 case PFSuptime: 868 case PFSmounts: 869 case PFScpustat: 870 case PFSloadavg: 871 case PFSstatm: 872 case PFSversion: 873 vap->va_bytes = vap->va_size = 0; 874 break; 875 case PFSlimit: 876 case PFSmap: 877 case PFSmaps: 878 /* 879 * Advise a larger blocksize for the map files, so that 880 * they may be read in one pass. 881 */ 882 vap->va_blocksize = 4 * PAGE_SIZE; 883 vap->va_bytes = vap->va_size = 0; 884 break; 885 886 case PFScwd: 887 case PFSchroot: 888 bp = path + MAXPATHLEN; 889 *--bp = '\0'; 890 procfs_dir(pfs->pfs_type, curlwp, procp, &bp, path, 891 MAXPATHLEN); 892 vap->va_bytes = vap->va_size = strlen(bp); 893 break; 894 895 case PFSexe: 896 vap->va_bytes = vap->va_size = strlen(procp->p_path); 897 break; 898 899 case PFSemul: 900 vap->va_bytes = vap->va_size = strlen(procp->p_emul->e_name); 901 break; 902 903 #ifdef __HAVE_PROCFS_MACHDEP 904 PROCFS_MACHDEP_NODETYPE_CASES 905 error = procfs_machdep_getattr(ap->a_vp, vap, procp); 906 break; 907 #endif 908 909 default: 910 panic("%s: %d/2", __func__, pfs->pfs_type); 911 } 912 913 if (procp != NULL) 914 procfs_proc_unlock(procp); 915 if (path != NULL) 916 free(path, M_TEMP); 917 918 return (error); 919 } 920 921 /*ARGSUSED*/ 922 int 923 procfs_setattr(void *v) 924 { 925 /* 926 * just fake out attribute setting 927 * it's not good to generate an error 928 * return, otherwise things like creat() 929 * will fail when they try to set the 930 * file length to 0. worse, this means 931 * that echo $note > /proc/$pid/note will fail. 932 */ 933 934 return (0); 935 } 936 937 /* 938 * implement access checking. 939 * 940 * actually, the check for super-user is slightly 941 * broken since it will allow read access to write-only 942 * objects. this doesn't cause any particular trouble 943 * but does mean that the i/o entry points need to check 944 * that the operation really does make sense. 945 */ 946 int 947 procfs_access(void *v) 948 { 949 struct vop_access_args /* { 950 struct vnode *a_vp; 951 accmode_t a_accmode; 952 kauth_cred_t a_cred; 953 } */ *ap = v; 954 struct vattr va; 955 int error; 956 957 if ((error = VOP_GETATTR(ap->a_vp, &va, ap->a_cred)) != 0) 958 return (error); 959 960 return kauth_authorize_vnode(ap->a_cred, 961 KAUTH_ACCESS_ACTION(ap->a_accmode, ap->a_vp->v_type, va.va_mode), 962 ap->a_vp, NULL, genfs_can_access(ap->a_vp, ap->a_cred, 963 va.va_uid, va.va_gid, va.va_mode, NULL, ap->a_accmode)); 964 } 965 966 /* 967 * lookup. this is incredibly complicated in the 968 * general case, however for most pseudo-filesystems 969 * very little needs to be done. 970 * 971 * Locking isn't hard here, just poorly documented. 972 * 973 * If we're looking up ".", just vref the parent & return it. 974 * 975 * If we're looking up "..", unlock the parent, and lock "..". If everything 976 * went ok, and we're on the last component and the caller requested the 977 * parent locked, try to re-lock the parent. We do this to prevent lock 978 * races. 979 * 980 * For anything else, get the needed node. Then unlock the parent if not 981 * the last component or not LOCKPARENT (i.e. if we wouldn't re-lock the 982 * parent in the .. case). 983 * 984 * We try to exit with the parent locked in error cases. 985 */ 986 int 987 procfs_lookup(void *v) 988 { 989 struct vop_lookup_v2_args /* { 990 struct vnode * a_dvp; 991 struct vnode ** a_vpp; 992 struct componentname * a_cnp; 993 } */ *ap = v; 994 struct componentname *cnp = ap->a_cnp; 995 struct vnode **vpp = ap->a_vpp; 996 struct vnode *dvp = ap->a_dvp; 997 const char *pname = cnp->cn_nameptr; 998 const struct proc_target *pt = NULL; 999 struct vnode *fvp; 1000 pid_t pid, vnpid; 1001 struct pfsnode *pfs; 1002 struct proc *p = NULL; 1003 struct lwp *plwp; 1004 int i, error; 1005 pfstype type; 1006 1007 *vpp = NULL; 1008 1009 if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) 1010 return (EROFS); 1011 1012 if (cnp->cn_namelen == 1 && *pname == '.') { 1013 *vpp = dvp; 1014 vref(dvp); 1015 return (0); 1016 } 1017 1018 pfs = VTOPFS(dvp); 1019 switch (pfs->pfs_type) { 1020 case PFSroot: 1021 /* 1022 * Shouldn't get here with .. in the root node. 1023 */ 1024 if (cnp->cn_flags & ISDOTDOT) 1025 return (EIO); 1026 1027 for (i = 0; i < nproc_root_targets; i++) { 1028 pt = &proc_root_targets[i]; 1029 /* 1030 * check for node match. proc is always NULL here, 1031 * so call pt_valid with constant NULL lwp. 1032 */ 1033 if (cnp->cn_namelen == pt->pt_namlen && 1034 memcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 && 1035 (pt->pt_valid == NULL || 1036 (*pt->pt_valid)(NULL, dvp->v_mount))) 1037 break; 1038 } 1039 1040 if (i != nproc_root_targets) { 1041 error = procfs_allocvp(dvp->v_mount, vpp, 0, 1042 pt->pt_pfstype, -1); 1043 return (error); 1044 } 1045 1046 if (CNEQ(cnp, "curproc", 7)) { 1047 pid = curproc->p_pid; 1048 vnpid = 0; 1049 type = PFScurproc; 1050 } else if (CNEQ(cnp, "self", 4)) { 1051 pid = curproc->p_pid; 1052 vnpid = 0; 1053 type = PFSself; 1054 } else { 1055 pid = (pid_t)atoi(pname, cnp->cn_namelen); 1056 vnpid = pid; 1057 type = PFSproc; 1058 } 1059 1060 if (procfs_proc_lock(dvp->v_mount, pid, &p, ESRCH) != 0) 1061 break; 1062 error = procfs_allocvp(dvp->v_mount, vpp, vnpid, type, -1); 1063 procfs_proc_unlock(p); 1064 return (error); 1065 1066 case PFSproc: 1067 if (cnp->cn_flags & ISDOTDOT) { 1068 error = procfs_allocvp(dvp->v_mount, vpp, 0, PFSroot, 1069 -1); 1070 return (error); 1071 } 1072 1073 if (procfs_proc_lock(dvp->v_mount, pfs->pfs_pid, &p, 1074 ESRCH) != 0) 1075 break; 1076 1077 mutex_enter(p->p_lock); 1078 LIST_FOREACH(plwp, &p->p_lwps, l_sibling) { 1079 if (plwp->l_stat != LSZOMB) 1080 break; 1081 } 1082 /* Process is exiting if no-LWPS or all LWPs are LSZOMB */ 1083 if (plwp == NULL) { 1084 mutex_exit(p->p_lock); 1085 procfs_proc_unlock(p); 1086 return ESRCH; 1087 } 1088 1089 lwp_addref(plwp); 1090 mutex_exit(p->p_lock); 1091 1092 for (pt = proc_targets, i = 0; i < nproc_targets; pt++, i++) { 1093 int found; 1094 1095 found = cnp->cn_namelen == pt->pt_namlen && 1096 memcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 && 1097 (pt->pt_valid == NULL 1098 || (*pt->pt_valid)(plwp, dvp->v_mount)); 1099 if (found) 1100 break; 1101 } 1102 lwp_delref(plwp); 1103 1104 if (i == nproc_targets) { 1105 procfs_proc_unlock(p); 1106 break; 1107 } 1108 if (pt->pt_pfstype == PFSfile) { 1109 fvp = p->p_textvp; 1110 /* We already checked that it exists. */ 1111 vref(fvp); 1112 procfs_proc_unlock(p); 1113 *vpp = fvp; 1114 return (0); 1115 } 1116 1117 error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, 1118 pt->pt_pfstype, -1); 1119 procfs_proc_unlock(p); 1120 return (error); 1121 1122 case PFSfd: { 1123 int fd; 1124 file_t *fp; 1125 1126 if ((error = procfs_proc_lock(dvp->v_mount, pfs->pfs_pid, &p, 1127 ENOENT)) != 0) 1128 return error; 1129 1130 if (cnp->cn_flags & ISDOTDOT) { 1131 error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, 1132 PFSproc, -1); 1133 procfs_proc_unlock(p); 1134 return (error); 1135 } 1136 fd = atoi(pname, cnp->cn_namelen); 1137 1138 fp = fd_getfile2(p, fd); 1139 if (fp == NULL) { 1140 procfs_proc_unlock(p); 1141 return ENOENT; 1142 } 1143 fvp = fp->f_vnode; 1144 1145 /* Don't show directories */ 1146 if (fp->f_type == DTYPE_VNODE && fvp->v_type != VDIR && 1147 !procfs_proc_is_linux_compat()) { 1148 vref(fvp); 1149 closef(fp); 1150 procfs_proc_unlock(p); 1151 *vpp = fvp; 1152 return 0; 1153 } 1154 1155 closef(fp); 1156 error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, 1157 PFSfd, fd); 1158 procfs_proc_unlock(p); 1159 return error; 1160 } 1161 case PFStask: { 1162 int xpid; 1163 1164 if ((error = procfs_proc_lock(dvp->v_mount, pfs->pfs_pid, &p, 1165 ENOENT)) != 0) 1166 return error; 1167 1168 if (cnp->cn_flags & ISDOTDOT) { 1169 error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, 1170 PFSproc, -1); 1171 procfs_proc_unlock(p); 1172 return (error); 1173 } 1174 xpid = atoi(pname, cnp->cn_namelen); 1175 1176 if (xpid != pfs->pfs_pid) { 1177 procfs_proc_unlock(p); 1178 return ENOENT; 1179 } 1180 error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, 1181 PFStask, 0); 1182 procfs_proc_unlock(p); 1183 return error; 1184 } 1185 default: 1186 return (ENOTDIR); 1187 } 1188 1189 return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS); 1190 } 1191 1192 int 1193 procfs_validfile(struct lwp *l, struct mount *mp) 1194 { 1195 return l != NULL && l->l_proc != NULL && l->l_proc->p_textvp != NULL; 1196 } 1197 1198 static int 1199 procfs_validfile_linux(struct lwp *l, struct mount *mp) 1200 { 1201 return procfs_use_linux_compat(mp) && 1202 (l == NULL || l->l_proc == NULL || procfs_validfile(l, mp)); 1203 } 1204 1205 struct procfs_root_readdir_ctx { 1206 struct uio *uiop; 1207 off_t *cookies; 1208 int ncookies; 1209 off_t off; 1210 off_t startoff; 1211 int error; 1212 }; 1213 1214 static int 1215 procfs_root_readdir_callback(struct proc *p, void *arg) 1216 { 1217 struct procfs_root_readdir_ctx *ctxp = arg; 1218 struct dirent d; 1219 struct uio *uiop; 1220 int error; 1221 1222 uiop = ctxp->uiop; 1223 if (uiop->uio_resid < UIO_MX) 1224 return -1; /* no space */ 1225 1226 if (kauth_authorize_process(kauth_cred_get(), 1227 KAUTH_PROCESS_CANSEE, p, 1228 KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL) != 0) 1229 return 0; 1230 1231 if (ctxp->off < ctxp->startoff) { 1232 ctxp->off++; 1233 return 0; 1234 } 1235 1236 memset(&d, 0, UIO_MX); 1237 d.d_reclen = UIO_MX; 1238 d.d_fileno = PROCFS_FILENO(p->p_pid, PFSproc, -1); 1239 d.d_namlen = snprintf(d.d_name, 1240 UIO_MX - offsetof(struct dirent, d_name), "%ld", (long)p->p_pid); 1241 d.d_type = DT_DIR; 1242 1243 mutex_exit(&proc_lock); 1244 error = uiomove(&d, UIO_MX, uiop); 1245 mutex_enter(&proc_lock); 1246 if (error) { 1247 ctxp->error = error; 1248 return -1; 1249 } 1250 1251 ctxp->ncookies++; 1252 if (ctxp->cookies) 1253 *(ctxp->cookies)++ = ctxp->off + 1; 1254 ctxp->off++; 1255 1256 return 0; 1257 } 1258 1259 /* 1260 * readdir returns directory entries from pfsnode (vp). 1261 * 1262 * the strategy here with procfs is to generate a single 1263 * directory entry at a time (struct dirent) and then 1264 * copy that out to userland using uiomove. a more efficient 1265 * though more complex implementation, would try to minimize 1266 * the number of calls to uiomove(). for procfs, this is 1267 * hardly worth the added code complexity. 1268 * 1269 * this should just be done through read() 1270 */ 1271 int 1272 procfs_readdir(void *v) 1273 { 1274 struct vop_readdir_args /* { 1275 struct vnode *a_vp; 1276 struct uio *a_uio; 1277 kauth_cred_t a_cred; 1278 int *a_eofflag; 1279 off_t **a_cookies; 1280 int *a_ncookies; 1281 } */ *ap = v; 1282 struct uio *uio = ap->a_uio; 1283 struct dirent d; 1284 struct pfsnode *pfs; 1285 off_t i; 1286 int error; 1287 off_t *cookies = NULL; 1288 int ncookies; 1289 struct vnode *vp; 1290 const struct proc_target *pt; 1291 struct procfs_root_readdir_ctx ctx; 1292 struct proc *p = NULL; 1293 struct lwp *l; 1294 int nfd; 1295 int nc = 0; 1296 1297 vp = ap->a_vp; 1298 pfs = VTOPFS(vp); 1299 1300 if (uio->uio_resid < UIO_MX) 1301 return (EINVAL); 1302 if (uio->uio_offset < 0) 1303 return (EINVAL); 1304 1305 error = 0; 1306 i = uio->uio_offset; 1307 memset(&d, 0, UIO_MX); 1308 d.d_reclen = UIO_MX; 1309 ncookies = uio->uio_resid / UIO_MX; 1310 1311 switch (pfs->pfs_type) { 1312 /* 1313 * this is for the process-specific sub-directories. 1314 * all that is needed to is copy out all the entries 1315 * from the procent[] table (top of this file). 1316 */ 1317 case PFSproc: { 1318 1319 if (i >= nproc_targets) 1320 return 0; 1321 1322 if (procfs_proc_lock(vp->v_mount, pfs->pfs_pid, &p, ESRCH) != 0) 1323 break; 1324 1325 if (ap->a_ncookies) { 1326 ncookies = uimin(ncookies, (nproc_targets - i)); 1327 cookies = malloc(ncookies * sizeof (off_t), 1328 M_TEMP, M_WAITOK); 1329 *ap->a_cookies = cookies; 1330 } 1331 1332 for (pt = &proc_targets[i]; 1333 uio->uio_resid >= UIO_MX && i < nproc_targets; pt++, i++) { 1334 if (pt->pt_valid) { 1335 /* XXXSMP LWP can disappear */ 1336 mutex_enter(p->p_lock); 1337 l = LIST_FIRST(&p->p_lwps); 1338 KASSERT(l != NULL); 1339 mutex_exit(p->p_lock); 1340 if ((*pt->pt_valid)(l, vp->v_mount) == 0) 1341 continue; 1342 } 1343 1344 d.d_fileno = PROCFS_FILENO(pfs->pfs_pid, 1345 pt->pt_pfstype, -1); 1346 d.d_namlen = pt->pt_namlen; 1347 memcpy(d.d_name, pt->pt_name, pt->pt_namlen + 1); 1348 d.d_type = pt->pt_type; 1349 1350 if ((error = uiomove(&d, UIO_MX, uio)) != 0) 1351 break; 1352 if (cookies) 1353 *cookies++ = i + 1; 1354 } 1355 1356 procfs_proc_unlock(p); 1357 break; 1358 } 1359 case PFSfd: { 1360 file_t *fp; 1361 int lim; 1362 1363 if ((error = procfs_proc_lock(vp->v_mount, pfs->pfs_pid, &p, 1364 ESRCH)) != 0) 1365 return error; 1366 1367 /* XXX Should this be by file as well? */ 1368 if (kauth_authorize_process(kauth_cred_get(), 1369 KAUTH_PROCESS_CANSEE, p, 1370 KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_OPENFILES), NULL, 1371 NULL) != 0) { 1372 procfs_proc_unlock(p); 1373 return ESRCH; 1374 } 1375 1376 nfd = atomic_load_consume(&p->p_fd->fd_dt)->dt_nfiles; 1377 1378 lim = uimin((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles); 1379 if (i >= lim) { 1380 procfs_proc_unlock(p); 1381 return 0; 1382 } 1383 1384 if (ap->a_ncookies) { 1385 ncookies = uimin(ncookies, (nfd + 2 - i)); 1386 cookies = malloc(ncookies * sizeof (off_t), 1387 M_TEMP, M_WAITOK); 1388 *ap->a_cookies = cookies; 1389 } 1390 1391 for (; i < 2 && uio->uio_resid >= UIO_MX; i++) { 1392 pt = &proc_targets[i]; 1393 d.d_namlen = pt->pt_namlen; 1394 d.d_fileno = PROCFS_FILENO(pfs->pfs_pid, 1395 pt->pt_pfstype, -1); 1396 (void)memcpy(d.d_name, pt->pt_name, pt->pt_namlen + 1); 1397 d.d_type = pt->pt_type; 1398 if ((error = uiomove(&d, UIO_MX, uio)) != 0) 1399 break; 1400 if (cookies) 1401 *cookies++ = i + 1; 1402 nc++; 1403 } 1404 if (error) 1405 goto out; 1406 for (; uio->uio_resid >= UIO_MX && i < nfd; i++) { 1407 /* check the descriptor exists */ 1408 if ((fp = fd_getfile2(p, i - 2)) == NULL) 1409 continue; 1410 closef(fp); 1411 1412 d.d_fileno = PROCFS_FILENO(pfs->pfs_pid, PFSfd, i - 2); 1413 d.d_namlen = snprintf(d.d_name, sizeof(d.d_name), 1414 "%lld", (long long)(i - 2)); 1415 d.d_type = fttodt(fp); 1416 if ((error = uiomove(&d, UIO_MX, uio)) != 0) 1417 break; 1418 if (cookies) 1419 *cookies++ = i + 1; 1420 nc++; 1421 } 1422 goto out; 1423 } 1424 case PFStask: { 1425 1426 if ((error = procfs_proc_lock(vp->v_mount, pfs->pfs_pid, &p, 1427 ESRCH)) != 0) 1428 return error; 1429 1430 nfd = 3; /* ., .., pid */ 1431 1432 if (ap->a_ncookies) { 1433 ncookies = uimin(ncookies, (nfd + 2 - i)); 1434 cookies = malloc(ncookies * sizeof (off_t), 1435 M_TEMP, M_WAITOK); 1436 *ap->a_cookies = cookies; 1437 } 1438 1439 for (; i < 2 && uio->uio_resid >= UIO_MX; i++) { 1440 pt = &proc_targets[i]; 1441 d.d_namlen = pt->pt_namlen; 1442 d.d_fileno = PROCFS_FILENO(pfs->pfs_pid, 1443 pt->pt_pfstype, -1); 1444 (void)memcpy(d.d_name, pt->pt_name, pt->pt_namlen + 1); 1445 d.d_type = pt->pt_type; 1446 if ((error = uiomove(&d, UIO_MX, uio)) != 0) 1447 break; 1448 if (cookies) 1449 *cookies++ = i + 1; 1450 nc++; 1451 } 1452 if (error) 1453 goto out; 1454 for (; uio->uio_resid >= UIO_MX && i < nfd; i++) { 1455 /* check the descriptor exists */ 1456 d.d_fileno = PROCFS_FILENO(pfs->pfs_pid, PFStask, 1457 i - 2); 1458 d.d_namlen = snprintf(d.d_name, sizeof(d.d_name), 1459 "%ld", (long)pfs->pfs_pid); 1460 d.d_type = DT_LNK; 1461 if ((error = uiomove(&d, UIO_MX, uio)) != 0) 1462 break; 1463 if (cookies) 1464 *cookies++ = i + 1; 1465 nc++; 1466 } 1467 goto out; 1468 } 1469 1470 /* 1471 * this is for the root of the procfs filesystem 1472 * what is needed are special entries for "curproc" 1473 * and "self" followed by an entry for each process 1474 * on allproc. 1475 */ 1476 1477 case PFSroot: { 1478 1479 if (ap->a_ncookies) { 1480 /* 1481 * XXX Potentially allocating too much space here, 1482 * but I'm lazy. This loop needs some work. 1483 */ 1484 cookies = malloc(ncookies * sizeof (off_t), 1485 M_TEMP, M_WAITOK); 1486 *ap->a_cookies = cookies; 1487 } 1488 1489 /* 0 ... 3 are static entries. */ 1490 for (; i <= 3 && uio->uio_resid >= UIO_MX; i++) { 1491 switch (i) { 1492 case 0: /* `.' */ 1493 case 1: /* `..' */ 1494 d.d_fileno = PROCFS_FILENO(0, PFSroot, -1); 1495 d.d_namlen = i + 1; 1496 memcpy(d.d_name, "..", d.d_namlen); 1497 d.d_name[i + 1] = '\0'; 1498 d.d_type = DT_DIR; 1499 break; 1500 1501 case 2: 1502 d.d_fileno = PROCFS_FILENO(0, PFScurproc, -1); 1503 d.d_namlen = sizeof("curproc") - 1; 1504 memcpy(d.d_name, "curproc", sizeof("curproc")); 1505 d.d_type = DT_LNK; 1506 break; 1507 1508 case 3: 1509 d.d_fileno = PROCFS_FILENO(0, PFSself, -1); 1510 d.d_namlen = sizeof("self") - 1; 1511 memcpy(d.d_name, "self", sizeof("self")); 1512 d.d_type = DT_LNK; 1513 break; 1514 } 1515 1516 if ((error = uiomove(&d, UIO_MX, uio)) != 0) 1517 break; 1518 nc++; 1519 if (cookies) 1520 *cookies++ = i + 1; 1521 } 1522 if (error) 1523 break; 1524 /* 4 ... are process entries. */ 1525 ctx.uiop = uio; 1526 ctx.error = 0; 1527 ctx.off = 4; 1528 ctx.startoff = i; 1529 ctx.cookies = cookies; 1530 ctx.ncookies = nc; 1531 proclist_foreach_call(&allproc, 1532 procfs_root_readdir_callback, &ctx); 1533 cookies = ctx.cookies; 1534 nc = ctx.ncookies; 1535 error = ctx.error; 1536 if (error) 1537 break; 1538 1539 /* misc entries. */ 1540 if (i < ctx.off) 1541 i = ctx.off; 1542 if (i >= ctx.off + nproc_root_targets) 1543 break; 1544 error = procfs_proc_lock(vp->v_mount, pfs->pfs_pid, &p, ESRCH); 1545 if (error) 1546 break; 1547 for (pt = &proc_root_targets[i - ctx.off]; 1548 uio->uio_resid >= UIO_MX && 1549 pt < &proc_root_targets[nproc_root_targets]; 1550 pt++, i++) { 1551 if (pt->pt_valid && 1552 (*pt->pt_valid)(NULL, vp->v_mount) == 0) 1553 continue; 1554 if (kauth_authorize_process(kauth_cred_get(), 1555 KAUTH_PROCESS_CANSEE, p, 1556 KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), 1557 NULL, NULL) != 0) 1558 continue; 1559 d.d_fileno = PROCFS_FILENO(0, pt->pt_pfstype, -1); 1560 d.d_namlen = pt->pt_namlen; 1561 memcpy(d.d_name, pt->pt_name, pt->pt_namlen + 1); 1562 d.d_type = pt->pt_type; 1563 1564 if ((error = uiomove(&d, UIO_MX, uio)) != 0) 1565 break; 1566 nc++; 1567 if (cookies) 1568 *cookies++ = i + 1; 1569 } 1570 out: 1571 KASSERT(p != NULL); 1572 ncookies = nc; 1573 procfs_proc_unlock(p); 1574 break; 1575 } 1576 1577 default: 1578 error = ENOTDIR; 1579 break; 1580 } 1581 1582 if (ap->a_ncookies) { 1583 if (error) { 1584 if (cookies) 1585 free(*ap->a_cookies, M_TEMP); 1586 *ap->a_ncookies = 0; 1587 *ap->a_cookies = NULL; 1588 } else 1589 *ap->a_ncookies = ncookies; 1590 } 1591 uio->uio_offset = i; 1592 return (error); 1593 } 1594 1595 /* 1596 * readlink reads the link of `curproc' and others 1597 */ 1598 int 1599 procfs_readlink(void *v) 1600 { 1601 struct vop_readlink_args *ap = v; 1602 char bf[16]; /* should be enough */ 1603 char *bp = bf; 1604 char *path = NULL; 1605 int len = 0; 1606 int error = 0; 1607 struct vnode *vp = ap->a_vp; 1608 struct pfsnode *pfs = VTOPFS(vp); 1609 struct proc *pown = NULL; 1610 1611 if (pfs->pfs_fileno == PROCFS_FILENO(0, PFScurproc, -1)) 1612 len = snprintf(bf, sizeof(bf), "%ld", (long)curproc->p_pid); 1613 else if (pfs->pfs_fileno == PROCFS_FILENO(0, PFSself, -1)) 1614 len = snprintf(bf, sizeof(bf), "%s", "curproc"); 1615 else if (pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFStask, 0)) 1616 len = snprintf(bf, sizeof(bf), ".."); 1617 else if (pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFSexe, -1)) { 1618 if ((error = procfs_proc_lock(vp->v_mount, pfs->pfs_pid, &pown, 1619 ESRCH)) != 0) 1620 return error; 1621 bp = pown->p_path; 1622 len = strlen(bp); 1623 } else if (pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFScwd, -1) || 1624 pfs->pfs_fileno == PROCFS_FILENO(pfs->pfs_pid, PFSchroot, -1)) { 1625 if ((error = procfs_proc_lock(vp->v_mount, pfs->pfs_pid, &pown, 1626 ESRCH)) != 0) 1627 return error; 1628 path = malloc(MAXPATHLEN + 4, M_TEMP, M_WAITOK); 1629 if (path == NULL) { 1630 procfs_proc_unlock(pown); 1631 return (ENOMEM); 1632 } 1633 bp = path + MAXPATHLEN; 1634 *--bp = '\0'; 1635 procfs_dir(PROCFS_TYPE(pfs->pfs_fileno), curlwp, pown, 1636 &bp, path, MAXPATHLEN); 1637 len = strlen(bp); 1638 } else { 1639 file_t *fp; 1640 struct vnode *vxp; 1641 1642 if ((error = procfs_proc_lock(vp->v_mount, pfs->pfs_pid, &pown, 1643 ESRCH)) != 0) 1644 return error; 1645 1646 fp = fd_getfile2(pown, pfs->pfs_fd); 1647 if (fp == NULL) { 1648 procfs_proc_unlock(pown); 1649 return EBADF; 1650 } 1651 1652 switch (fp->f_type) { 1653 case DTYPE_VNODE: 1654 vxp = fp->f_vnode; 1655 if (vxp->v_type != VDIR && 1656 !procfs_proc_is_linux_compat()) { 1657 error = EINVAL; 1658 break; 1659 } 1660 if ((path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK)) 1661 == NULL) { 1662 error = ENOMEM; 1663 break; 1664 } 1665 bp = path + MAXPATHLEN; 1666 *--bp = '\0'; 1667 1668 /* 1669 * XXX: kludge to avoid locking against ourselves 1670 * in getcwd() 1671 */ 1672 if (vxp->v_tag == VT_PROCFS) { 1673 *--bp = '/'; 1674 } else { 1675 rw_enter(&curproc->p_cwdi->cwdi_lock, 1676 RW_READER); 1677 vp = curproc->p_cwdi->cwdi_rdir; 1678 if (vp == NULL) 1679 vp = rootvnode; 1680 error = getcwd_common(vxp, vp, &bp, path, 1681 MAXPATHLEN / 2, 0, curlwp); 1682 rw_exit(&curproc->p_cwdi->cwdi_lock); 1683 } 1684 if (error) 1685 break; 1686 len = strlen(bp); 1687 break; 1688 1689 case DTYPE_MISC: 1690 len = snprintf(bf, sizeof(bf), "%s", "[misc]"); 1691 break; 1692 1693 case DTYPE_KQUEUE: 1694 len = snprintf(bf, sizeof(bf), "%s", "[kqueue]"); 1695 break; 1696 1697 case DTYPE_SEM: 1698 len = snprintf(bf, sizeof(bf), "%s", "[ksem]"); 1699 break; 1700 1701 default: 1702 error = EINVAL; 1703 break; 1704 } 1705 closef(fp); 1706 } 1707 1708 if (error == 0) 1709 error = uiomove(bp, len, ap->a_uio); 1710 if (pown) 1711 procfs_proc_unlock(pown); 1712 if (path) 1713 free(path, M_TEMP); 1714 return error; 1715 } 1716 1717 int 1718 procfs_getpages(void *v) 1719 { 1720 struct vop_getpages_args /* { 1721 struct vnode *a_vp; 1722 voff_t a_offset; 1723 struct vm_page **a_m; 1724 int *a_count; 1725 int a_centeridx; 1726 vm_prot_t a_access_type; 1727 int a_advice; 1728 int a_flags; 1729 } */ *ap = v; 1730 1731 if ((ap->a_flags & PGO_LOCKED) == 0) 1732 rw_exit(ap->a_vp->v_uobj.vmobjlock); 1733 1734 return (EFAULT); 1735 } 1736 1737 /* 1738 * convert decimal ascii to int 1739 */ 1740 static int 1741 atoi(const char *b, size_t len) 1742 { 1743 int p = 0; 1744 1745 while (len--) { 1746 char c = *b++; 1747 if (c < '0' || c > '9') 1748 return -1; 1749 p = 10 * p + (c - '0'); 1750 } 1751 1752 return p; 1753 } 1754 1755 /** 1756 * convert DTYPE_XXX to corresponding DT_XXX 1757 * matching what procfs_loadvnode() does. 1758 */ 1759 static uint8_t 1760 fttodt(file_t *fp) 1761 { 1762 switch (fp->f_type) { 1763 case DTYPE_VNODE: 1764 switch (fp->f_vnode->v_type) { 1765 case VREG: return DT_REG; 1766 case VDIR: return DT_LNK; /* symlink */ 1767 case VBLK: return DT_BLK; 1768 case VCHR: return DT_CHR; 1769 case VLNK: return DT_LNK; 1770 case VSOCK: return DT_SOCK; 1771 case VFIFO: return DT_FIFO; 1772 default: return DT_UNKNOWN; 1773 } 1774 case DTYPE_PIPE: return DT_FIFO; 1775 case DTYPE_SOCKET: return DT_SOCK; 1776 case DTYPE_KQUEUE: /*FALLTHROUGH*/ 1777 case DTYPE_MISC: /*FALLTHROUGH*/ 1778 case DTYPE_SEM: return DT_LNK; /* symlinks */ 1779 default: return DT_UNKNOWN; 1780 } 1781 } 1782