1 /* 2 * Copyright (c) 1993, 1995 Jan-Simon Pendry 3 * Copyright (c) 1993, 1995 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Jan-Simon Pendry. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Berkeley and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 38 * 39 * $FreeBSD: src/sys/miscfs/procfs/procfs_vnops.c,v 1.76.2.7 2002/01/22 17:22:59 nectar Exp $ 40 * $DragonFly: src/sys/vfs/procfs/procfs_vnops.c,v 1.29 2006/04/01 20:46:53 dillon Exp $ 41 */ 42 43 /* 44 * procfs vnode interface 45 */ 46 47 #include <sys/param.h> 48 #include <sys/systm.h> 49 #include <sys/time.h> 50 #include <sys/kernel.h> 51 #include <sys/lock.h> 52 #include <sys/fcntl.h> 53 #include <sys/proc.h> 54 #include <sys/signalvar.h> 55 #include <sys/vnode.h> 56 #include <sys/uio.h> 57 #include <sys/mount.h> 58 #include <sys/namei.h> 59 #include <sys/dirent.h> 60 #include <sys/malloc.h> 61 #include <machine/reg.h> 62 #include <vm/vm_zone.h> 63 #include <vfs/procfs/procfs.h> 64 #include <sys/pioctl.h> 65 66 #include <machine/limits.h> 67 68 static int procfs_access (struct vop_access_args *); 69 static int procfs_badop (void); 70 static int procfs_bmap (struct vop_bmap_args *); 71 static int procfs_close (struct vop_close_args *); 72 static int procfs_getattr (struct vop_getattr_args *); 73 static int procfs_inactive (struct vop_inactive_args *); 74 static int procfs_ioctl (struct vop_ioctl_args *); 75 static int procfs_lookup (struct vop_old_lookup_args *); 76 static int procfs_open (struct vop_open_args *); 77 static int procfs_print (struct vop_print_args *); 78 static int procfs_readdir (struct vop_readdir_args *); 79 static int procfs_readlink (struct vop_readlink_args *); 80 static int procfs_reclaim (struct vop_reclaim_args *); 81 static int procfs_setattr (struct vop_setattr_args *); 82 83 static int procfs_readdir_proc(struct vop_readdir_args *); 84 static int procfs_readdir_root(struct vop_readdir_args *); 85 86 /* 87 * This is a list of the valid names in the 88 * process-specific sub-directories. It is 89 * used in procfs_lookup and procfs_readdir 90 */ 91 static struct proc_target { 92 u_char pt_type; 93 u_char pt_namlen; 94 char *pt_name; 95 pfstype pt_pfstype; 96 int (*pt_valid) (struct proc *p); 97 } proc_targets[] = { 98 #define N(s) sizeof(s)-1, s 99 /* name type validp */ 100 { DT_DIR, N("."), Pproc, NULL }, 101 { DT_DIR, N(".."), Proot, NULL }, 102 { DT_REG, N("mem"), Pmem, NULL }, 103 { DT_REG, N("regs"), Pregs, procfs_validregs }, 104 { DT_REG, N("fpregs"), Pfpregs, procfs_validfpregs }, 105 { DT_REG, N("dbregs"), Pdbregs, procfs_validdbregs }, 106 { DT_REG, N("ctl"), Pctl, NULL }, 107 { DT_REG, N("status"), Pstatus, NULL }, 108 { DT_REG, N("note"), Pnote, NULL }, 109 { DT_REG, N("notepg"), Pnotepg, NULL }, 110 { DT_REG, N("map"), Pmap, procfs_validmap }, 111 { DT_REG, N("etype"), Ptype, procfs_validtype }, 112 { DT_REG, N("cmdline"), Pcmdline, NULL }, 113 { DT_REG, N("rlimit"), Prlimit, NULL }, 114 { DT_LNK, N("file"), Pfile, NULL }, 115 #undef N 116 }; 117 static const int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]); 118 119 static pid_t atopid (const char *, u_int); 120 121 /* 122 * set things up for doing i/o on 123 * the pfsnode (vp). (vp) is locked 124 * on entry, and should be left locked 125 * on exit. 126 * 127 * for procfs we don't need to do anything 128 * in particular for i/o. all that is done 129 * is to support exclusive open on process 130 * memory images. 131 * 132 * procfs_open(struct vnode *a_vp, int a_mode, struct ucred *a_cred, 133 * struct thread *a_td) 134 */ 135 static int 136 procfs_open(struct vop_open_args *ap) 137 { 138 struct pfsnode *pfs = VTOPFS(ap->a_vp); 139 struct proc *p1, *p2; 140 141 p2 = PFIND(pfs->pfs_pid); 142 if (p2 == NULL) 143 return (ENOENT); 144 if (pfs->pfs_pid && !PRISON_CHECK(ap->a_cred, p2->p_ucred)) 145 return (ENOENT); 146 147 switch (pfs->pfs_type) { 148 case Pmem: 149 if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) || 150 ((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))) 151 return (EBUSY); 152 153 p1 = ap->a_td->td_proc; 154 KKASSERT(p1); 155 /* Can't trace a process that's currently exec'ing. */ 156 if ((p2->p_flag & P_INEXEC) != 0) 157 return EAGAIN; 158 if (!CHECKIO(p1, p2) || p_trespass(ap->a_cred, p2->p_ucred)) 159 return (EPERM); 160 161 if (ap->a_mode & FWRITE) 162 pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL); 163 164 break; 165 166 default: 167 break; 168 } 169 170 return (vop_stdopen(ap)); 171 } 172 173 /* 174 * close the pfsnode (vp) after doing i/o. 175 * (vp) is not locked on entry or exit. 176 * 177 * nothing to do for procfs other than undo 178 * any exclusive open flag (see _open above). 179 * 180 * procfs_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred, 181 * struct thread *a_td) 182 */ 183 static int 184 procfs_close(struct vop_close_args *ap) 185 { 186 struct pfsnode *pfs = VTOPFS(ap->a_vp); 187 struct proc *p; 188 189 switch (pfs->pfs_type) { 190 case Pmem: 191 if ((ap->a_fflag & FWRITE) && (pfs->pfs_flags & O_EXCL)) 192 pfs->pfs_flags &= ~(FWRITE|O_EXCL); 193 /* 194 * This rather complicated-looking code is trying to 195 * determine if this was the last close on this particular 196 * vnode. While one would expect v_usecount to be 1 at 197 * that point, it seems that (according to John Dyson) 198 * the VM system will bump up the usecount. So: if the 199 * usecount is 2, and VOBJBUF is set, then this is really 200 * the last close. Otherwise, if the usecount is < 2 201 * then it is definitely the last close. 202 * If this is the last close, then it checks to see if 203 * the target process has PF_LINGER set in p_pfsflags, 204 * if this is *not* the case, then the process' stop flags 205 * are cleared, and the process is woken up. This is 206 * to help prevent the case where a process has been 207 * told to stop on an event, but then the requesting process 208 * has gone away or forgotten about it. 209 */ 210 if ((ap->a_vp->v_usecount < 2) 211 && (p = pfind(pfs->pfs_pid)) 212 && !(p->p_pfsflags & PF_LINGER)) { 213 p->p_stops = 0; 214 p->p_step = 0; 215 wakeup(&p->p_step); 216 } 217 break; 218 default: 219 break; 220 } 221 222 return (vop_stdclose(ap)); 223 } 224 225 /* 226 * do an ioctl operation on a pfsnode (vp). 227 * (vp) is not locked on entry or exit. 228 */ 229 static int 230 procfs_ioctl(struct vop_ioctl_args *ap) 231 { 232 struct pfsnode *pfs = VTOPFS(ap->a_vp); 233 struct proc *procp; 234 struct proc *p; 235 int error; 236 int signo; 237 struct procfs_status *psp; 238 unsigned char flags; 239 240 procp = pfind(pfs->pfs_pid); 241 if (procp == NULL) 242 return ENOTTY; 243 p = ap->a_td->td_proc; 244 if (p == NULL) 245 return EINVAL; 246 247 /* Can't trace a process that's currently exec'ing. */ 248 if ((procp->p_flag & P_INEXEC) != 0) 249 return EAGAIN; 250 if (!CHECKIO(p, procp) || p_trespass(ap->a_cred, procp->p_ucred)) 251 return EPERM; 252 253 switch (ap->a_command) { 254 case PIOCBIS: 255 procp->p_stops |= *(unsigned int*)ap->a_data; 256 break; 257 case PIOCBIC: 258 procp->p_stops &= ~*(unsigned int*)ap->a_data; 259 break; 260 case PIOCSFL: 261 /* 262 * NFLAGS is "non-suser_xxx flags" -- currently, only 263 * PFS_ISUGID ("ignore set u/g id"); 264 */ 265 #define NFLAGS (PF_ISUGID) 266 flags = (unsigned char)*(unsigned int*)ap->a_data; 267 if (flags & NFLAGS && (error = suser_cred(ap->a_cred, 0))) 268 return error; 269 procp->p_pfsflags = flags; 270 break; 271 case PIOCGFL: 272 *(unsigned int*)ap->a_data = (unsigned int)procp->p_pfsflags; 273 break; 274 case PIOCSTATUS: 275 psp = (struct procfs_status *)ap->a_data; 276 psp->state = (procp->p_step == 0); 277 psp->flags = procp->p_pfsflags; 278 psp->events = procp->p_stops; 279 if (procp->p_step) { 280 psp->why = procp->p_stype; 281 psp->val = procp->p_xstat; 282 } else { 283 psp->why = psp->val = 0; /* Not defined values */ 284 } 285 break; 286 case PIOCWAIT: 287 psp = (struct procfs_status *)ap->a_data; 288 if (procp->p_step == 0) { 289 error = tsleep(&procp->p_stype, PCATCH, "piocwait", 0); 290 if (error) 291 return error; 292 } 293 psp->state = 1; /* It stopped */ 294 psp->flags = procp->p_pfsflags; 295 psp->events = procp->p_stops; 296 psp->why = procp->p_stype; /* why it stopped */ 297 psp->val = procp->p_xstat; /* any extra info */ 298 break; 299 case PIOCCONT: /* Restart a proc */ 300 if (procp->p_step == 0) 301 return EINVAL; /* Can only start a stopped process */ 302 if ((signo = *(int*)ap->a_data) != 0) { 303 if (signo >= NSIG || signo <= 0) 304 return EINVAL; 305 psignal(procp, signo); 306 } 307 procp->p_step = 0; 308 wakeup(&procp->p_step); 309 break; 310 default: 311 return (ENOTTY); 312 } 313 return 0; 314 } 315 316 /* 317 * do block mapping for pfsnode (vp). 318 * since we don't use the buffer cache 319 * for procfs this function should never 320 * be called. in any case, it's not clear 321 * what part of the kernel ever makes use 322 * of this function. for sanity, this is the 323 * usual no-op bmap, although returning 324 * (EIO) would be a reasonable alternative. 325 * 326 * procfs_bmap(struct vnode *a_vp, off_t a_loffset, struct vnode **a_vpp, 327 * off_t *a_doffsetp, int *a_runp) 328 */ 329 static int 330 procfs_bmap(struct vop_bmap_args *ap) 331 { 332 if (ap->a_vpp != NULL) 333 *ap->a_vpp = ap->a_vp; 334 if (ap->a_doffsetp != NULL) 335 *ap->a_doffsetp = ap->a_loffset; 336 if (ap->a_runp != NULL) 337 *ap->a_runp = 0; 338 if (ap->a_runb != NULL) 339 *ap->a_runb = 0; 340 return (0); 341 } 342 343 /* 344 * procfs_inactive is called when the pfsnode 345 * is vrele'd and the reference count goes 346 * to zero. (vp) will be on the vnode free 347 * list, so to get it back vget() must be 348 * used. 349 * 350 * (vp) is locked on entry, but must be unlocked on exit. 351 * 352 * procfs_inactive(struct vnode *a_vp, struct thread *a_td) 353 */ 354 static int 355 procfs_inactive(struct vop_inactive_args *ap) 356 { 357 /*struct vnode *vp = ap->a_vp;*/ 358 359 return (0); 360 } 361 362 /* 363 * _reclaim is called when getnewvnode() 364 * wants to make use of an entry on the vnode 365 * free list. at this time the filesystem needs 366 * to free any private data and remove the node 367 * from any private lists. 368 * 369 * procfs_reclaim(struct vnode *a_vp) 370 */ 371 static int 372 procfs_reclaim(struct vop_reclaim_args *ap) 373 { 374 return (procfs_freevp(ap->a_vp)); 375 } 376 377 /* 378 * _print is used for debugging. 379 * just print a readable description 380 * of (vp). 381 * 382 * procfs_print(struct vnode *a_vp) 383 */ 384 static int 385 procfs_print(struct vop_print_args *ap) 386 { 387 struct pfsnode *pfs = VTOPFS(ap->a_vp); 388 389 printf("tag VT_PROCFS, type %d, pid %ld, mode %x, flags %lx\n", 390 pfs->pfs_type, (long)pfs->pfs_pid, pfs->pfs_mode, pfs->pfs_flags); 391 return (0); 392 } 393 394 /* 395 * generic entry point for unsupported operations 396 */ 397 static int 398 procfs_badop(void) 399 { 400 return (EIO); 401 } 402 403 /* 404 * Invent attributes for pfsnode (vp) and store 405 * them in (vap). 406 * Directories lengths are returned as zero since 407 * any real length would require the genuine size 408 * to be computed, and nothing cares anyway. 409 * 410 * this is relatively minimal for procfs. 411 * 412 * procfs_getattr(struct vnode *a_vp, struct vattr *a_vap, 413 * struct ucred *a_cred, struct thread *a_td) 414 */ 415 static int 416 procfs_getattr(struct vop_getattr_args *ap) 417 { 418 struct pfsnode *pfs = VTOPFS(ap->a_vp); 419 struct vattr *vap = ap->a_vap; 420 struct proc *procp; 421 int error; 422 423 /* 424 * First make sure that the process and its credentials 425 * still exist. 426 */ 427 switch (pfs->pfs_type) { 428 case Proot: 429 case Pcurproc: 430 procp = 0; 431 break; 432 433 default: 434 procp = PFIND(pfs->pfs_pid); 435 if (procp == NULL || procp->p_ucred == NULL) 436 return (ENOENT); 437 } 438 439 error = 0; 440 441 /* start by zeroing out the attributes */ 442 VATTR_NULL(vap); 443 444 /* next do all the common fields */ 445 vap->va_type = ap->a_vp->v_type; 446 vap->va_mode = pfs->pfs_mode; 447 vap->va_fileid = pfs->pfs_fileno; 448 vap->va_flags = 0; 449 vap->va_blocksize = PAGE_SIZE; 450 vap->va_bytes = vap->va_size = 0; 451 vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0]; 452 453 /* 454 * Make all times be current TOD. 455 * It would be possible to get the process start 456 * time from the p_stat structure, but there's 457 * no "file creation" time stamp anyway, and the 458 * p_stat structure is not addressible if u. gets 459 * swapped out for that process. 460 */ 461 nanotime(&vap->va_ctime); 462 vap->va_atime = vap->va_mtime = vap->va_ctime; 463 464 /* 465 * If the process has exercised some setuid or setgid 466 * privilege, then rip away read/write permission so 467 * that only root can gain access. 468 */ 469 switch (pfs->pfs_type) { 470 case Pctl: 471 case Pregs: 472 case Pfpregs: 473 case Pdbregs: 474 case Pmem: 475 if (procp->p_flag & P_SUGID) 476 vap->va_mode &= ~((VREAD|VWRITE)| 477 ((VREAD|VWRITE)>>3)| 478 ((VREAD|VWRITE)>>6)); 479 break; 480 default: 481 break; 482 } 483 484 /* 485 * now do the object specific fields 486 * 487 * The size could be set from struct reg, but it's hardly 488 * worth the trouble, and it puts some (potentially) machine 489 * dependent data into this machine-independent code. If it 490 * becomes important then this function should break out into 491 * a per-file stat function in the corresponding .c file. 492 */ 493 494 vap->va_nlink = 1; 495 if (procp) { 496 vap->va_uid = procp->p_ucred->cr_uid; 497 vap->va_gid = procp->p_ucred->cr_gid; 498 } 499 500 switch (pfs->pfs_type) { 501 case Proot: 502 /* 503 * Set nlink to 1 to tell fts(3) we don't actually know. 504 */ 505 vap->va_nlink = 1; 506 vap->va_uid = 0; 507 vap->va_gid = 0; 508 vap->va_size = vap->va_bytes = DEV_BSIZE; 509 break; 510 511 case Pcurproc: { 512 char buf[16]; /* should be enough */ 513 vap->va_uid = 0; 514 vap->va_gid = 0; 515 vap->va_size = vap->va_bytes = 516 snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid); 517 break; 518 } 519 520 case Pproc: 521 vap->va_nlink = nproc_targets; 522 vap->va_size = vap->va_bytes = DEV_BSIZE; 523 break; 524 525 case Pfile: { 526 char *fullpath, *freepath; 527 error = vn_fullpath(procp, NULL, &fullpath, &freepath); 528 if (error == 0) { 529 vap->va_size = strlen(fullpath); 530 free(freepath, M_TEMP); 531 } else { 532 vap->va_size = sizeof("unknown") - 1; 533 error = 0; 534 } 535 vap->va_bytes = vap->va_size; 536 break; 537 } 538 539 case Pmem: 540 /* 541 * If we denied owner access earlier, then we have to 542 * change the owner to root - otherwise 'ps' and friends 543 * will break even though they are setgid kmem. *SIGH* 544 */ 545 if (procp->p_flag & P_SUGID) 546 vap->va_uid = 0; 547 else 548 vap->va_uid = procp->p_ucred->cr_uid; 549 break; 550 551 case Pregs: 552 vap->va_bytes = vap->va_size = sizeof(struct reg); 553 break; 554 555 case Pfpregs: 556 vap->va_bytes = vap->va_size = sizeof(struct fpreg); 557 break; 558 559 case Pdbregs: 560 vap->va_bytes = vap->va_size = sizeof(struct dbreg); 561 break; 562 563 case Ptype: 564 case Pmap: 565 case Pctl: 566 case Pstatus: 567 case Pnote: 568 case Pnotepg: 569 case Pcmdline: 570 case Prlimit: 571 break; 572 573 default: 574 panic("procfs_getattr"); 575 } 576 577 return (error); 578 } 579 580 /* 581 * procfs_setattr(struct vnode *a_vp, struct vattr *a_vap, 582 * struct ucred *a_cred, struct thread *a_td) 583 */ 584 static int 585 procfs_setattr(struct vop_setattr_args *ap) 586 { 587 if (ap->a_vap->va_flags != VNOVAL) 588 return (EOPNOTSUPP); 589 590 /* 591 * just fake out attribute setting 592 * it's not good to generate an error 593 * return, otherwise things like creat() 594 * will fail when they try to set the 595 * file length to 0. worse, this means 596 * that echo $note > /proc/$pid/note will fail. 597 */ 598 599 return (0); 600 } 601 602 /* 603 * implement access checking. 604 * 605 * something very similar to this code is duplicated 606 * throughout the 4bsd kernel and should be moved 607 * into kern/vfs_subr.c sometime. 608 * 609 * actually, the check for super-user is slightly 610 * broken since it will allow read access to write-only 611 * objects. this doesn't cause any particular trouble 612 * but does mean that the i/o entry points need to check 613 * that the operation really does make sense. 614 * 615 * procfs_access(struct vnode *a_vp, int a_mode, struct ucred *a_cred, 616 * struct thread *a_td) 617 */ 618 static int 619 procfs_access(struct vop_access_args *ap) 620 { 621 struct vattr *vap; 622 struct vattr vattr; 623 int error; 624 625 /* 626 * If you're the super-user, 627 * you always get access. 628 */ 629 if (ap->a_cred->cr_uid == 0) 630 return (0); 631 632 vap = &vattr; 633 error = VOP_GETATTR(ap->a_vp, vap, ap->a_td); 634 if (error) 635 return (error); 636 637 /* 638 * Access check is based on only one of owner, group, public. 639 * If not owner, then check group. If not a member of the 640 * group, then check public access. 641 */ 642 if (ap->a_cred->cr_uid != vap->va_uid) { 643 gid_t *gp; 644 int i; 645 646 ap->a_mode >>= 3; 647 gp = ap->a_cred->cr_groups; 648 for (i = 0; i < ap->a_cred->cr_ngroups; i++, gp++) 649 if (vap->va_gid == *gp) 650 goto found; 651 ap->a_mode >>= 3; 652 found: 653 ; 654 } 655 656 if ((vap->va_mode & ap->a_mode) == ap->a_mode) 657 return (0); 658 659 return (EACCES); 660 } 661 662 /* 663 * lookup. this is incredibly complicated in the general case, however 664 * for most pseudo-filesystems very little needs to be done. 665 * 666 * procfs_lookup(struct vnode *a_dvp, struct vnode **a_vpp, 667 * struct componentname *a_cnp) 668 */ 669 static int 670 procfs_lookup(struct vop_old_lookup_args *ap) 671 { 672 struct componentname *cnp = ap->a_cnp; 673 struct vnode **vpp = ap->a_vpp; 674 struct vnode *dvp = ap->a_dvp; 675 char *pname = cnp->cn_nameptr; 676 /* struct proc *curp = cnp->cn_proc; */ 677 struct proc_target *pt; 678 pid_t pid; 679 struct pfsnode *pfs; 680 struct proc *p; 681 int i; 682 int error; 683 684 *vpp = NULL; 685 686 if (cnp->cn_nameiop == NAMEI_DELETE || cnp->cn_nameiop == NAMEI_RENAME) 687 return (EROFS); 688 689 error = 0; 690 if (cnp->cn_namelen == 1 && *pname == '.') { 691 *vpp = dvp; 692 vref(*vpp); 693 goto out; 694 } 695 696 pfs = VTOPFS(dvp); 697 switch (pfs->pfs_type) { 698 case Proot: 699 if (cnp->cn_flags & CNP_ISDOTDOT) 700 return (EIO); 701 702 if (CNEQ(cnp, "curproc", 7)) { 703 error = procfs_allocvp(dvp->v_mount, vpp, 0, Pcurproc); 704 goto out; 705 } 706 707 pid = atopid(pname, cnp->cn_namelen); 708 if (pid == NO_PID) 709 break; 710 711 p = PFIND(pid); 712 if (p == NULL) 713 break; 714 715 if (!PRISON_CHECK(ap->a_cnp->cn_cred, p->p_ucred)) 716 break; 717 718 if (ps_showallprocs == 0 && ap->a_cnp->cn_cred->cr_uid != 0 && 719 ap->a_cnp->cn_cred->cr_uid != p->p_ucred->cr_uid) 720 break; 721 722 error = procfs_allocvp(dvp->v_mount, vpp, pid, Pproc); 723 goto out; 724 725 case Pproc: 726 if (cnp->cn_flags & CNP_ISDOTDOT) { 727 error = procfs_root(dvp->v_mount, vpp); 728 goto out; 729 } 730 731 p = PFIND(pfs->pfs_pid); 732 if (p == NULL) 733 break; 734 735 if (!PRISON_CHECK(ap->a_cnp->cn_cred, p->p_ucred)) 736 break; 737 738 if (ps_showallprocs == 0 && ap->a_cnp->cn_cred->cr_uid != 0 && 739 ap->a_cnp->cn_cred->cr_uid != p->p_ucred->cr_uid) 740 break; 741 742 for (pt = proc_targets, i = 0; i < nproc_targets; pt++, i++) { 743 if (cnp->cn_namelen == pt->pt_namlen && 744 bcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 && 745 (pt->pt_valid == NULL || (*pt->pt_valid)(p))) 746 goto found; 747 } 748 break; 749 found: 750 error = procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid, 751 pt->pt_pfstype); 752 goto out; 753 754 default: 755 error = ENOTDIR; 756 goto out; 757 } 758 if (cnp->cn_nameiop == NAMEI_LOOKUP) 759 error = ENOENT; 760 else 761 error = EROFS; 762 /* 763 * If no error occured *vpp will hold a referenced locked vnode. 764 * dvp was passed to us locked and *vpp must be returned locked. 765 * If *vpp != dvp then we should unlock dvp if (1) this is not the 766 * last component or (2) CNP_LOCKPARENT is not set. 767 */ 768 out: 769 if (error == 0 && *vpp != dvp) { 770 if ((cnp->cn_flags & CNP_LOCKPARENT) == 0) { 771 cnp->cn_flags |= CNP_PDIRUNLOCK; 772 VOP_UNLOCK(dvp, 0, cnp->cn_td); 773 } 774 } 775 return (error); 776 } 777 778 /* 779 * Does this process have a text file? 780 */ 781 int 782 procfs_validfile(struct proc *p) 783 { 784 return (procfs_findtextvp(p) != NULLVP); 785 } 786 787 /* 788 * readdir() returns directory entries from pfsnode (vp). 789 * 790 * We generate just one directory entry at a time, as it would probably 791 * not pay off to buffer several entries locally to save uiomove calls. 792 * 793 * procfs_readdir(struct vnode *a_vp, struct uio *a_uio, struct ucred *a_cred, 794 * int *a_eofflag, int *a_ncookies, u_long **a_cookies) 795 */ 796 static int 797 procfs_readdir(struct vop_readdir_args *ap) 798 { 799 struct pfsnode *pfs; 800 int error; 801 802 if (ap->a_uio->uio_offset < 0 || ap->a_uio->uio_offset > INT_MAX) 803 return (EINVAL); 804 805 pfs = VTOPFS(ap->a_vp); 806 807 switch (pfs->pfs_type) { 808 /* 809 * this is for the process-specific sub-directories. 810 * all that is needed to is copy out all the entries 811 * from the procent[] table (top of this file). 812 */ 813 case Pproc: 814 error = procfs_readdir_proc(ap); 815 break; 816 817 /* 818 * this is for the root of the procfs filesystem 819 * what is needed is a special entry for "curproc" 820 * followed by an entry for each process on allproc 821 */ 822 823 case Proot: 824 error = procfs_readdir_root(ap); 825 break; 826 827 default: 828 error = ENOTDIR; 829 break; 830 } 831 832 return (error); 833 } 834 835 static int 836 procfs_readdir_proc(struct vop_readdir_args *ap) 837 { 838 struct pfsnode *pfs; 839 int error, i, retval; 840 struct proc *p; 841 struct proc_target *pt; 842 struct uio *uio = ap->a_uio; 843 844 pfs = VTOPFS(ap->a_vp); 845 p = PFIND(pfs->pfs_pid); 846 if (p == NULL) 847 return(0); 848 if (!PRISON_CHECK(ap->a_cred, p->p_ucred)) 849 return(0); 850 851 error = 0; 852 i = uio->uio_offset; 853 854 for (pt = &proc_targets[i]; 855 !error && uio->uio_resid > 0 && i < nproc_targets; pt++, i++) { 856 if (pt->pt_valid && (*pt->pt_valid)(p) == 0) 857 continue; 858 859 retval = vop_write_dirent(&error, uio, 860 PROCFS_FILENO(pfs->pfs_pid, pt->pt_pfstype), pt->pt_type, 861 pt->pt_namlen, pt->pt_name); 862 if (retval) 863 break; 864 } 865 866 uio->uio_offset = i; 867 868 return(0); 869 } 870 871 static int 872 procfs_readdir_root(struct vop_readdir_args *ap) 873 { 874 int error, i, pcnt, retval; 875 struct uio *uio = ap->a_uio; 876 volatile struct proc *p = LIST_FIRST(&allproc); 877 ino_t d_ino; 878 const char *d_name; 879 char d_name_pid[20]; 880 size_t d_namlen; 881 uint8_t d_type; 882 883 error = 0; 884 pcnt = 0; 885 i = uio->uio_offset; 886 887 for (; p && uio->uio_resid > 0 && !error; i++, pcnt++) { 888 switch (i) { 889 case 0: /* `.' */ 890 d_ino = PROCFS_FILENO(0, Proot); 891 d_name = "."; 892 d_namlen = 1; 893 d_type = DT_DIR; 894 break; 895 case 1: /* `..' */ 896 d_ino = PROCFS_FILENO(0, Proot); 897 d_name = ".."; 898 d_namlen = 2; 899 d_type = DT_DIR; 900 break; 901 902 case 2: 903 d_ino = PROCFS_FILENO(0, Pcurproc); 904 d_namlen = 7; 905 d_name = "curproc"; 906 d_type = DT_LNK; 907 break; 908 909 910 default: 911 while (pcnt < i) { 912 p = LIST_NEXT(p, p_list); 913 if (!p) 914 goto done; 915 if (!PRISON_CHECK(ap->a_cred, p->p_ucred)) 916 continue; 917 pcnt++; 918 } 919 while (!PRISON_CHECK(ap->a_cred, p->p_ucred)) { 920 p = LIST_NEXT(p, p_list); 921 if (!p) 922 goto done; 923 } 924 if (ps_showallprocs == 0 && 925 ap->a_cred->cr_uid != 0 && 926 ap->a_cred->cr_uid != p->p_ucred->cr_uid) { 927 p = LIST_NEXT(p, p_list); 928 if (!p) 929 goto done; 930 continue; 931 } 932 933 d_ino = PROCFS_FILENO(p->p_pid, Pproc); 934 d_namlen = snprintf(d_name_pid, sizeof(d_name_pid), 935 "%ld", (long)p->p_pid); 936 d_name = d_name_pid; 937 d_type = DT_DIR; 938 p = LIST_NEXT(p, p_list); 939 break; 940 } 941 942 if (p) 943 PHOLD(p); 944 retval = vop_write_dirent(&error, uio, 945 d_ino, d_type, d_namlen, d_name); 946 if (p) 947 PRELE(p); 948 if (retval) 949 break; 950 } 951 done: 952 uio->uio_offset = i; 953 return(0); 954 } 955 956 /* 957 * readlink reads the link of `curproc' or `file' 958 */ 959 static int 960 procfs_readlink(struct vop_readlink_args *ap) 961 { 962 char buf[16]; /* should be enough */ 963 struct proc *procp; 964 struct vnode *vp = ap->a_vp; 965 struct pfsnode *pfs = VTOPFS(vp); 966 char *fullpath, *freepath; 967 int error, len; 968 969 switch (pfs->pfs_type) { 970 case Pcurproc: 971 if (pfs->pfs_fileno != PROCFS_FILENO(0, Pcurproc)) 972 return (EINVAL); 973 974 len = snprintf(buf, sizeof(buf), "%ld", (long)curproc->p_pid); 975 976 return (uiomove(buf, len, ap->a_uio)); 977 /* 978 * There _should_ be no way for an entire process to disappear 979 * from under us... 980 */ 981 case Pfile: 982 procp = PFIND(pfs->pfs_pid); 983 if (procp == NULL || procp->p_ucred == NULL) { 984 printf("procfs_readlink: pid %d disappeared\n", 985 pfs->pfs_pid); 986 return (uiomove("unknown", sizeof("unknown") - 1, 987 ap->a_uio)); 988 } 989 error = vn_fullpath(procp, NULL, &fullpath, &freepath); 990 if (error != 0) 991 return (uiomove("unknown", sizeof("unknown") - 1, 992 ap->a_uio)); 993 error = uiomove(fullpath, strlen(fullpath), ap->a_uio); 994 free(freepath, M_TEMP); 995 return (error); 996 default: 997 return (EINVAL); 998 } 999 } 1000 1001 /* 1002 * convert decimal ascii to pid_t 1003 */ 1004 static pid_t 1005 atopid(const char *b, u_int len) 1006 { 1007 pid_t p = 0; 1008 1009 while (len--) { 1010 char c = *b++; 1011 if (c < '0' || c > '9') 1012 return (NO_PID); 1013 p = 10 * p + (c - '0'); 1014 if (p > PID_MAX) 1015 return (NO_PID); 1016 } 1017 1018 return (p); 1019 } 1020 1021 /* 1022 * procfs vnode operations. 1023 */ 1024 struct vnodeopv_entry_desc procfs_vnodeop_entries[] = { 1025 { &vop_default_desc, vop_defaultop }, 1026 { &vop_access_desc, (vnodeopv_entry_t) procfs_access }, 1027 { &vop_advlock_desc, (vnodeopv_entry_t) procfs_badop }, 1028 { &vop_bmap_desc, (vnodeopv_entry_t) procfs_bmap }, 1029 { &vop_close_desc, (vnodeopv_entry_t) procfs_close }, 1030 { &vop_old_create_desc, (vnodeopv_entry_t) procfs_badop }, 1031 { &vop_getattr_desc, (vnodeopv_entry_t) procfs_getattr }, 1032 { &vop_inactive_desc, (vnodeopv_entry_t) procfs_inactive }, 1033 { &vop_old_link_desc, (vnodeopv_entry_t) procfs_badop }, 1034 { &vop_old_lookup_desc, (vnodeopv_entry_t) procfs_lookup }, 1035 { &vop_old_mkdir_desc, (vnodeopv_entry_t) procfs_badop }, 1036 { &vop_old_mknod_desc, (vnodeopv_entry_t) procfs_badop }, 1037 { &vop_open_desc, (vnodeopv_entry_t) procfs_open }, 1038 { &vop_pathconf_desc, (vnodeopv_entry_t) vop_stdpathconf }, 1039 { &vop_print_desc, (vnodeopv_entry_t) procfs_print }, 1040 { &vop_read_desc, (vnodeopv_entry_t) procfs_rw }, 1041 { &vop_readdir_desc, (vnodeopv_entry_t) procfs_readdir }, 1042 { &vop_readlink_desc, (vnodeopv_entry_t) procfs_readlink }, 1043 { &vop_reclaim_desc, (vnodeopv_entry_t) procfs_reclaim }, 1044 { &vop_old_remove_desc, (vnodeopv_entry_t) procfs_badop }, 1045 { &vop_old_rename_desc, (vnodeopv_entry_t) procfs_badop }, 1046 { &vop_old_rmdir_desc, (vnodeopv_entry_t) procfs_badop }, 1047 { &vop_setattr_desc, (vnodeopv_entry_t) procfs_setattr }, 1048 { &vop_old_symlink_desc, (vnodeopv_entry_t) procfs_badop }, 1049 { &vop_write_desc, (vnodeopv_entry_t) procfs_rw }, 1050 { &vop_ioctl_desc, (vnodeopv_entry_t) procfs_ioctl }, 1051 { NULL, NULL } 1052 }; 1053 1054