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