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