1 /* $NetBSD: vfs_lookup.c,v 1.116 2009/06/29 05:00:14 dholland Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * (c) UNIX System Laboratories, Inc. 7 * All or some portions of this file are derived from material licensed 8 * to the University of California by American Telephone and Telegraph 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 * the permission of UNIX System Laboratories, Inc. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)vfs_lookup.c 8.10 (Berkeley) 5/27/95 37 */ 38 39 #include <sys/cdefs.h> 40 __KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.116 2009/06/29 05:00:14 dholland Exp $"); 41 42 #include "opt_magiclinks.h" 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/kernel.h> 47 #include <sys/syslimits.h> 48 #include <sys/time.h> 49 #include <sys/namei.h> 50 #include <sys/vnode.h> 51 #include <sys/mount.h> 52 #include <sys/errno.h> 53 #include <sys/filedesc.h> 54 #include <sys/hash.h> 55 #include <sys/proc.h> 56 #include <sys/syslog.h> 57 #include <sys/kauth.h> 58 #include <sys/ktrace.h> 59 60 #ifndef MAGICLINKS 61 #define MAGICLINKS 0 62 #endif 63 64 struct pathname_internal { 65 char *pathbuf; 66 bool needfree; 67 }; 68 69 int vfs_magiclinks = MAGICLINKS; 70 71 pool_cache_t pnbuf_cache; /* pathname buffer cache */ 72 73 /* 74 * Substitute replacement text for 'magic' strings in symlinks. 75 * Returns 0 if successful, and returns non-zero if an error 76 * occurs. (Currently, the only possible error is running out 77 * of temporary pathname space.) 78 * 79 * Looks for "@<string>" and "@<string>/", where <string> is a 80 * recognized 'magic' string. Replaces the "@<string>" with the 81 * appropriate replacement text. (Note that in some cases the 82 * replacement text may have zero length.) 83 * 84 * This would have been table driven, but the variance in 85 * replacement strings (and replacement string lengths) made 86 * that impractical. 87 */ 88 #define VNL(x) \ 89 (sizeof(x) - 1) 90 91 #define VO '{' 92 #define VC '}' 93 94 #define MATCH(str) \ 95 ((termchar == '/' && i + VNL(str) == *len) || \ 96 (i + VNL(str) < *len && \ 97 cp[i + VNL(str)] == termchar)) && \ 98 !strncmp((str), &cp[i], VNL(str)) 99 100 #define SUBSTITUTE(m, s, sl) \ 101 if ((newlen + (sl)) >= MAXPATHLEN) \ 102 return 1; \ 103 i += VNL(m); \ 104 if (termchar != '/') \ 105 i++; \ 106 (void)memcpy(&tmp[newlen], (s), (sl)); \ 107 newlen += (sl); \ 108 change = 1; \ 109 termchar = '/'; 110 111 static int 112 symlink_magic(struct proc *p, char *cp, size_t *len) 113 { 114 char *tmp; 115 size_t change, i, newlen, slen; 116 char termchar = '/'; 117 char idtmp[11]; /* enough for 32 bit *unsigned* integer */ 118 119 120 tmp = PNBUF_GET(); 121 for (change = i = newlen = 0; i < *len; ) { 122 if (cp[i] != '@') { 123 tmp[newlen++] = cp[i++]; 124 continue; 125 } 126 127 i++; 128 129 /* Check for @{var} syntax. */ 130 if (cp[i] == VO) { 131 termchar = VC; 132 i++; 133 } 134 135 /* 136 * The following checks should be ordered according 137 * to frequency of use. 138 */ 139 if (MATCH("machine_arch")) { 140 slen = VNL(MACHINE_ARCH); 141 SUBSTITUTE("machine_arch", MACHINE_ARCH, slen); 142 } else if (MATCH("machine")) { 143 slen = VNL(MACHINE); 144 SUBSTITUTE("machine", MACHINE, slen); 145 } else if (MATCH("hostname")) { 146 SUBSTITUTE("hostname", hostname, hostnamelen); 147 } else if (MATCH("osrelease")) { 148 slen = strlen(osrelease); 149 SUBSTITUTE("osrelease", osrelease, slen); 150 } else if (MATCH("emul")) { 151 slen = strlen(p->p_emul->e_name); 152 SUBSTITUTE("emul", p->p_emul->e_name, slen); 153 } else if (MATCH("kernel_ident")) { 154 slen = strlen(kernel_ident); 155 SUBSTITUTE("kernel_ident", kernel_ident, slen); 156 } else if (MATCH("domainname")) { 157 SUBSTITUTE("domainname", domainname, domainnamelen); 158 } else if (MATCH("ostype")) { 159 slen = strlen(ostype); 160 SUBSTITUTE("ostype", ostype, slen); 161 } else if (MATCH("uid")) { 162 slen = snprintf(idtmp, sizeof(idtmp), "%u", 163 kauth_cred_geteuid(kauth_cred_get())); 164 SUBSTITUTE("uid", idtmp, slen); 165 } else if (MATCH("ruid")) { 166 slen = snprintf(idtmp, sizeof(idtmp), "%u", 167 kauth_cred_getuid(kauth_cred_get())); 168 SUBSTITUTE("ruid", idtmp, slen); 169 } else if (MATCH("gid")) { 170 slen = snprintf(idtmp, sizeof(idtmp), "%u", 171 kauth_cred_getegid(kauth_cred_get())); 172 SUBSTITUTE("gid", idtmp, slen); 173 } else if (MATCH("rgid")) { 174 slen = snprintf(idtmp, sizeof(idtmp), "%u", 175 kauth_cred_getgid(kauth_cred_get())); 176 SUBSTITUTE("rgid", idtmp, slen); 177 } else { 178 tmp[newlen++] = '@'; 179 if (termchar == VC) 180 tmp[newlen++] = VO; 181 } 182 } 183 184 if (change) { 185 (void)memcpy(cp, tmp, newlen); 186 *len = newlen; 187 } 188 PNBUF_PUT(tmp); 189 190 return 0; 191 } 192 193 #undef VNL 194 #undef VO 195 #undef VC 196 #undef MATCH 197 #undef SUBSTITUTE 198 199 /* 200 * Convert a pathname into a pointer to a locked vnode. 201 * 202 * The FOLLOW flag is set when symbolic links are to be followed 203 * when they occur at the end of the name translation process. 204 * Symbolic links are always followed for all other pathname 205 * components other than the last. 206 * 207 * The segflg defines whether the name is to be copied from user 208 * space or kernel space. 209 * 210 * Overall outline of namei: 211 * 212 * copy in name 213 * get starting directory 214 * while (!done && !error) { 215 * call lookup to search path. 216 * if symbolic link, massage name in buffer and continue 217 * } 218 */ 219 int 220 namei(struct nameidata *ndp) 221 { 222 struct cwdinfo *cwdi; /* pointer to cwd state */ 223 char *cp; /* pointer into pathname argument */ 224 struct vnode *dp; /* the directory we are searching */ 225 struct iovec aiov; /* uio for reading symbolic links */ 226 struct lwp *l = curlwp; /* thread doing namei() */ 227 struct uio auio; 228 int error; 229 size_t linklen; 230 struct componentname *cnp = &ndp->ni_cnd; 231 232 #ifdef DIAGNOSTIC 233 if (!cnp->cn_cred) 234 panic("namei: bad cred/proc"); 235 if (cnp->cn_nameiop & (~OPMASK)) 236 panic("namei: nameiop contaminated with flags"); 237 if (cnp->cn_flags & OPMASK) 238 panic("namei: flags contaminated with nameiops"); 239 #endif 240 241 /* 242 * Get a buffer for the name to be translated, and copy the 243 * name into the buffer. 244 */ 245 if ((cnp->cn_flags & HASBUF) == 0) 246 cnp->cn_pnbuf = PNBUF_GET(); 247 emul_retry: 248 if (ndp->ni_segflg == UIO_SYSSPACE) 249 error = copystr(ndp->ni_dirp, cnp->cn_pnbuf, 250 MAXPATHLEN, &ndp->ni_pathlen); 251 else 252 error = copyinstr(ndp->ni_dirp, cnp->cn_pnbuf, 253 MAXPATHLEN, &ndp->ni_pathlen); 254 255 /* 256 * POSIX.1 requirement: "" is not a valid file name. 257 */ 258 if (!error && ndp->ni_pathlen == 1) 259 error = ENOENT; 260 261 if (error) { 262 PNBUF_PUT(cnp->cn_pnbuf); 263 ndp->ni_vp = NULL; 264 return (error); 265 } 266 ndp->ni_loopcnt = 0; 267 268 /* 269 * Get root directory for the translation. 270 */ 271 cwdi = l->l_proc->p_cwdi; 272 rw_enter(&cwdi->cwdi_lock, RW_READER); 273 dp = cwdi->cwdi_rdir; 274 if (dp == NULL) 275 dp = rootvnode; 276 ndp->ni_rootdir = dp; 277 278 /* 279 * Check if starting from root directory or current directory. 280 */ 281 if (cnp->cn_pnbuf[0] == '/') { 282 if (cnp->cn_flags & TRYEMULROOT) { 283 if (cnp->cn_flags & EMULROOTSET) { 284 /* Called from (eg) emul_find_interp() */ 285 dp = ndp->ni_erootdir; 286 } else { 287 if (cwdi->cwdi_edir == NULL 288 || (cnp->cn_pnbuf[1] == '.' 289 && cnp->cn_pnbuf[2] == '.' 290 && cnp->cn_pnbuf[3] == '/')) { 291 ndp->ni_erootdir = NULL; 292 } else { 293 dp = cwdi->cwdi_edir; 294 ndp->ni_erootdir = dp; 295 } 296 } 297 } else { 298 ndp->ni_erootdir = NULL; 299 if (cnp->cn_flags & NOCHROOT) 300 dp = ndp->ni_rootdir = rootvnode; 301 } 302 } else { 303 dp = cwdi->cwdi_cdir; 304 ndp->ni_erootdir = NULL; 305 } 306 VREF(dp); 307 rw_exit(&cwdi->cwdi_lock); 308 309 if (ktrpoint(KTR_NAMEI)) { 310 if (ndp->ni_erootdir != NULL) { 311 /* 312 * To make any sense, the trace entry need to have the 313 * text of the emulation path prepended. 314 * Usually we can get this from the current process, 315 * but when called from emul_find_interp() it is only 316 * in the exec_package - so we get it passed in ni_next 317 * (this is a hack). 318 */ 319 const char *emul_path; 320 if (cnp->cn_flags & EMULROOTSET) 321 emul_path = ndp->ni_next; 322 else 323 emul_path = l->l_proc->p_emul->e_path; 324 ktrnamei2(emul_path, strlen(emul_path), 325 cnp->cn_pnbuf, ndp->ni_pathlen); 326 } else 327 ktrnamei(cnp->cn_pnbuf, ndp->ni_pathlen); 328 } 329 330 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY); 331 /* Loop through symbolic links */ 332 for (;;) { 333 if (!dp->v_mount) { 334 /* Give up if the directory is no longer mounted */ 335 vput(dp); 336 PNBUF_PUT(cnp->cn_pnbuf); 337 return (ENOENT); 338 } 339 cnp->cn_nameptr = cnp->cn_pnbuf; 340 ndp->ni_startdir = dp; 341 error = lookup(ndp); 342 if (error != 0) { 343 if (ndp->ni_dvp) { 344 vput(ndp->ni_dvp); 345 } 346 if (ndp->ni_erootdir != NULL) { 347 /* Retry the whole thing from the normal root */ 348 cnp->cn_flags &= ~TRYEMULROOT; 349 goto emul_retry; 350 } 351 PNBUF_PUT(cnp->cn_pnbuf); 352 return (error); 353 } 354 355 /* 356 * Check for symbolic link 357 */ 358 if ((cnp->cn_flags & ISSYMLINK) == 0) { 359 if ((cnp->cn_flags & LOCKPARENT) == 0 && ndp->ni_dvp) { 360 if (ndp->ni_dvp == ndp->ni_vp) { 361 vrele(ndp->ni_dvp); 362 } else { 363 vput(ndp->ni_dvp); 364 } 365 } 366 if ((cnp->cn_flags & (SAVENAME | SAVESTART)) == 0) { 367 PNBUF_PUT(cnp->cn_pnbuf); 368 #if defined(DIAGNOSTIC) 369 cnp->cn_pnbuf = NULL; 370 #endif /* defined(DIAGNOSTIC) */ 371 } else { 372 cnp->cn_flags |= HASBUF; 373 } 374 return (0); 375 } 376 377 if (ndp->ni_loopcnt++ >= MAXSYMLINKS) { 378 error = ELOOP; 379 break; 380 } 381 if (ndp->ni_vp->v_mount->mnt_flag & MNT_SYMPERM) { 382 error = VOP_ACCESS(ndp->ni_vp, VEXEC, cnp->cn_cred); 383 if (error != 0) 384 break; 385 } 386 if (ndp->ni_pathlen > 1) 387 cp = PNBUF_GET(); 388 else 389 cp = cnp->cn_pnbuf; 390 aiov.iov_base = cp; 391 aiov.iov_len = MAXPATHLEN; 392 auio.uio_iov = &aiov; 393 auio.uio_iovcnt = 1; 394 auio.uio_offset = 0; 395 auio.uio_rw = UIO_READ; 396 auio.uio_resid = MAXPATHLEN; 397 UIO_SETUP_SYSSPACE(&auio); 398 error = VOP_READLINK(ndp->ni_vp, &auio, cnp->cn_cred); 399 if (error) { 400 badlink: 401 if (ndp->ni_pathlen > 1) 402 PNBUF_PUT(cp); 403 break; 404 } 405 linklen = MAXPATHLEN - auio.uio_resid; 406 if (linklen == 0) { 407 error = ENOENT; 408 goto badlink; 409 } 410 411 /* 412 * Do symlink substitution, if appropriate, and 413 * check length for potential overflow. 414 */ 415 if ((vfs_magiclinks && 416 symlink_magic(l->l_proc, cp, &linklen)) || 417 (linklen + ndp->ni_pathlen >= MAXPATHLEN)) { 418 error = ENAMETOOLONG; 419 goto badlink; 420 } 421 if (ndp->ni_pathlen > 1) { 422 memcpy(cp + linklen, ndp->ni_next, ndp->ni_pathlen); 423 PNBUF_PUT(cnp->cn_pnbuf); 424 cnp->cn_pnbuf = cp; 425 } else 426 cnp->cn_pnbuf[linklen] = '\0'; 427 ndp->ni_pathlen += linklen; 428 vput(ndp->ni_vp); 429 dp = ndp->ni_dvp; 430 431 /* 432 * Check if root directory should replace current directory. 433 */ 434 if (cnp->cn_pnbuf[0] == '/') { 435 vput(dp); 436 /* Keep absolute symbolic links inside emulation root */ 437 dp = ndp->ni_erootdir; 438 if (dp == NULL || (cnp->cn_pnbuf[1] == '.' 439 && cnp->cn_pnbuf[2] == '.' 440 && cnp->cn_pnbuf[3] == '/')) { 441 ndp->ni_erootdir = NULL; 442 dp = ndp->ni_rootdir; 443 } 444 VREF(dp); 445 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY); 446 } 447 } 448 /* Failed to process a symbolic link */ 449 KASSERT(ndp->ni_dvp != ndp->ni_vp); 450 vput(ndp->ni_dvp); 451 vput(ndp->ni_vp); 452 ndp->ni_vp = NULL; 453 PNBUF_PUT(cnp->cn_pnbuf); 454 return (error); 455 } 456 457 /* 458 * Determine the namei hash (for cn_hash) for name. 459 * If *ep != NULL, hash from name to ep-1. 460 * If *ep == NULL, hash from name until the first NUL or '/', and 461 * return the location of this termination character in *ep. 462 * 463 * This function returns an equivalent hash to the MI hash32_strn(). 464 * The latter isn't used because in the *ep == NULL case, determining 465 * the length of the string to the first NUL or `/' and then calling 466 * hash32_strn() involves unnecessary double-handling of the data. 467 */ 468 uint32_t 469 namei_hash(const char *name, const char **ep) 470 { 471 uint32_t hash; 472 473 hash = HASH32_STR_INIT; 474 if (*ep != NULL) { 475 for (; name < *ep; name++) 476 hash = hash * 33 + *(const uint8_t *)name; 477 } else { 478 for (; *name != '\0' && *name != '/'; name++) 479 hash = hash * 33 + *(const uint8_t *)name; 480 *ep = name; 481 } 482 return (hash + (hash >> 5)); 483 } 484 485 /* 486 * Search a pathname. 487 * This is a very central and rather complicated routine. 488 * 489 * The pathname is pointed to by ni_ptr and is of length ni_pathlen. 490 * The starting directory is taken from ni_startdir. The pathname is 491 * descended until done, or a symbolic link is encountered. The variable 492 * ni_more is clear if the path is completed; it is set to one if a 493 * symbolic link needing interpretation is encountered. 494 * 495 * The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on 496 * whether the name is to be looked up, created, renamed, or deleted. 497 * When CREATE, RENAME, or DELETE is specified, information usable in 498 * creating, renaming, or deleting a directory entry may be calculated. 499 * If flag has LOCKPARENT or'ed into it, the parent directory is returned 500 * locked. Otherwise the parent directory is not returned. If the target 501 * of the pathname exists and LOCKLEAF is or'ed into the flag the target 502 * is returned locked, otherwise it is returned unlocked. When creating 503 * or renaming and LOCKPARENT is specified, the target may not be ".". 504 * When deleting and LOCKPARENT is specified, the target may be ".". 505 * 506 * Overall outline of lookup: 507 * 508 * dirloop: 509 * identify next component of name at ndp->ni_ptr 510 * handle degenerate case where name is null string 511 * if .. and crossing mount points and on mounted filesys, find parent 512 * call VOP_LOOKUP routine for next component name 513 * directory vnode returned in ni_dvp, locked. 514 * component vnode returned in ni_vp (if it exists), locked. 515 * if result vnode is mounted on and crossing mount points, 516 * find mounted on vnode 517 * if more components of name, do next level at dirloop 518 * return the answer in ni_vp, locked if LOCKLEAF set 519 * if LOCKPARENT set, return locked parent in ni_dvp 520 */ 521 int 522 lookup(struct nameidata *ndp) 523 { 524 const char *cp; /* pointer into pathname argument */ 525 struct vnode *dp = 0; /* the directory we are searching */ 526 struct vnode *tdp; /* saved dp */ 527 struct mount *mp; /* mount table entry */ 528 int docache; /* == 0 do not cache last component */ 529 int rdonly; /* lookup read-only flag bit */ 530 int error = 0; 531 int slashes; 532 struct componentname *cnp = &ndp->ni_cnd; 533 struct lwp *l = curlwp; 534 535 /* 536 * Setup: break out flag bits into variables. 537 */ 538 docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE; 539 if (cnp->cn_nameiop == DELETE) 540 docache = 0; 541 rdonly = cnp->cn_flags & RDONLY; 542 ndp->ni_dvp = NULL; 543 cnp->cn_flags &= ~ISSYMLINK; 544 dp = ndp->ni_startdir; 545 ndp->ni_startdir = NULLVP; 546 547 /* 548 * If we have a leading string of slashes, remove them, and just make 549 * sure the current node is a directory. 550 */ 551 cp = cnp->cn_nameptr; 552 if (*cp == '/') { 553 do { 554 cp++; 555 } while (*cp == '/'); 556 ndp->ni_pathlen -= cp - cnp->cn_nameptr; 557 cnp->cn_nameptr = cp; 558 559 if (dp->v_type != VDIR) { 560 error = ENOTDIR; 561 vput(dp); 562 goto bad; 563 } 564 565 /* 566 * If we've exhausted the path name, then just return the 567 * current node. 568 */ 569 if (cnp->cn_nameptr[0] == '\0') { 570 ndp->ni_vp = dp; 571 cnp->cn_flags |= ISLASTCN; 572 goto terminal; 573 } 574 } 575 576 dirloop: 577 /* 578 * Search a new directory. 579 * 580 * The cn_hash value is for use by vfs_cache. 581 * The last component of the filename is left accessible via 582 * cnp->cn_nameptr for callers that need the name. Callers needing 583 * the name set the SAVENAME flag. When done, they assume 584 * responsibility for freeing the pathname buffer. 585 * 586 * At this point, our only vnode state is that "dp" is held and locked. 587 */ 588 cnp->cn_consume = 0; 589 cp = NULL; 590 cnp->cn_hash = namei_hash(cnp->cn_nameptr, &cp); 591 cnp->cn_namelen = cp - cnp->cn_nameptr; 592 if (cnp->cn_namelen > NAME_MAX) { 593 vput(dp); 594 error = ENAMETOOLONG; 595 ndp->ni_dvp = NULL; 596 goto bad; 597 } 598 #ifdef NAMEI_DIAGNOSTIC 599 { char c = *cp; 600 *(char *)cp = '\0'; 601 printf("{%s}: ", cnp->cn_nameptr); 602 *(char *)cp = c; } 603 #endif /* NAMEI_DIAGNOSTIC */ 604 ndp->ni_pathlen -= cnp->cn_namelen; 605 ndp->ni_next = cp; 606 /* 607 * If this component is followed by a slash, then move the pointer to 608 * the next component forward, and remember that this component must be 609 * a directory. 610 */ 611 if (*cp == '/') { 612 do { 613 cp++; 614 } while (*cp == '/'); 615 slashes = cp - ndp->ni_next; 616 ndp->ni_pathlen -= slashes; 617 ndp->ni_next = cp; 618 cnp->cn_flags |= REQUIREDIR; 619 } else { 620 slashes = 0; 621 cnp->cn_flags &= ~REQUIREDIR; 622 } 623 /* 624 * We do special processing on the last component, whether or not it's 625 * a directory. Cache all intervening lookups, but not the final one. 626 */ 627 if (*cp == '\0') { 628 if (docache) 629 cnp->cn_flags |= MAKEENTRY; 630 else 631 cnp->cn_flags &= ~MAKEENTRY; 632 cnp->cn_flags |= ISLASTCN; 633 } else { 634 cnp->cn_flags |= MAKEENTRY; 635 cnp->cn_flags &= ~ISLASTCN; 636 } 637 if (cnp->cn_namelen == 2 && 638 cnp->cn_nameptr[1] == '.' && cnp->cn_nameptr[0] == '.') 639 cnp->cn_flags |= ISDOTDOT; 640 else 641 cnp->cn_flags &= ~ISDOTDOT; 642 643 /* 644 * Handle "..": two special cases. 645 * 1. If at root directory (e.g. after chroot) 646 * or at absolute root directory 647 * then ignore it so can't get out. 648 * 1a. If at the root of the emulation filesystem go to the real 649 * root. So "/../<path>" is always absolute. 650 * 1b. If we have somehow gotten out of a jail, warn 651 * and also ignore it so we can't get farther out. 652 * 2. If this vnode is the root of a mounted 653 * filesystem, then replace it with the 654 * vnode which was mounted on so we take the 655 * .. in the other file system. 656 */ 657 if (cnp->cn_flags & ISDOTDOT) { 658 struct proc *p = l->l_proc; 659 660 for (;;) { 661 if (dp == ndp->ni_rootdir || dp == rootvnode) { 662 ndp->ni_dvp = dp; 663 ndp->ni_vp = dp; 664 VREF(dp); 665 goto nextname; 666 } 667 if (ndp->ni_rootdir != rootvnode) { 668 int retval; 669 670 VOP_UNLOCK(dp, 0); 671 retval = vn_isunder(dp, ndp->ni_rootdir, l); 672 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY); 673 if (!retval) { 674 /* Oops! We got out of jail! */ 675 log(LOG_WARNING, 676 "chrooted pid %d uid %d (%s) " 677 "detected outside of its chroot\n", 678 p->p_pid, kauth_cred_geteuid(l->l_cred), 679 p->p_comm); 680 /* Put us at the jail root. */ 681 vput(dp); 682 dp = ndp->ni_rootdir; 683 ndp->ni_dvp = dp; 684 ndp->ni_vp = dp; 685 VREF(dp); 686 VREF(dp); 687 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY); 688 goto nextname; 689 } 690 } 691 if ((dp->v_vflag & VV_ROOT) == 0 || 692 (cnp->cn_flags & NOCROSSMOUNT)) 693 break; 694 tdp = dp; 695 dp = dp->v_mount->mnt_vnodecovered; 696 vput(tdp); 697 VREF(dp); 698 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY); 699 } 700 } 701 702 /* 703 * We now have a segment name to search for, and a directory to search. 704 * Again, our only vnode state is that "dp" is held and locked. 705 */ 706 unionlookup: 707 ndp->ni_dvp = dp; 708 ndp->ni_vp = NULL; 709 error = VOP_LOOKUP(dp, &ndp->ni_vp, cnp); 710 if (error != 0) { 711 #ifdef DIAGNOSTIC 712 if (ndp->ni_vp != NULL) 713 panic("leaf `%s' should be empty", cnp->cn_nameptr); 714 #endif /* DIAGNOSTIC */ 715 #ifdef NAMEI_DIAGNOSTIC 716 printf("not found\n"); 717 #endif /* NAMEI_DIAGNOSTIC */ 718 if ((error == ENOENT) && 719 (dp->v_vflag & VV_ROOT) && 720 (dp->v_mount->mnt_flag & MNT_UNION)) { 721 tdp = dp; 722 dp = dp->v_mount->mnt_vnodecovered; 723 vput(tdp); 724 VREF(dp); 725 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY); 726 goto unionlookup; 727 } 728 729 if (error != EJUSTRETURN) 730 goto bad; 731 732 /* 733 * If this was not the last component, or there were trailing 734 * slashes, and we are not going to create a directory, 735 * then the name must exist. 736 */ 737 if ((cnp->cn_flags & (REQUIREDIR | CREATEDIR)) == REQUIREDIR) { 738 error = ENOENT; 739 goto bad; 740 } 741 742 /* 743 * If creating and at end of pathname, then can consider 744 * allowing file to be created. 745 */ 746 if (rdonly) { 747 error = EROFS; 748 goto bad; 749 } 750 751 /* 752 * We return with ni_vp NULL to indicate that the entry 753 * doesn't currently exist, leaving a pointer to the 754 * (possibly locked) directory vnode in ndp->ni_dvp. 755 */ 756 if (cnp->cn_flags & SAVESTART) { 757 ndp->ni_startdir = ndp->ni_dvp; 758 VREF(ndp->ni_startdir); 759 } 760 return (0); 761 } 762 #ifdef NAMEI_DIAGNOSTIC 763 printf("found\n"); 764 #endif /* NAMEI_DIAGNOSTIC */ 765 766 /* 767 * Take into account any additional components consumed by the 768 * underlying filesystem. This will include any trailing slashes after 769 * the last component consumed. 770 */ 771 if (cnp->cn_consume > 0) { 772 ndp->ni_pathlen -= cnp->cn_consume - slashes; 773 ndp->ni_next += cnp->cn_consume - slashes; 774 cnp->cn_consume = 0; 775 if (ndp->ni_next[0] == '\0') 776 cnp->cn_flags |= ISLASTCN; 777 } 778 779 dp = ndp->ni_vp; 780 781 /* 782 * "dp" and "ndp->ni_dvp" are both locked and held, 783 * and may be the same vnode. 784 */ 785 786 /* 787 * Check to see if the vnode has been mounted on; 788 * if so find the root of the mounted file system. 789 */ 790 while (dp->v_type == VDIR && (mp = dp->v_mountedhere) && 791 (cnp->cn_flags & NOCROSSMOUNT) == 0) { 792 error = vfs_busy(mp, NULL); 793 if (error != 0) { 794 vput(dp); 795 goto bad; 796 } 797 KASSERT(ndp->ni_dvp != dp); 798 VOP_UNLOCK(ndp->ni_dvp, 0); 799 vput(dp); 800 error = VFS_ROOT(mp, &tdp); 801 vfs_unbusy(mp, false, NULL); 802 if (error) { 803 vn_lock(ndp->ni_dvp, LK_EXCLUSIVE | LK_RETRY); 804 goto bad; 805 } 806 VOP_UNLOCK(tdp, 0); 807 ndp->ni_vp = dp = tdp; 808 vn_lock(ndp->ni_dvp, LK_EXCLUSIVE | LK_RETRY); 809 vn_lock(ndp->ni_vp, LK_EXCLUSIVE | LK_RETRY); 810 } 811 812 /* 813 * Check for symbolic link. Back up over any slashes that we skipped, 814 * as we will need them again. 815 */ 816 if ((dp->v_type == VLNK) && (cnp->cn_flags & (FOLLOW|REQUIREDIR))) { 817 ndp->ni_pathlen += slashes; 818 ndp->ni_next -= slashes; 819 cnp->cn_flags |= ISSYMLINK; 820 return (0); 821 } 822 823 /* 824 * Check for directory, if the component was followed by a series of 825 * slashes. 826 */ 827 if ((dp->v_type != VDIR) && (cnp->cn_flags & REQUIREDIR)) { 828 error = ENOTDIR; 829 KASSERT(dp != ndp->ni_dvp); 830 vput(dp); 831 goto bad; 832 } 833 834 nextname: 835 836 /* 837 * Not a symbolic link. If this was not the last component, then 838 * continue at the next component, else return. 839 */ 840 if (!(cnp->cn_flags & ISLASTCN)) { 841 cnp->cn_nameptr = ndp->ni_next; 842 if (ndp->ni_dvp == dp) { 843 vrele(ndp->ni_dvp); 844 } else { 845 vput(ndp->ni_dvp); 846 } 847 goto dirloop; 848 } 849 850 terminal: 851 if (dp == ndp->ni_erootdir) { 852 /* 853 * We are about to return the emulation root. 854 * This isn't a good idea because code might repeatedly 855 * lookup ".." until the file matches that returned 856 * for "/" and loop forever. 857 * So convert it to the real root. 858 */ 859 if (ndp->ni_dvp == dp) 860 vrele(dp); 861 else 862 if (ndp->ni_dvp != NULL) 863 vput(ndp->ni_dvp); 864 ndp->ni_dvp = NULL; 865 vput(dp); 866 dp = ndp->ni_rootdir; 867 VREF(dp); 868 vn_lock(dp, LK_EXCLUSIVE | LK_RETRY); 869 ndp->ni_vp = dp; 870 } 871 872 /* 873 * If the caller requested the parent node (i.e. 874 * it's a CREATE, DELETE, or RENAME), and we don't have one 875 * (because this is the root directory), then we must fail. 876 */ 877 if (ndp->ni_dvp == NULL && cnp->cn_nameiop != LOOKUP) { 878 switch (cnp->cn_nameiop) { 879 case CREATE: 880 error = EEXIST; 881 break; 882 case DELETE: 883 case RENAME: 884 error = EBUSY; 885 break; 886 default: 887 KASSERT(0); 888 } 889 vput(dp); 890 goto bad; 891 } 892 893 /* 894 * Disallow directory write attempts on read-only lookups. 895 * Prefers EEXIST over EROFS for the CREATE case. 896 */ 897 if (rdonly && 898 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) { 899 error = EROFS; 900 if (dp != ndp->ni_dvp) { 901 vput(dp); 902 } 903 goto bad; 904 } 905 if (ndp->ni_dvp != NULL) { 906 if (cnp->cn_flags & SAVESTART) { 907 ndp->ni_startdir = ndp->ni_dvp; 908 VREF(ndp->ni_startdir); 909 } 910 } 911 if ((cnp->cn_flags & LOCKLEAF) == 0) { 912 VOP_UNLOCK(dp, 0); 913 } 914 return (0); 915 916 bad: 917 ndp->ni_vp = NULL; 918 return (error); 919 } 920 921 /* 922 * Reacquire a path name component. 923 * dvp is locked on entry and exit. 924 * *vpp is locked on exit unless it's NULL. 925 */ 926 int 927 relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp) 928 { 929 int rdonly; /* lookup read-only flag bit */ 930 int error = 0; 931 #ifdef DEBUG 932 uint32_t newhash; /* DEBUG: check name hash */ 933 const char *cp; /* DEBUG: check name ptr/len */ 934 #endif /* DEBUG */ 935 936 /* 937 * Setup: break out flag bits into variables. 938 */ 939 rdonly = cnp->cn_flags & RDONLY; 940 cnp->cn_flags &= ~ISSYMLINK; 941 942 /* 943 * Search a new directory. 944 * 945 * The cn_hash value is for use by vfs_cache. 946 * The last component of the filename is left accessible via 947 * cnp->cn_nameptr for callers that need the name. Callers needing 948 * the name set the SAVENAME flag. When done, they assume 949 * responsibility for freeing the pathname buffer. 950 */ 951 #ifdef DEBUG 952 cp = NULL; 953 newhash = namei_hash(cnp->cn_nameptr, &cp); 954 if ((uint32_t)newhash != (uint32_t)cnp->cn_hash) 955 panic("relookup: bad hash"); 956 if (cnp->cn_namelen != cp - cnp->cn_nameptr) 957 panic("relookup: bad len"); 958 while (*cp == '/') 959 cp++; 960 if (*cp != 0) 961 panic("relookup: not last component"); 962 #endif /* DEBUG */ 963 964 /* 965 * Check for degenerate name (e.g. / or "") 966 * which is a way of talking about a directory, 967 * e.g. like "/." or ".". 968 */ 969 if (cnp->cn_nameptr[0] == '\0') 970 panic("relookup: null name"); 971 972 if (cnp->cn_flags & ISDOTDOT) 973 panic("relookup: lookup on dot-dot"); 974 975 /* 976 * We now have a segment name to search for, and a directory to search. 977 */ 978 if ((error = VOP_LOOKUP(dvp, vpp, cnp)) != 0) { 979 #ifdef DIAGNOSTIC 980 if (*vpp != NULL) 981 panic("leaf `%s' should be empty", cnp->cn_nameptr); 982 #endif 983 if (error != EJUSTRETURN) 984 goto bad; 985 } 986 987 #ifdef DIAGNOSTIC 988 /* 989 * Check for symbolic link 990 */ 991 if (*vpp && (*vpp)->v_type == VLNK && (cnp->cn_flags & FOLLOW)) 992 panic("relookup: symlink found"); 993 #endif 994 995 /* 996 * Check for read-only lookups. 997 */ 998 if (rdonly && cnp->cn_nameiop != LOOKUP) { 999 error = EROFS; 1000 if (*vpp) { 1001 vput(*vpp); 1002 } 1003 goto bad; 1004 } 1005 if (cnp->cn_flags & SAVESTART) 1006 VREF(dvp); 1007 return (0); 1008 1009 bad: 1010 *vpp = NULL; 1011 return (error); 1012 } 1013 1014 /* 1015 * namei_simple - simple forms of namei. 1016 * 1017 * These are wrappers to allow the simple case callers of namei to be 1018 * left alone while everything else changes under them. 1019 */ 1020 1021 /* Flags */ 1022 struct namei_simple_flags_type { 1023 int dummy; 1024 }; 1025 static const struct namei_simple_flags_type ns_nn, ns_nt, ns_fn, ns_ft; 1026 const namei_simple_flags_t NSM_NOFOLLOW_NOEMULROOT = &ns_nn; 1027 const namei_simple_flags_t NSM_NOFOLLOW_TRYEMULROOT = &ns_nt; 1028 const namei_simple_flags_t NSM_FOLLOW_NOEMULROOT = &ns_fn; 1029 const namei_simple_flags_t NSM_FOLLOW_TRYEMULROOT = &ns_ft; 1030 1031 static 1032 int 1033 namei_simple_convert_flags(namei_simple_flags_t sflags) 1034 { 1035 if (sflags == NSM_NOFOLLOW_NOEMULROOT) 1036 return NOFOLLOW | 0; 1037 if (sflags == NSM_NOFOLLOW_TRYEMULROOT) 1038 return NOFOLLOW | TRYEMULROOT; 1039 if (sflags == NSM_FOLLOW_NOEMULROOT) 1040 return FOLLOW | 0; 1041 if (sflags == NSM_FOLLOW_TRYEMULROOT) 1042 return FOLLOW | TRYEMULROOT; 1043 panic("namei_simple_convert_flags: bogus sflags\n"); 1044 return 0; 1045 } 1046 1047 int 1048 namei_simple_kernel(const char *path, namei_simple_flags_t sflags, 1049 struct vnode **vp_ret) 1050 { 1051 struct nameidata nd; 1052 int err; 1053 1054 NDINIT(&nd, 1055 LOOKUP, 1056 namei_simple_convert_flags(sflags), 1057 UIO_SYSSPACE, 1058 path); 1059 err = namei(&nd); 1060 if (err != 0) { 1061 return err; 1062 } 1063 *vp_ret = nd.ni_vp; 1064 return 0; 1065 } 1066 1067 int 1068 namei_simple_user(const char *path, namei_simple_flags_t sflags, 1069 struct vnode **vp_ret) 1070 { 1071 struct nameidata nd; 1072 int err; 1073 1074 NDINIT(&nd, 1075 LOOKUP, 1076 namei_simple_convert_flags(sflags), 1077 UIO_USERSPACE, 1078 path); 1079 err = namei(&nd); 1080 if (err != 0) { 1081 return err; 1082 } 1083 *vp_ret = nd.ni_vp; 1084 return 0; 1085 } 1086