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