1 1.239 andvar /* $NetBSD: vfs_lookup.c,v 1.239 2025/09/14 14:24:13 andvar Exp $ */ 2 1.13 cgd 3 1.10 cgd /* 4 1.12 mycroft * Copyright (c) 1982, 1986, 1989, 1993 5 1.12 mycroft * The Regents of the University of California. All rights reserved. 6 1.10 cgd * (c) UNIX System Laboratories, Inc. 7 1.10 cgd * All or some portions of this file are derived from material licensed 8 1.10 cgd * to the University of California by American Telephone and Telegraph 9 1.10 cgd * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 1.10 cgd * the permission of UNIX System Laboratories, Inc. 11 1.10 cgd * 12 1.10 cgd * Redistribution and use in source and binary forms, with or without 13 1.10 cgd * modification, are permitted provided that the following conditions 14 1.10 cgd * are met: 15 1.10 cgd * 1. Redistributions of source code must retain the above copyright 16 1.10 cgd * notice, this list of conditions and the following disclaimer. 17 1.10 cgd * 2. Redistributions in binary form must reproduce the above copyright 18 1.10 cgd * notice, this list of conditions and the following disclaimer in the 19 1.10 cgd * documentation and/or other materials provided with the distribution. 20 1.49 agc * 3. Neither the name of the University nor the names of its contributors 21 1.10 cgd * may be used to endorse or promote products derived from this software 22 1.10 cgd * without specific prior written permission. 23 1.10 cgd * 24 1.10 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 1.10 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 1.10 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 1.10 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 1.10 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 1.10 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 1.10 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 1.10 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 1.10 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 1.10 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 1.10 cgd * SUCH DAMAGE. 35 1.10 cgd * 36 1.26 fvdl * @(#)vfs_lookup.c 8.10 (Berkeley) 5/27/95 37 1.10 cgd */ 38 1.38 lukem 39 1.38 lukem #include <sys/cdefs.h> 40 1.239 andvar __KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.239 2025/09/14 14:24:13 andvar Exp $"); 41 1.27 thorpej 42 1.203 pooka #ifdef _KERNEL_OPT 43 1.67 chs #include "opt_magiclinks.h" 44 1.203 pooka #endif 45 1.10 cgd 46 1.10 cgd #include <sys/param.h> 47 1.236 riastrad #include <sys/types.h> 48 1.236 riastrad 49 1.236 riastrad #include <sys/dirent.h> 50 1.236 riastrad #include <sys/errno.h> 51 1.236 riastrad #include <sys/filedesc.h> 52 1.236 riastrad #include <sys/fstrans.h> 53 1.236 riastrad #include <sys/hash.h> 54 1.236 riastrad #include <sys/kauth.h> 55 1.61 thorpej #include <sys/kernel.h> 56 1.236 riastrad #include <sys/ktrace.h> 57 1.236 riastrad #include <sys/mount.h> 58 1.236 riastrad #include <sys/namei.h> 59 1.236 riastrad #include <sys/proc.h> 60 1.238 riastrad #include <sys/sdt.h> 61 1.10 cgd #include <sys/syslimits.h> 62 1.236 riastrad #include <sys/syslog.h> 63 1.236 riastrad #include <sys/systm.h> 64 1.10 cgd #include <sys/time.h> 65 1.10 cgd #include <sys/vnode.h> 66 1.215 ad #include <sys/vnode_impl.h> 67 1.12 mycroft 68 1.67 chs #ifndef MAGICLINKS 69 1.67 chs #define MAGICLINKS 0 70 1.67 chs #endif 71 1.67 chs 72 1.67 chs int vfs_magiclinks = MAGICLINKS; 73 1.67 chs 74 1.191 christos __CTASSERT(MAXNAMLEN == NAME_MAX); 75 1.191 christos 76 1.10 cgd /* 77 1.61 thorpej * Substitute replacement text for 'magic' strings in symlinks. 78 1.61 thorpej * Returns 0 if successful, and returns non-zero if an error 79 1.61 thorpej * occurs. (Currently, the only possible error is running out 80 1.61 thorpej * of temporary pathname space.) 81 1.61 thorpej * 82 1.61 thorpej * Looks for "@<string>" and "@<string>/", where <string> is a 83 1.61 thorpej * recognized 'magic' string. Replaces the "@<string>" with the 84 1.61 thorpej * appropriate replacement text. (Note that in some cases the 85 1.61 thorpej * replacement text may have zero length.) 86 1.61 thorpej * 87 1.61 thorpej * This would have been table driven, but the variance in 88 1.61 thorpej * replacement strings (and replacement string lengths) made 89 1.61 thorpej * that impractical. 90 1.61 thorpej */ 91 1.63 thorpej #define VNL(x) \ 92 1.63 thorpej (sizeof(x) - 1) 93 1.63 thorpej 94 1.63 thorpej #define VO '{' 95 1.63 thorpej #define VC '}' 96 1.63 thorpej 97 1.61 thorpej #define MATCH(str) \ 98 1.63 thorpej ((termchar == '/' && i + VNL(str) == *len) || \ 99 1.63 thorpej (i + VNL(str) < *len && \ 100 1.63 thorpej cp[i + VNL(str)] == termchar)) && \ 101 1.63 thorpej !strncmp((str), &cp[i], VNL(str)) 102 1.61 thorpej 103 1.61 thorpej #define SUBSTITUTE(m, s, sl) \ 104 1.115 christos if ((newlen + (sl)) >= MAXPATHLEN) \ 105 1.115 christos return 1; \ 106 1.63 thorpej i += VNL(m); \ 107 1.63 thorpej if (termchar != '/') \ 108 1.63 thorpej i++; \ 109 1.115 christos (void)memcpy(&tmp[newlen], (s), (sl)); \ 110 1.63 thorpej newlen += (sl); \ 111 1.63 thorpej change = 1; \ 112 1.63 thorpej termchar = '/'; 113 1.61 thorpej 114 1.61 thorpej static int 115 1.115 christos symlink_magic(struct proc *p, char *cp, size_t *len) 116 1.61 thorpej { 117 1.66 yamt char *tmp; 118 1.115 christos size_t change, i, newlen, slen; 119 1.115 christos char termchar = '/'; 120 1.115 christos char idtmp[11]; /* enough for 32 bit *unsigned* integer */ 121 1.101 mjf 122 1.61 thorpej 123 1.66 yamt tmp = PNBUF_GET(); 124 1.61 thorpej for (change = i = newlen = 0; i < *len; ) { 125 1.63 thorpej if (cp[i] != '@') { 126 1.61 thorpej tmp[newlen++] = cp[i++]; 127 1.63 thorpej continue; 128 1.63 thorpej } 129 1.63 thorpej 130 1.63 thorpej i++; 131 1.63 thorpej 132 1.63 thorpej /* Check for @{var} syntax. */ 133 1.63 thorpej if (cp[i] == VO) { 134 1.63 thorpej termchar = VC; 135 1.61 thorpej i++; 136 1.63 thorpej } 137 1.63 thorpej 138 1.63 thorpej /* 139 1.63 thorpej * The following checks should be ordered according 140 1.63 thorpej * to frequency of use. 141 1.63 thorpej */ 142 1.63 thorpej if (MATCH("machine_arch")) { 143 1.234 mlelstv slen = strlen(PROC_MACHINE_ARCH(p)); 144 1.234 mlelstv SUBSTITUTE("machine_arch", PROC_MACHINE_ARCH(p), slen); 145 1.63 thorpej } else if (MATCH("machine")) { 146 1.115 christos slen = VNL(MACHINE); 147 1.115 christos SUBSTITUTE("machine", MACHINE, slen); 148 1.63 thorpej } else if (MATCH("hostname")) { 149 1.115 christos SUBSTITUTE("hostname", hostname, hostnamelen); 150 1.63 thorpej } else if (MATCH("osrelease")) { 151 1.115 christos slen = strlen(osrelease); 152 1.115 christos SUBSTITUTE("osrelease", osrelease, slen); 153 1.63 thorpej } else if (MATCH("emul")) { 154 1.115 christos slen = strlen(p->p_emul->e_name); 155 1.115 christos SUBSTITUTE("emul", p->p_emul->e_name, slen); 156 1.63 thorpej } else if (MATCH("kernel_ident")) { 157 1.115 christos slen = strlen(kernel_ident); 158 1.115 christos SUBSTITUTE("kernel_ident", kernel_ident, slen); 159 1.63 thorpej } else if (MATCH("domainname")) { 160 1.115 christos SUBSTITUTE("domainname", domainname, domainnamelen); 161 1.63 thorpej } else if (MATCH("ostype")) { 162 1.115 christos slen = strlen(ostype); 163 1.115 christos SUBSTITUTE("ostype", ostype, slen); 164 1.72 elad } else if (MATCH("uid")) { 165 1.115 christos slen = snprintf(idtmp, sizeof(idtmp), "%u", 166 1.72 elad kauth_cred_geteuid(kauth_cred_get())); 167 1.115 christos SUBSTITUTE("uid", idtmp, slen); 168 1.101 mjf } else if (MATCH("ruid")) { 169 1.115 christos slen = snprintf(idtmp, sizeof(idtmp), "%u", 170 1.101 mjf kauth_cred_getuid(kauth_cred_get())); 171 1.115 christos SUBSTITUTE("ruid", idtmp, slen); 172 1.115 christos } else if (MATCH("gid")) { 173 1.115 christos slen = snprintf(idtmp, sizeof(idtmp), "%u", 174 1.115 christos kauth_cred_getegid(kauth_cred_get())); 175 1.115 christos SUBSTITUTE("gid", idtmp, slen); 176 1.115 christos } else if (MATCH("rgid")) { 177 1.115 christos slen = snprintf(idtmp, sizeof(idtmp), "%u", 178 1.115 christos kauth_cred_getgid(kauth_cred_get())); 179 1.115 christos SUBSTITUTE("rgid", idtmp, slen); 180 1.63 thorpej } else { 181 1.63 thorpej tmp[newlen++] = '@'; 182 1.63 thorpej if (termchar == VC) 183 1.63 thorpej tmp[newlen++] = VO; 184 1.61 thorpej } 185 1.61 thorpej } 186 1.61 thorpej 187 1.66 yamt if (change) { 188 1.115 christos (void)memcpy(cp, tmp, newlen); 189 1.66 yamt *len = newlen; 190 1.66 yamt } 191 1.66 yamt PNBUF_PUT(tmp); 192 1.61 thorpej 193 1.115 christos return 0; 194 1.61 thorpej } 195 1.61 thorpej 196 1.63 thorpej #undef VNL 197 1.63 thorpej #undef VO 198 1.63 thorpej #undef VC 199 1.63 thorpej #undef MATCH 200 1.63 thorpej #undef SUBSTITUTE 201 1.63 thorpej 202 1.123 dholland //////////////////////////////////////////////////////////// 203 1.123 dholland 204 1.123 dholland /* 205 1.197 dholland * Determine the namei hash (for the namecache) for name. 206 1.131 dholland * If *ep != NULL, hash from name to ep-1. 207 1.131 dholland * If *ep == NULL, hash from name until the first NUL or '/', and 208 1.131 dholland * return the location of this termination character in *ep. 209 1.131 dholland * 210 1.131 dholland * This function returns an equivalent hash to the MI hash32_strn(). 211 1.131 dholland * The latter isn't used because in the *ep == NULL case, determining 212 1.131 dholland * the length of the string to the first NUL or `/' and then calling 213 1.131 dholland * hash32_strn() involves unnecessary double-handling of the data. 214 1.131 dholland */ 215 1.131 dholland uint32_t 216 1.131 dholland namei_hash(const char *name, const char **ep) 217 1.131 dholland { 218 1.131 dholland uint32_t hash; 219 1.131 dholland 220 1.131 dholland hash = HASH32_STR_INIT; 221 1.131 dholland if (*ep != NULL) { 222 1.131 dholland for (; name < *ep; name++) 223 1.131 dholland hash = hash * 33 + *(const uint8_t *)name; 224 1.131 dholland } else { 225 1.131 dholland for (; *name != '\0' && *name != '/'; name++) 226 1.131 dholland hash = hash * 33 + *(const uint8_t *)name; 227 1.131 dholland *ep = name; 228 1.131 dholland } 229 1.131 dholland return (hash + (hash >> 5)); 230 1.131 dholland } 231 1.131 dholland 232 1.131 dholland //////////////////////////////////////////////////////////// 233 1.131 dholland 234 1.131 dholland /* 235 1.123 dholland * Sealed abstraction for pathnames. 236 1.123 dholland * 237 1.123 dholland * System-call-layer level code that is going to call namei should 238 1.123 dholland * first create a pathbuf and adjust all the bells and whistles on it 239 1.176 dholland * as needed by context. 240 1.123 dholland */ 241 1.123 dholland 242 1.123 dholland struct pathbuf { 243 1.123 dholland char *pb_path; 244 1.123 dholland char *pb_pathcopy; 245 1.123 dholland unsigned pb_pathcopyuses; 246 1.123 dholland }; 247 1.123 dholland 248 1.123 dholland static struct pathbuf * 249 1.123 dholland pathbuf_create_raw(void) 250 1.123 dholland { 251 1.123 dholland struct pathbuf *pb; 252 1.123 dholland 253 1.123 dholland pb = kmem_alloc(sizeof(*pb), KM_SLEEP); 254 1.123 dholland pb->pb_path = PNBUF_GET(); 255 1.123 dholland if (pb->pb_path == NULL) { 256 1.123 dholland kmem_free(pb, sizeof(*pb)); 257 1.123 dholland return NULL; 258 1.123 dholland } 259 1.123 dholland pb->pb_pathcopy = NULL; 260 1.123 dholland pb->pb_pathcopyuses = 0; 261 1.123 dholland return pb; 262 1.123 dholland } 263 1.123 dholland 264 1.123 dholland void 265 1.123 dholland pathbuf_destroy(struct pathbuf *pb) 266 1.123 dholland { 267 1.236 riastrad 268 1.123 dholland KASSERT(pb->pb_pathcopyuses == 0); 269 1.123 dholland KASSERT(pb->pb_pathcopy == NULL); 270 1.123 dholland PNBUF_PUT(pb->pb_path); 271 1.123 dholland kmem_free(pb, sizeof(*pb)); 272 1.123 dholland } 273 1.123 dholland 274 1.123 dholland struct pathbuf * 275 1.124 dholland pathbuf_assimilate(char *pnbuf) 276 1.124 dholland { 277 1.124 dholland struct pathbuf *pb; 278 1.124 dholland 279 1.124 dholland pb = kmem_alloc(sizeof(*pb), KM_SLEEP); 280 1.124 dholland pb->pb_path = pnbuf; 281 1.124 dholland pb->pb_pathcopy = NULL; 282 1.124 dholland pb->pb_pathcopyuses = 0; 283 1.124 dholland return pb; 284 1.124 dholland } 285 1.124 dholland 286 1.124 dholland struct pathbuf * 287 1.123 dholland pathbuf_create(const char *path) 288 1.123 dholland { 289 1.123 dholland struct pathbuf *pb; 290 1.123 dholland int error; 291 1.123 dholland 292 1.123 dholland pb = pathbuf_create_raw(); 293 1.123 dholland if (pb == NULL) { 294 1.123 dholland return NULL; 295 1.123 dholland } 296 1.123 dholland error = copystr(path, pb->pb_path, PATH_MAX, NULL); 297 1.123 dholland if (error != 0) { 298 1.123 dholland KASSERT(!"kernel path too long in pathbuf_create"); 299 1.123 dholland /* make sure it's null-terminated, just in case */ 300 1.123 dholland pb->pb_path[PATH_MAX-1] = '\0'; 301 1.123 dholland } 302 1.123 dholland return pb; 303 1.123 dholland } 304 1.123 dholland 305 1.123 dholland int 306 1.123 dholland pathbuf_copyin(const char *userpath, struct pathbuf **ret) 307 1.123 dholland { 308 1.123 dholland struct pathbuf *pb; 309 1.123 dholland int error; 310 1.123 dholland 311 1.123 dholland pb = pathbuf_create_raw(); 312 1.123 dholland if (pb == NULL) { 313 1.238 riastrad return SET_ERROR(ENOMEM); 314 1.123 dholland } 315 1.123 dholland error = copyinstr(userpath, pb->pb_path, PATH_MAX, NULL); 316 1.123 dholland if (error) { 317 1.123 dholland pathbuf_destroy(pb); 318 1.123 dholland return error; 319 1.123 dholland } 320 1.123 dholland *ret = pb; 321 1.123 dholland return 0; 322 1.123 dholland } 323 1.123 dholland 324 1.123 dholland /* 325 1.173 dholland * XXX should not exist: 326 1.176 dholland * 1. whether a pointer is kernel or user should be statically checkable. 327 1.173 dholland * 2. copyin should be handled by the upper part of the syscall layer, 328 1.173 dholland * not in here. 329 1.123 dholland */ 330 1.123 dholland int 331 1.123 dholland pathbuf_maybe_copyin(const char *path, enum uio_seg seg, struct pathbuf **ret) 332 1.123 dholland { 333 1.236 riastrad 334 1.123 dholland if (seg == UIO_USERSPACE) { 335 1.123 dholland return pathbuf_copyin(path, ret); 336 1.123 dholland } else { 337 1.123 dholland *ret = pathbuf_create(path); 338 1.123 dholland if (*ret == NULL) { 339 1.238 riastrad return SET_ERROR(ENOMEM); 340 1.123 dholland } 341 1.123 dholland return 0; 342 1.123 dholland } 343 1.123 dholland } 344 1.123 dholland 345 1.123 dholland /* 346 1.123 dholland * Get a copy of the path buffer as it currently exists. If this is 347 1.123 dholland * called after namei starts the results may be arbitrary. 348 1.123 dholland */ 349 1.123 dholland void 350 1.123 dholland pathbuf_copystring(const struct pathbuf *pb, char *buf, size_t maxlen) 351 1.123 dholland { 352 1.236 riastrad 353 1.123 dholland strlcpy(buf, pb->pb_path, maxlen); 354 1.123 dholland } 355 1.123 dholland 356 1.123 dholland /* 357 1.123 dholland * These two functions allow access to a saved copy of the original 358 1.123 dholland * path string. The first copy should be gotten before namei is 359 1.123 dholland * called. Each copy that is gotten should be put back. 360 1.123 dholland */ 361 1.123 dholland 362 1.123 dholland const char * 363 1.123 dholland pathbuf_stringcopy_get(struct pathbuf *pb) 364 1.123 dholland { 365 1.236 riastrad 366 1.123 dholland if (pb->pb_pathcopyuses == 0) { 367 1.123 dholland pb->pb_pathcopy = PNBUF_GET(); 368 1.123 dholland strcpy(pb->pb_pathcopy, pb->pb_path); 369 1.123 dholland } 370 1.123 dholland pb->pb_pathcopyuses++; 371 1.123 dholland return pb->pb_pathcopy; 372 1.123 dholland } 373 1.123 dholland 374 1.123 dholland void 375 1.123 dholland pathbuf_stringcopy_put(struct pathbuf *pb, const char *str) 376 1.123 dholland { 377 1.236 riastrad 378 1.123 dholland KASSERT(str == pb->pb_pathcopy); 379 1.123 dholland KASSERT(pb->pb_pathcopyuses > 0); 380 1.123 dholland pb->pb_pathcopyuses--; 381 1.123 dholland if (pb->pb_pathcopyuses == 0) { 382 1.123 dholland PNBUF_PUT(pb->pb_pathcopy); 383 1.123 dholland pb->pb_pathcopy = NULL; 384 1.123 dholland } 385 1.123 dholland } 386 1.123 dholland 387 1.123 dholland 388 1.123 dholland //////////////////////////////////////////////////////////// 389 1.123 dholland 390 1.61 thorpej /* 391 1.173 dholland * namei: convert a pathname into a pointer to a (maybe-locked) vnode, 392 1.173 dholland * and maybe also its parent directory vnode, and assorted other guff. 393 1.173 dholland * See namei(9) for the interface documentation. 394 1.173 dholland * 395 1.10 cgd * 396 1.10 cgd * The FOLLOW flag is set when symbolic links are to be followed 397 1.10 cgd * when they occur at the end of the name translation process. 398 1.10 cgd * Symbolic links are always followed for all other pathname 399 1.10 cgd * components other than the last. 400 1.10 cgd * 401 1.10 cgd * The segflg defines whether the name is to be copied from user 402 1.10 cgd * space or kernel space. 403 1.10 cgd * 404 1.10 cgd * Overall outline of namei: 405 1.10 cgd * 406 1.10 cgd * copy in name 407 1.10 cgd * get starting directory 408 1.10 cgd * while (!done && !error) { 409 1.10 cgd * call lookup to search path. 410 1.10 cgd * if symbolic link, massage name in buffer and continue 411 1.10 cgd * } 412 1.10 cgd */ 413 1.117 dholland 414 1.117 dholland /* 415 1.173 dholland * Search a pathname. 416 1.173 dholland * This is a very central and rather complicated routine. 417 1.173 dholland * 418 1.173 dholland * The pathname is pointed to by ni_ptr and is of length ni_pathlen. 419 1.173 dholland * The starting directory is passed in. The pathname is descended 420 1.173 dholland * until done, or a symbolic link is encountered. The variable ni_more 421 1.173 dholland * is clear if the path is completed; it is set to one if a symbolic 422 1.173 dholland * link needing interpretation is encountered. 423 1.173 dholland * 424 1.173 dholland * The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on 425 1.173 dholland * whether the name is to be looked up, created, renamed, or deleted. 426 1.173 dholland * When CREATE, RENAME, or DELETE is specified, information usable in 427 1.173 dholland * creating, renaming, or deleting a directory entry may be calculated. 428 1.173 dholland * If flag has LOCKPARENT or'ed into it, the parent directory is returned 429 1.173 dholland * locked. Otherwise the parent directory is not returned. If the target 430 1.173 dholland * of the pathname exists and LOCKLEAF is or'ed into the flag the target 431 1.173 dholland * is returned locked, otherwise it is returned unlocked. When creating 432 1.173 dholland * or renaming and LOCKPARENT is specified, the target may not be ".". 433 1.173 dholland * When deleting and LOCKPARENT is specified, the target may be ".". 434 1.173 dholland * 435 1.173 dholland * Overall outline of lookup: 436 1.173 dholland * 437 1.173 dholland * dirloop: 438 1.173 dholland * identify next component of name at ndp->ni_ptr 439 1.173 dholland * handle degenerate case where name is null string 440 1.173 dholland * if .. and crossing mount points and on mounted filesys, find parent 441 1.173 dholland * call VOP_LOOKUP routine for next component name 442 1.173 dholland * directory vnode returned in ni_dvp, locked. 443 1.173 dholland * component vnode returned in ni_vp (if it exists), locked. 444 1.173 dholland * if result vnode is mounted on and crossing mount points, 445 1.173 dholland * find mounted on vnode 446 1.173 dholland * if more components of name, do next level at dirloop 447 1.173 dholland * return the answer in ni_vp, locked if LOCKLEAF set 448 1.173 dholland * if LOCKPARENT set, return locked parent in ni_dvp 449 1.173 dholland */ 450 1.173 dholland 451 1.173 dholland 452 1.173 dholland /* 453 1.117 dholland * Internal state for a namei operation. 454 1.173 dholland * 455 1.173 dholland * cnp is always equal to &ndp->ni_cnp. 456 1.117 dholland */ 457 1.117 dholland struct namei_state { 458 1.117 dholland struct nameidata *ndp; 459 1.117 dholland struct componentname *cnp; 460 1.117 dholland 461 1.118 dholland int docache; /* == 0 do not cache last component */ 462 1.118 dholland int rdonly; /* lookup read-only flag bit */ 463 1.118 dholland int slashes; 464 1.137 dholland 465 1.137 dholland unsigned attempt_retry:1; /* true if error allows emul retry */ 466 1.209 hannken unsigned root_referenced:1; /* true if ndp->ni_rootdir and 467 1.236 riastrad ndp->ni_erootdir were referenced */ 468 1.117 dholland }; 469 1.117 dholland 470 1.118 dholland 471 1.117 dholland /* 472 1.117 dholland * Initialize the namei working state. 473 1.117 dholland */ 474 1.117 dholland static void 475 1.117 dholland namei_init(struct namei_state *state, struct nameidata *ndp) 476 1.117 dholland { 477 1.202 riastrad 478 1.117 dholland state->ndp = ndp; 479 1.117 dholland state->cnp = &ndp->ni_cnd; 480 1.117 dholland 481 1.118 dholland state->docache = 0; 482 1.118 dholland state->rdonly = 0; 483 1.118 dholland state->slashes = 0; 484 1.133 dholland 485 1.209 hannken state->root_referenced = 0; 486 1.209 hannken 487 1.205 riastrad KASSERTMSG((state->cnp->cn_cred != NULL), "namei: bad cred/proc"); 488 1.205 riastrad KASSERTMSG(((state->cnp->cn_nameiop & (~OPMASK)) == 0), 489 1.205 riastrad "namei: nameiop contaminated with flags: %08"PRIx32, 490 1.205 riastrad state->cnp->cn_nameiop); 491 1.205 riastrad KASSERTMSG(((state->cnp->cn_flags & OPMASK) == 0), 492 1.205 riastrad "name: flags contaminated with nameiops: %08"PRIx32, 493 1.205 riastrad state->cnp->cn_flags); 494 1.133 dholland 495 1.133 dholland /* 496 1.133 dholland * The buffer for name translation shall be the one inside the 497 1.133 dholland * pathbuf. 498 1.133 dholland */ 499 1.133 dholland state->ndp->ni_pnbuf = state->ndp->ni_pathbuf->pb_path; 500 1.117 dholland } 501 1.117 dholland 502 1.117 dholland /* 503 1.117 dholland * Clean up the working namei state, leaving things ready for return 504 1.117 dholland * from namei. 505 1.117 dholland */ 506 1.117 dholland static void 507 1.117 dholland namei_cleanup(struct namei_state *state) 508 1.117 dholland { 509 1.236 riastrad 510 1.117 dholland KASSERT(state->cnp == &state->ndp->ni_cnd); 511 1.117 dholland 512 1.209 hannken if (state->root_referenced) { 513 1.212 hannken if (state->ndp->ni_rootdir != NULL) 514 1.212 hannken vrele(state->ndp->ni_rootdir); 515 1.209 hannken if (state->ndp->ni_erootdir != NULL) 516 1.209 hannken vrele(state->ndp->ni_erootdir); 517 1.209 hannken } 518 1.117 dholland } 519 1.117 dholland 520 1.117 dholland ////////////////////////////// 521 1.117 dholland 522 1.117 dholland /* 523 1.133 dholland * Get the directory context. 524 1.133 dholland * Initializes the rootdir and erootdir state and returns a reference 525 1.133 dholland * to the starting dir. 526 1.117 dholland */ 527 1.133 dholland static struct vnode * 528 1.196 dholland namei_getstartdir(struct namei_state *state) 529 1.117 dholland { 530 1.117 dholland struct nameidata *ndp = state->ndp; 531 1.117 dholland struct componentname *cnp = state->cnp; 532 1.117 dholland struct cwdinfo *cwdi; /* pointer to cwd state */ 533 1.218 ad struct lwp *self = curlwp; /* thread doing namei() */ 534 1.133 dholland struct vnode *rootdir, *erootdir, *curdir, *startdir; 535 1.117 dholland 536 1.210 hannken if (state->root_referenced) { 537 1.212 hannken if (state->ndp->ni_rootdir != NULL) 538 1.212 hannken vrele(state->ndp->ni_rootdir); 539 1.210 hannken if (state->ndp->ni_erootdir != NULL) 540 1.210 hannken vrele(state->ndp->ni_erootdir); 541 1.210 hannken state->root_referenced = 0; 542 1.210 hannken } 543 1.210 hannken 544 1.218 ad cwdi = self->l_proc->p_cwdi; 545 1.218 ad rw_enter(&cwdi->cwdi_lock, RW_READER); 546 1.21 kleink 547 1.133 dholland /* root dir */ 548 1.133 dholland if (cwdi->cwdi_rdir == NULL || (cnp->cn_flags & NOCHROOT)) { 549 1.133 dholland rootdir = rootvnode; 550 1.133 dholland } else { 551 1.133 dholland rootdir = cwdi->cwdi_rdir; 552 1.10 cgd } 553 1.123 dholland 554 1.133 dholland /* emulation root dir, if any */ 555 1.133 dholland if ((cnp->cn_flags & TRYEMULROOT) == 0) { 556 1.133 dholland /* if we don't want it, don't fetch it */ 557 1.133 dholland erootdir = NULL; 558 1.133 dholland } else if (cnp->cn_flags & EMULROOTSET) { 559 1.133 dholland /* explicitly set emulroot; "/../" doesn't override this */ 560 1.133 dholland erootdir = ndp->ni_erootdir; 561 1.133 dholland } else if (!strncmp(ndp->ni_pnbuf, "/../", 4)) { 562 1.133 dholland /* explicit reference to real rootdir */ 563 1.133 dholland erootdir = NULL; 564 1.133 dholland } else { 565 1.133 dholland /* may be null */ 566 1.133 dholland erootdir = cwdi->cwdi_edir; 567 1.133 dholland } 568 1.21 kleink 569 1.133 dholland /* current dir */ 570 1.196 dholland curdir = cwdi->cwdi_cdir; 571 1.85 dsl 572 1.133 dholland if (ndp->ni_pnbuf[0] != '/') { 573 1.198 dholland if (ndp->ni_atdir != NULL) { 574 1.198 dholland startdir = ndp->ni_atdir; 575 1.196 dholland } else { 576 1.196 dholland startdir = curdir; 577 1.196 dholland } 578 1.133 dholland erootdir = NULL; 579 1.133 dholland } else if (cnp->cn_flags & TRYEMULROOT && erootdir != NULL) { 580 1.133 dholland startdir = erootdir; 581 1.23 mycroft } else { 582 1.133 dholland startdir = rootdir; 583 1.133 dholland erootdir = NULL; 584 1.23 mycroft } 585 1.133 dholland 586 1.133 dholland state->ndp->ni_rootdir = rootdir; 587 1.133 dholland state->ndp->ni_erootdir = erootdir; 588 1.117 dholland 589 1.117 dholland /* 590 1.133 dholland * Get a reference to the start dir so we can safely unlock cwdi. 591 1.133 dholland * 592 1.209 hannken * Must hold references to rootdir and erootdir while we're running. 593 1.209 hannken * A multithreaded process may chroot during namei. 594 1.117 dholland */ 595 1.212 hannken if (startdir != NULL) 596 1.212 hannken vref(startdir); 597 1.212 hannken if (state->ndp->ni_rootdir != NULL) 598 1.212 hannken vref(state->ndp->ni_rootdir); 599 1.209 hannken if (state->ndp->ni_erootdir != NULL) 600 1.209 hannken vref(state->ndp->ni_erootdir); 601 1.209 hannken state->root_referenced = 1; 602 1.133 dholland 603 1.218 ad rw_exit(&cwdi->cwdi_lock); 604 1.133 dholland return startdir; 605 1.133 dholland } 606 1.133 dholland 607 1.133 dholland /* 608 1.133 dholland * Get the directory context for the nfsd case, in parallel to 609 1.133 dholland * getstartdir. Initializes the rootdir and erootdir state and 610 1.173 dholland * returns a reference to the passed-in starting dir. 611 1.133 dholland */ 612 1.133 dholland static struct vnode * 613 1.196 dholland namei_getstartdir_for_nfsd(struct namei_state *state) 614 1.133 dholland { 615 1.236 riastrad 616 1.198 dholland KASSERT(state->ndp->ni_atdir != NULL); 617 1.193 dholland 618 1.133 dholland /* always use the real root, and never set an emulation root */ 619 1.212 hannken if (rootvnode == NULL) { 620 1.212 hannken return NULL; 621 1.212 hannken } 622 1.133 dholland state->ndp->ni_rootdir = rootvnode; 623 1.133 dholland state->ndp->ni_erootdir = NULL; 624 1.133 dholland 625 1.198 dholland vref(state->ndp->ni_atdir); 626 1.209 hannken KASSERT(! state->root_referenced); 627 1.209 hannken vref(state->ndp->ni_rootdir); 628 1.209 hannken state->root_referenced = 1; 629 1.198 dholland return state->ndp->ni_atdir; 630 1.133 dholland } 631 1.133 dholland 632 1.133 dholland 633 1.133 dholland /* 634 1.133 dholland * Ktrace the namei operation. 635 1.133 dholland */ 636 1.133 dholland static void 637 1.133 dholland namei_ktrace(struct namei_state *state) 638 1.133 dholland { 639 1.133 dholland struct nameidata *ndp = state->ndp; 640 1.133 dholland struct componentname *cnp = state->cnp; 641 1.133 dholland struct lwp *self = curlwp; /* thread doing namei() */ 642 1.133 dholland const char *emul_path; 643 1.133 dholland 644 1.97 ad if (ktrpoint(KTR_NAMEI)) { 645 1.90 dsl if (ndp->ni_erootdir != NULL) { 646 1.89 dsl /* 647 1.89 dsl * To make any sense, the trace entry need to have the 648 1.89 dsl * text of the emulation path prepended. 649 1.89 dsl * Usually we can get this from the current process, 650 1.89 dsl * but when called from emul_find_interp() it is only 651 1.89 dsl * in the exec_package - so we get it passed in ni_next 652 1.89 dsl * (this is a hack). 653 1.89 dsl */ 654 1.88 dsl if (cnp->cn_flags & EMULROOTSET) 655 1.89 dsl emul_path = ndp->ni_next; 656 1.88 dsl else 657 1.117 dholland emul_path = self->l_proc->p_emul->e_path; 658 1.97 ad ktrnamei2(emul_path, strlen(emul_path), 659 1.124 dholland ndp->ni_pnbuf, ndp->ni_pathlen); 660 1.88 dsl } else 661 1.124 dholland ktrnamei(ndp->ni_pnbuf, ndp->ni_pathlen); 662 1.88 dsl } 663 1.133 dholland } 664 1.133 dholland 665 1.133 dholland /* 666 1.166 dholland * Start up namei. Find the root dir and cwd, establish the starting 667 1.166 dholland * directory for lookup, and lock it. Also calls ktrace when 668 1.133 dholland * appropriate. 669 1.133 dholland */ 670 1.133 dholland static int 671 1.196 dholland namei_start(struct namei_state *state, int isnfsd, 672 1.236 riastrad struct vnode **startdir_ret) 673 1.133 dholland { 674 1.133 dholland struct nameidata *ndp = state->ndp; 675 1.140 dholland struct vnode *startdir; 676 1.133 dholland 677 1.133 dholland /* length includes null terminator (was originally from copyinstr) */ 678 1.133 dholland ndp->ni_pathlen = strlen(ndp->ni_pnbuf) + 1; 679 1.133 dholland 680 1.133 dholland /* 681 1.133 dholland * POSIX.1 requirement: "" is not a valid file name. 682 1.133 dholland */ 683 1.133 dholland if (ndp->ni_pathlen == 1) { 684 1.211 maxv ndp->ni_erootdir = NULL; 685 1.238 riastrad return SET_ERROR(ENOENT); 686 1.133 dholland } 687 1.133 dholland 688 1.133 dholland ndp->ni_loopcnt = 0; 689 1.133 dholland 690 1.133 dholland /* Get starting directory, set up root, and ktrace. */ 691 1.193 dholland if (isnfsd) { 692 1.196 dholland startdir = namei_getstartdir_for_nfsd(state); 693 1.133 dholland /* no ktrace */ 694 1.133 dholland } else { 695 1.196 dholland startdir = namei_getstartdir(state); 696 1.133 dholland namei_ktrace(state); 697 1.133 dholland } 698 1.97 ad 699 1.212 hannken if (startdir == NULL) { 700 1.238 riastrad return SET_ERROR(ENOENT); 701 1.212 hannken } 702 1.212 hannken 703 1.200 manu /* NDAT may feed us with a non directory namei_getstartdir */ 704 1.208 dholland if (startdir->v_type != VDIR) { 705 1.208 dholland vrele(startdir); 706 1.238 riastrad return SET_ERROR(ENOTDIR); 707 1.208 dholland } 708 1.200 manu 709 1.140 dholland *startdir_ret = startdir; 710 1.117 dholland return 0; 711 1.117 dholland } 712 1.117 dholland 713 1.117 dholland /* 714 1.173 dholland * Check for being at a symlink that we're going to follow. 715 1.117 dholland */ 716 1.117 dholland static inline int 717 1.144 dholland namei_atsymlink(struct namei_state *state, struct vnode *foundobj) 718 1.117 dholland { 719 1.236 riastrad 720 1.144 dholland return (foundobj->v_type == VLNK) && 721 1.236 riastrad (state->cnp->cn_flags & (FOLLOW|REQUIREDIR)); 722 1.117 dholland } 723 1.117 dholland 724 1.117 dholland /* 725 1.117 dholland * Follow a symlink. 726 1.173 dholland * 727 1.173 dholland * Updates searchdir. inhibitmagic causes magic symlinks to not be 728 1.173 dholland * interpreted; this is used by nfsd. 729 1.174 jakllsch * 730 1.174 jakllsch * Unlocks foundobj on success (ugh) 731 1.117 dholland */ 732 1.117 dholland static inline int 733 1.141 dholland namei_follow(struct namei_state *state, int inhibitmagic, 734 1.236 riastrad struct vnode *searchdir, struct vnode *foundobj, 735 1.236 riastrad struct vnode **newsearchdir_ret) 736 1.117 dholland { 737 1.117 dholland struct nameidata *ndp = state->ndp; 738 1.117 dholland struct componentname *cnp = state->cnp; 739 1.117 dholland 740 1.117 dholland struct lwp *self = curlwp; /* thread doing namei() */ 741 1.117 dholland struct iovec aiov; /* uio for reading symbolic links */ 742 1.117 dholland struct uio auio; 743 1.117 dholland char *cp; /* pointer into pathname argument */ 744 1.117 dholland size_t linklen; 745 1.117 dholland int error; 746 1.117 dholland 747 1.117 dholland if (ndp->ni_loopcnt++ >= MAXSYMLINKS) { 748 1.238 riastrad return SET_ERROR(ELOOP); 749 1.117 dholland } 750 1.215 ad 751 1.215 ad vn_lock(foundobj, LK_EXCLUSIVE | LK_RETRY); 752 1.161 dholland if (foundobj->v_mount->mnt_flag & MNT_SYMPERM) { 753 1.161 dholland error = VOP_ACCESS(foundobj, VEXEC, cnp->cn_cred); 754 1.215 ad if (error != 0) { 755 1.215 ad VOP_UNLOCK(foundobj); 756 1.117 dholland return error; 757 1.215 ad } 758 1.117 dholland } 759 1.124 dholland 760 1.124 dholland /* FUTURE: fix this to not use a second buffer */ 761 1.124 dholland cp = PNBUF_GET(); 762 1.117 dholland aiov.iov_base = cp; 763 1.117 dholland aiov.iov_len = MAXPATHLEN; 764 1.117 dholland auio.uio_iov = &aiov; 765 1.117 dholland auio.uio_iovcnt = 1; 766 1.117 dholland auio.uio_offset = 0; 767 1.117 dholland auio.uio_rw = UIO_READ; 768 1.117 dholland auio.uio_resid = MAXPATHLEN; 769 1.117 dholland UIO_SETUP_SYSSPACE(&auio); 770 1.161 dholland error = VOP_READLINK(foundobj, &auio, cnp->cn_cred); 771 1.215 ad VOP_UNLOCK(foundobj); 772 1.117 dholland if (error) { 773 1.124 dholland PNBUF_PUT(cp); 774 1.117 dholland return error; 775 1.117 dholland } 776 1.117 dholland linklen = MAXPATHLEN - auio.uio_resid; 777 1.117 dholland if (linklen == 0) { 778 1.124 dholland PNBUF_PUT(cp); 779 1.238 riastrad return SET_ERROR(ENOENT); 780 1.117 dholland } 781 1.117 dholland 782 1.117 dholland /* 783 1.117 dholland * Do symlink substitution, if appropriate, and 784 1.117 dholland * check length for potential overflow. 785 1.134 dholland * 786 1.134 dholland * Inhibit symlink substitution for nfsd. 787 1.134 dholland * XXX: This is how it was before; is that a bug or a feature? 788 1.117 dholland */ 789 1.134 dholland if ((!inhibitmagic && vfs_magiclinks && 790 1.236 riastrad symlink_magic(self->l_proc, cp, &linklen)) || 791 1.117 dholland (linklen + ndp->ni_pathlen >= MAXPATHLEN)) { 792 1.124 dholland PNBUF_PUT(cp); 793 1.238 riastrad return SET_ERROR(ENAMETOOLONG); 794 1.117 dholland } 795 1.117 dholland if (ndp->ni_pathlen > 1) { 796 1.124 dholland /* includes a null-terminator */ 797 1.117 dholland memcpy(cp + linklen, ndp->ni_next, ndp->ni_pathlen); 798 1.124 dholland } else { 799 1.124 dholland cp[linklen] = '\0'; 800 1.124 dholland } 801 1.117 dholland ndp->ni_pathlen += linklen; 802 1.124 dholland memcpy(ndp->ni_pnbuf, cp, ndp->ni_pathlen); 803 1.124 dholland PNBUF_PUT(cp); 804 1.167 dholland 805 1.167 dholland /* we're now starting from the beginning of the buffer again */ 806 1.167 dholland cnp->cn_nameptr = ndp->ni_pnbuf; 807 1.117 dholland 808 1.117 dholland /* 809 1.117 dholland * Check if root directory should replace current directory. 810 1.117 dholland */ 811 1.124 dholland if (ndp->ni_pnbuf[0] == '/') { 812 1.215 ad vrele(searchdir); 813 1.117 dholland /* Keep absolute symbolic links inside emulation root */ 814 1.141 dholland searchdir = ndp->ni_erootdir; 815 1.141 dholland if (searchdir == NULL || 816 1.223 riastrad (ndp->ni_pnbuf[1] == '.' 817 1.236 riastrad && ndp->ni_pnbuf[2] == '.' 818 1.236 riastrad && ndp->ni_pnbuf[3] == '/')) { 819 1.117 dholland ndp->ni_erootdir = NULL; 820 1.141 dholland searchdir = ndp->ni_rootdir; 821 1.117 dholland } 822 1.141 dholland vref(searchdir); 823 1.186 dholland while (cnp->cn_nameptr[0] == '/') { 824 1.186 dholland cnp->cn_nameptr++; 825 1.186 dholland ndp->ni_pathlen--; 826 1.186 dholland } 827 1.117 dholland } 828 1.117 dholland 829 1.141 dholland *newsearchdir_ret = searchdir; 830 1.117 dholland return 0; 831 1.117 dholland } 832 1.117 dholland 833 1.117 dholland ////////////////////////////// 834 1.117 dholland 835 1.39 lukem /* 836 1.173 dholland * Inspect the leading path component and update the state accordingly. 837 1.10 cgd */ 838 1.118 dholland static int 839 1.227 dholland lookup_parsepath(struct namei_state *state, struct vnode *searchdir) 840 1.118 dholland { 841 1.118 dholland const char *cp; /* pointer into pathname argument */ 842 1.227 dholland int error; 843 1.118 dholland struct componentname *cnp = state->cnp; 844 1.118 dholland struct nameidata *ndp = state->ndp; 845 1.118 dholland 846 1.118 dholland KASSERT(cnp == &ndp->ni_cnd); 847 1.118 dholland 848 1.10 cgd /* 849 1.10 cgd * Search a new directory. 850 1.10 cgd * 851 1.10 cgd * The last component of the filename is left accessible via 852 1.12 mycroft * cnp->cn_nameptr for callers that need the name. Callers needing 853 1.10 cgd * the name set the SAVENAME flag. When done, they assume 854 1.10 cgd * responsibility for freeing the pathname buffer. 855 1.127 yamt * 856 1.147 dholland * At this point, our only vnode state is that the search dir 857 1.215 ad * is held. 858 1.10 cgd */ 859 1.228 dholland error = VOP_PARSEPATH(searchdir, cnp->cn_nameptr, &cnp->cn_namelen); 860 1.227 dholland if (error) { 861 1.227 dholland return error; 862 1.227 dholland } 863 1.197 dholland cp = cnp->cn_nameptr + cnp->cn_namelen; 864 1.191 christos if (cnp->cn_namelen > KERNEL_NAME_MAX) { 865 1.238 riastrad return SET_ERROR(ENAMETOOLONG); 866 1.10 cgd } 867 1.10 cgd #ifdef NAMEI_DIAGNOSTIC 868 1.10 cgd { char c = *cp; 869 1.236 riastrad *(char *)cp = '\0'; 870 1.236 riastrad printf("{%s}: ", cnp->cn_nameptr); 871 1.236 riastrad *(char *)cp = c; } 872 1.52 yamt #endif /* NAMEI_DIAGNOSTIC */ 873 1.12 mycroft ndp->ni_pathlen -= cnp->cn_namelen; 874 1.10 cgd ndp->ni_next = cp; 875 1.23 mycroft /* 876 1.23 mycroft * If this component is followed by a slash, then move the pointer to 877 1.23 mycroft * the next component forward, and remember that this component must be 878 1.23 mycroft * a directory. 879 1.23 mycroft */ 880 1.23 mycroft if (*cp == '/') { 881 1.23 mycroft do { 882 1.23 mycroft cp++; 883 1.23 mycroft } while (*cp == '/'); 884 1.118 dholland state->slashes = cp - ndp->ni_next; 885 1.118 dholland ndp->ni_pathlen -= state->slashes; 886 1.23 mycroft ndp->ni_next = cp; 887 1.23 mycroft cnp->cn_flags |= REQUIREDIR; 888 1.23 mycroft } else { 889 1.118 dholland state->slashes = 0; 890 1.23 mycroft cnp->cn_flags &= ~REQUIREDIR; 891 1.23 mycroft } 892 1.23 mycroft /* 893 1.23 mycroft * We do special processing on the last component, whether or not it's 894 1.23 mycroft * a directory. Cache all intervening lookups, but not the final one. 895 1.23 mycroft */ 896 1.23 mycroft if (*cp == '\0') { 897 1.118 dholland if (state->docache) 898 1.23 mycroft cnp->cn_flags |= MAKEENTRY; 899 1.23 mycroft else 900 1.23 mycroft cnp->cn_flags &= ~MAKEENTRY; 901 1.23 mycroft cnp->cn_flags |= ISLASTCN; 902 1.23 mycroft } else { 903 1.23 mycroft cnp->cn_flags |= MAKEENTRY; 904 1.23 mycroft cnp->cn_flags &= ~ISLASTCN; 905 1.23 mycroft } 906 1.12 mycroft if (cnp->cn_namelen == 2 && 907 1.12 mycroft cnp->cn_nameptr[1] == '.' && cnp->cn_nameptr[0] == '.') 908 1.12 mycroft cnp->cn_flags |= ISDOTDOT; 909 1.12 mycroft else 910 1.12 mycroft cnp->cn_flags &= ~ISDOTDOT; 911 1.10 cgd 912 1.118 dholland return 0; 913 1.118 dholland } 914 1.118 dholland 915 1.173 dholland /* 916 1.215 ad * Take care of crossing a mounted-on vnode. On error, foundobj_ret will be 917 1.215 ad * vrele'd, but searchdir is left alone. 918 1.215 ad */ 919 1.215 ad static int 920 1.215 ad lookup_crossmount(struct namei_state *state, 921 1.236 riastrad struct vnode **searchdir_ret, 922 1.236 riastrad struct vnode **foundobj_ret, 923 1.236 riastrad bool *searchdir_locked) 924 1.215 ad { 925 1.215 ad struct componentname *cnp = state->cnp; 926 1.221 ad struct vnode *foundobj, *vp; 927 1.215 ad struct vnode *searchdir; 928 1.215 ad struct mount *mp; 929 1.215 ad int error, lktype; 930 1.215 ad 931 1.215 ad searchdir = *searchdir_ret; 932 1.215 ad foundobj = *foundobj_ret; 933 1.215 ad error = 0; 934 1.215 ad 935 1.215 ad KASSERT((cnp->cn_flags & NOCROSSMOUNT) == 0); 936 1.215 ad 937 1.215 ad /* First, unlock searchdir (oof). */ 938 1.215 ad if (*searchdir_locked) { 939 1.222 ad KASSERT(searchdir != NULL); 940 1.215 ad lktype = VOP_ISLOCKED(searchdir); 941 1.215 ad VOP_UNLOCK(searchdir); 942 1.215 ad *searchdir_locked = false; 943 1.215 ad } else { 944 1.215 ad lktype = LK_NONE; 945 1.215 ad } 946 1.215 ad 947 1.215 ad /* 948 1.215 ad * Do an unlocked check to see if the vnode has been mounted on; if 949 1.215 ad * so find the root of the mounted file system. 950 1.215 ad */ 951 1.215 ad while (foundobj->v_type == VDIR && 952 1.215 ad (mp = foundobj->v_mountedhere) != NULL && 953 1.215 ad (cnp->cn_flags & NOCROSSMOUNT) == 0) { 954 1.215 ad /* 955 1.221 ad * Try the namecache first. If that doesn't work, do 956 1.221 ad * it the hard way. 957 1.215 ad */ 958 1.221 ad if (cache_lookup_mount(foundobj, &vp)) { 959 1.215 ad vrele(foundobj); 960 1.221 ad foundobj = vp; 961 1.221 ad } else { 962 1.232 hannken /* First get the vnodes mount stable. */ 963 1.232 hannken while ((mp = foundobj->v_mountedhere) != NULL) { 964 1.232 hannken fstrans_start(mp); 965 1.232 hannken if (fstrans_held(mp) && 966 1.232 hannken mp == foundobj->v_mountedhere) { 967 1.232 hannken break; 968 1.232 hannken } 969 1.232 hannken fstrans_done(mp); 970 1.221 ad } 971 1.232 hannken if (mp == NULL) { 972 1.221 ad break; 973 1.221 ad } 974 1.221 ad 975 1.221 ad /* 976 1.221 ad * Now get a reference on the root vnode. 977 1.221 ad * XXX Future - maybe allow only VDIR here. 978 1.221 ad */ 979 1.221 ad error = VFS_ROOT(mp, LK_NONE, &vp); 980 1.215 ad 981 1.221 ad /* 982 1.221 ad * If successful, enter it into the cache while 983 1.221 ad * holding the mount busy (competing with unmount). 984 1.221 ad */ 985 1.221 ad if (error == 0) { 986 1.221 ad cache_enter_mount(foundobj, vp); 987 1.221 ad } 988 1.215 ad 989 1.236 riastrad /* 990 1.236 riastrad * Finally, drop references to foundobj & mountpoint. 991 1.236 riastrad */ 992 1.221 ad vrele(foundobj); 993 1.232 hannken fstrans_done(mp); 994 1.221 ad if (error) { 995 1.221 ad foundobj = NULL; 996 1.221 ad break; 997 1.221 ad } 998 1.221 ad foundobj = vp; 999 1.215 ad } 1000 1.215 ad 1001 1.215 ad /* 1002 1.215 ad * Avoid locking vnodes from two filesystems because 1003 1.215 ad * it's prone to deadlock, e.g. when using puffs. 1004 1.215 ad * Also, it isn't a good idea to propagate slowness of 1005 1.215 ad * a filesystem up to the root directory. For now, 1006 1.215 ad * only handle the common case, where foundobj is 1007 1.215 ad * VDIR. 1008 1.215 ad * 1009 1.215 ad * In this case set searchdir to null to avoid using 1010 1.215 ad * it again. It is not correct to set searchdir == 1011 1.215 ad * foundobj here as that will confuse the caller. 1012 1.215 ad * (See PR 40740.) 1013 1.215 ad */ 1014 1.215 ad if (searchdir == NULL) { 1015 1.215 ad /* already been here once; do nothing further */ 1016 1.215 ad } else if (foundobj->v_type == VDIR) { 1017 1.215 ad vrele(searchdir); 1018 1.215 ad *searchdir_ret = searchdir = NULL; 1019 1.215 ad lktype = LK_NONE; 1020 1.215 ad } 1021 1.215 ad } 1022 1.215 ad 1023 1.215 ad /* If searchdir is still around, re-lock it. */ 1024 1.237 riastrad if (error == 0 && lktype != LK_NONE) { 1025 1.215 ad vn_lock(searchdir, lktype | LK_RETRY); 1026 1.215 ad *searchdir_locked = true; 1027 1.215 ad } 1028 1.216 ad *foundobj_ret = foundobj; 1029 1.215 ad return error; 1030 1.215 ad } 1031 1.215 ad 1032 1.215 ad /* 1033 1.225 chs * Determine the desired locking mode for the directory of a lookup. 1034 1.225 chs */ 1035 1.225 chs static int 1036 1.225 chs lookup_lktype(struct vnode *searchdir, struct componentname *cnp) 1037 1.225 chs { 1038 1.225 chs 1039 1.225 chs /* 1040 1.225 chs * If the file system supports VOP_LOOKUP() with a shared lock, and 1041 1.225 chs * we are not making any modifications (nameiop LOOKUP) or this is 1042 1.225 chs * not the last component then get a shared lock. Where we can't do 1043 1.225 chs * fast-forwarded lookups (for example with layered file systems) 1044 1.225 chs * then this is the fallback for reducing lock contention. 1045 1.225 chs */ 1046 1.225 chs if ((searchdir->v_mount->mnt_iflag & IMNT_SHRLOOKUP) != 0 && 1047 1.225 chs (cnp->cn_nameiop == LOOKUP || (cnp->cn_flags & ISLASTCN) == 0)) { 1048 1.225 chs return LK_SHARED; 1049 1.225 chs } else { 1050 1.225 chs return LK_EXCLUSIVE; 1051 1.225 chs } 1052 1.225 chs } 1053 1.225 chs 1054 1.225 chs /* 1055 1.173 dholland * Call VOP_LOOKUP for a single lookup; return a new search directory 1056 1.223 riastrad * (used when crossing mountpoints up or searching union mounts down) and 1057 1.173 dholland * the found object, which for create operations may be NULL on success. 1058 1.204 dholland * 1059 1.204 dholland * Note that the new search directory may be null, which means the 1060 1.204 dholland * searchdir was unlocked and released. This happens in the common case 1061 1.204 dholland * when crossing a mount point downwards, in order to avoid coupling 1062 1.204 dholland * locks between different file system volumes. Importantly, this can 1063 1.204 dholland * happen even if the call fails. (XXX: this is gross and should be 1064 1.204 dholland * tidied somehow.) 1065 1.173 dholland */ 1066 1.118 dholland static int 1067 1.147 dholland lookup_once(struct namei_state *state, 1068 1.236 riastrad struct vnode *searchdir, 1069 1.236 riastrad struct vnode **newsearchdir_ret, 1070 1.236 riastrad struct vnode **foundobj_ret, 1071 1.236 riastrad bool *newsearchdir_locked_ret) 1072 1.118 dholland { 1073 1.163 dholland struct vnode *tmpvn; /* scratch vnode */ 1074 1.163 dholland struct vnode *foundobj; /* result */ 1075 1.118 dholland struct lwp *l = curlwp; 1076 1.215 ad bool searchdir_locked = false; 1077 1.215 ad int error, lktype; 1078 1.118 dholland 1079 1.118 dholland struct componentname *cnp = state->cnp; 1080 1.118 dholland struct nameidata *ndp = state->ndp; 1081 1.118 dholland 1082 1.118 dholland KASSERT(cnp == &ndp->ni_cnd); 1083 1.154 dholland *newsearchdir_ret = searchdir; 1084 1.118 dholland 1085 1.10 cgd /* 1086 1.10 cgd * Handle "..": two special cases. 1087 1.10 cgd * 1. If at root directory (e.g. after chroot) 1088 1.12 mycroft * or at absolute root directory 1089 1.10 cgd * then ignore it so can't get out. 1090 1.85 dsl * 1a. If at the root of the emulation filesystem go to the real 1091 1.85 dsl * root. So "/../<path>" is always absolute. 1092 1.85 dsl * 1b. If we have somehow gotten out of a jail, warn 1093 1.40 wrstuden * and also ignore it so we can't get farther out. 1094 1.10 cgd * 2. If this vnode is the root of a mounted 1095 1.10 cgd * filesystem, then replace it with the 1096 1.10 cgd * vnode which was mounted on so we take the 1097 1.10 cgd * .. in the other file system. 1098 1.10 cgd */ 1099 1.12 mycroft if (cnp->cn_flags & ISDOTDOT) { 1100 1.64 christos struct proc *p = l->l_proc; 1101 1.64 christos 1102 1.10 cgd for (;;) { 1103 1.154 dholland if (searchdir == ndp->ni_rootdir || 1104 1.154 dholland searchdir == rootvnode) { 1105 1.147 dholland foundobj = searchdir; 1106 1.147 dholland vref(foundobj); 1107 1.147 dholland *foundobj_ret = foundobj; 1108 1.225 chs if (cnp->cn_flags & LOCKPARENT) { 1109 1.225 chs lktype = lookup_lktype(searchdir, cnp); 1110 1.225 chs vn_lock(searchdir, lktype | LK_RETRY); 1111 1.225 chs searchdir_locked = true; 1112 1.225 chs } 1113 1.175 yamt error = 0; 1114 1.175 yamt goto done; 1115 1.40 wrstuden } 1116 1.40 wrstuden if (ndp->ni_rootdir != rootvnode) { 1117 1.40 wrstuden int retval; 1118 1.73 chs 1119 1.236 riastrad retval = vn_isunder(searchdir, ndp->ni_rootdir, 1120 1.236 riastrad l); 1121 1.40 wrstuden if (!retval) { 1122 1.236 riastrad /* Oops! We got out of jail! */ 1123 1.236 riastrad log(LOG_WARNING, 1124 1.236 riastrad "chrooted pid %d uid %d (%s) " 1125 1.236 riastrad "detected outside of its chroot\n", 1126 1.236 riastrad p->p_pid, 1127 1.236 riastrad kauth_cred_geteuid(l->l_cred), 1128 1.236 riastrad p->p_comm); 1129 1.236 riastrad /* Put us at the jail root. */ 1130 1.236 riastrad vrele(searchdir); 1131 1.236 riastrad searchdir = NULL; 1132 1.236 riastrad foundobj = ndp->ni_rootdir; 1133 1.236 riastrad vref(foundobj); 1134 1.236 riastrad vref(foundobj); 1135 1.236 riastrad *newsearchdir_ret = foundobj; 1136 1.236 riastrad *foundobj_ret = foundobj; 1137 1.236 riastrad error = 0; 1138 1.236 riastrad goto done; 1139 1.40 wrstuden } 1140 1.10 cgd } 1141 1.147 dholland if ((searchdir->v_vflag & VV_ROOT) == 0 || 1142 1.12 mycroft (cnp->cn_flags & NOCROSSMOUNT)) 1143 1.10 cgd break; 1144 1.163 dholland tmpvn = searchdir; 1145 1.147 dholland searchdir = searchdir->v_mount->mnt_vnodecovered; 1146 1.153 dholland vref(searchdir); 1147 1.215 ad vrele(tmpvn); 1148 1.154 dholland *newsearchdir_ret = searchdir; 1149 1.10 cgd } 1150 1.10 cgd } 1151 1.10 cgd 1152 1.225 chs lktype = lookup_lktype(searchdir, cnp); 1153 1.215 ad 1154 1.215 ad /* 1155 1.10 cgd * We now have a segment name to search for, and a directory to search. 1156 1.215 ad * Our vnode state here is that "searchdir" is held. 1157 1.10 cgd */ 1158 1.12 mycroft unionlookup: 1159 1.148 dholland foundobj = NULL; 1160 1.215 ad if (!searchdir_locked) { 1161 1.215 ad vn_lock(searchdir, lktype | LK_RETRY); 1162 1.215 ad searchdir_locked = true; 1163 1.215 ad } 1164 1.148 dholland error = VOP_LOOKUP(searchdir, &foundobj, cnp); 1165 1.154 dholland 1166 1.73 chs if (error != 0) { 1167 1.205 riastrad KASSERTMSG((foundobj == NULL), 1168 1.205 riastrad "leaf `%s' should be empty but is %p", 1169 1.205 riastrad cnp->cn_nameptr, foundobj); 1170 1.10 cgd #ifdef NAMEI_DIAGNOSTIC 1171 1.19 christos printf("not found\n"); 1172 1.52 yamt #endif /* NAMEI_DIAGNOSTIC */ 1173 1.215 ad 1174 1.215 ad /* 1175 1.215 ad * If ENOLCK, the file system needs us to retry the lookup 1176 1.215 ad * with an exclusive lock. It's likely nothing was found in 1177 1.215 ad * cache and/or modifications need to be made. 1178 1.215 ad */ 1179 1.215 ad if (error == ENOLCK) { 1180 1.215 ad KASSERT(VOP_ISLOCKED(searchdir) == LK_SHARED); 1181 1.215 ad KASSERT(searchdir_locked); 1182 1.215 ad if (vn_lock(searchdir, LK_UPGRADE | LK_NOWAIT)) { 1183 1.215 ad VOP_UNLOCK(searchdir); 1184 1.215 ad searchdir_locked = false; 1185 1.215 ad } 1186 1.215 ad lktype = LK_EXCLUSIVE; 1187 1.215 ad goto unionlookup; 1188 1.215 ad } 1189 1.215 ad 1190 1.12 mycroft if ((error == ENOENT) && 1191 1.147 dholland (searchdir->v_vflag & VV_ROOT) && 1192 1.147 dholland (searchdir->v_mount->mnt_flag & MNT_UNION)) { 1193 1.163 dholland tmpvn = searchdir; 1194 1.147 dholland searchdir = searchdir->v_mount->mnt_vnodecovered; 1195 1.153 dholland vref(searchdir); 1196 1.163 dholland vput(tmpvn); 1197 1.215 ad searchdir_locked = false; 1198 1.154 dholland *newsearchdir_ret = searchdir; 1199 1.12 mycroft goto unionlookup; 1200 1.10 cgd } 1201 1.12 mycroft 1202 1.10 cgd if (error != EJUSTRETURN) 1203 1.175 yamt goto done; 1204 1.73 chs 1205 1.10 cgd /* 1206 1.23 mycroft * If this was not the last component, or there were trailing 1207 1.51 christos * slashes, and we are not going to create a directory, 1208 1.51 christos * then the name must exist. 1209 1.23 mycroft */ 1210 1.51 christos if ((cnp->cn_flags & (REQUIREDIR | CREATEDIR)) == REQUIREDIR) { 1211 1.238 riastrad error = SET_ERROR(ENOENT); 1212 1.175 yamt goto done; 1213 1.23 mycroft } 1214 1.73 chs 1215 1.23 mycroft /* 1216 1.10 cgd * If creating and at end of pathname, then can consider 1217 1.10 cgd * allowing file to be created. 1218 1.10 cgd */ 1219 1.118 dholland if (state->rdonly) { 1220 1.238 riastrad error = SET_ERROR(EROFS); 1221 1.175 yamt goto done; 1222 1.10 cgd } 1223 1.73 chs 1224 1.10 cgd /* 1225 1.166 dholland * We return success and a NULL foundobj to indicate 1226 1.166 dholland * that the entry doesn't currently exist, leaving a 1227 1.173 dholland * pointer to the (normally, locked) directory vnode 1228 1.173 dholland * as searchdir. 1229 1.10 cgd */ 1230 1.147 dholland *foundobj_ret = NULL; 1231 1.175 yamt error = 0; 1232 1.175 yamt goto done; 1233 1.10 cgd } 1234 1.10 cgd #ifdef NAMEI_DIAGNOSTIC 1235 1.19 christos printf("found\n"); 1236 1.52 yamt #endif /* NAMEI_DIAGNOSTIC */ 1237 1.10 cgd 1238 1.215 ad /* Unlock, unless the caller needs the parent locked. */ 1239 1.215 ad if (searchdir != NULL) { 1240 1.215 ad KASSERT(searchdir_locked); 1241 1.215 ad if ((cnp->cn_flags & (ISLASTCN | LOCKPARENT)) != 1242 1.215 ad (ISLASTCN | LOCKPARENT)) { 1243 1.237 riastrad VOP_UNLOCK(searchdir); 1244 1.237 riastrad searchdir_locked = false; 1245 1.201 hannken } 1246 1.215 ad } else { 1247 1.215 ad KASSERT(!searchdir_locked); 1248 1.201 hannken } 1249 1.73 chs 1250 1.215 ad *foundobj_ret = foundobj; 1251 1.215 ad error = 0; 1252 1.215 ad done: 1253 1.215 ad *newsearchdir_locked_ret = searchdir_locked; 1254 1.215 ad return error; 1255 1.215 ad } 1256 1.215 ad 1257 1.215 ad /* 1258 1.223 riastrad * Parse out the first path name component that we need to to consider. 1259 1.215 ad * 1260 1.215 ad * While doing this, attempt to use the name cache to fast-forward through 1261 1.215 ad * as many "easy" to find components of the path as possible. 1262 1.215 ad * 1263 1.215 ad * We use the namecache's node locks to form a chain, and avoid as many 1264 1.215 ad * vnode references and locks as possible. In the ideal case, only the 1265 1.215 ad * final vnode will have its reference count adjusted and lock taken. 1266 1.215 ad */ 1267 1.215 ad static int 1268 1.215 ad lookup_fastforward(struct namei_state *state, struct vnode **searchdir_ret, 1269 1.236 riastrad struct vnode **foundobj_ret) 1270 1.215 ad { 1271 1.215 ad struct componentname *cnp = state->cnp; 1272 1.215 ad struct nameidata *ndp = state->ndp; 1273 1.215 ad krwlock_t *plock; 1274 1.215 ad struct vnode *foundobj, *searchdir; 1275 1.215 ad int error, error2; 1276 1.215 ad size_t oldpathlen; 1277 1.215 ad const char *oldnameptr; 1278 1.221 ad bool terminal; 1279 1.215 ad 1280 1.10 cgd /* 1281 1.215 ad * Eat as many path name components as possible before giving up and 1282 1.215 ad * letting lookup_once() handle it. Remember the starting point in 1283 1.215 ad * case we can't get vnode references and need to roll back. 1284 1.215 ad */ 1285 1.215 ad plock = NULL; 1286 1.215 ad searchdir = *searchdir_ret; 1287 1.215 ad oldnameptr = cnp->cn_nameptr; 1288 1.215 ad oldpathlen = ndp->ni_pathlen; 1289 1.221 ad terminal = false; 1290 1.215 ad for (;;) { 1291 1.215 ad foundobj = NULL; 1292 1.215 ad 1293 1.215 ad /* 1294 1.215 ad * Get the next component name. There should be no slashes 1295 1.215 ad * here, and we shouldn't have looped around if we were 1296 1.215 ad * done. 1297 1.215 ad */ 1298 1.215 ad KASSERT(cnp->cn_nameptr[0] != '/'); 1299 1.215 ad KASSERT(cnp->cn_nameptr[0] != '\0'); 1300 1.227 dholland if ((error = lookup_parsepath(state, searchdir)) != 0) { 1301 1.215 ad break; 1302 1.215 ad } 1303 1.215 ad 1304 1.215 ad /* 1305 1.219 ad * Can't deal with DOTDOT lookups if NOCROSSMOUNT or the 1306 1.219 ad * lookup is chrooted. 1307 1.215 ad */ 1308 1.219 ad if ((cnp->cn_flags & ISDOTDOT) != 0) { 1309 1.219 ad if ((searchdir->v_vflag & VV_ROOT) != 0 && 1310 1.219 ad (cnp->cn_flags & NOCROSSMOUNT)) { 1311 1.238 riastrad error = SET_ERROR(EOPNOTSUPP); 1312 1.219 ad break; 1313 1.219 ad } 1314 1.219 ad if (ndp->ni_rootdir != rootvnode) { 1315 1.238 riastrad error = SET_ERROR(EOPNOTSUPP); 1316 1.219 ad break; 1317 1.219 ad } 1318 1.215 ad } 1319 1.215 ad 1320 1.215 ad /* 1321 1.215 ad * Can't deal with last component when modifying; this needs 1322 1.215 ad * searchdir locked and VOP_LOOKUP() called (which can and 1323 1.221 ad * does modify state, despite the name). NB: this case means 1324 1.221 ad * terminal is never set true when LOCKPARENT. 1325 1.215 ad */ 1326 1.215 ad if ((cnp->cn_flags & ISLASTCN) != 0) { 1327 1.215 ad if (cnp->cn_nameiop != LOOKUP || 1328 1.215 ad (cnp->cn_flags & LOCKPARENT) != 0) { 1329 1.238 riastrad error = SET_ERROR(EOPNOTSUPP); 1330 1.215 ad break; 1331 1.215 ad } 1332 1.215 ad } 1333 1.204 dholland 1334 1.215 ad /* 1335 1.215 ad * Good, now look for it in cache. cache_lookup_linked() 1336 1.215 ad * will fail if there's nothing there, or if there's no 1337 1.215 ad * ownership info for the directory, or if the user doesn't 1338 1.215 ad * have permission to look up files in this directory. 1339 1.215 ad */ 1340 1.215 ad if (!cache_lookup_linked(searchdir, cnp->cn_nameptr, 1341 1.236 riastrad cnp->cn_namelen, &foundobj, &plock, cnp->cn_cred)) { 1342 1.238 riastrad error = SET_ERROR(EOPNOTSUPP); 1343 1.215 ad break; 1344 1.107 ad } 1345 1.233 riastrad KASSERT(plock != NULL); 1346 1.233 riastrad KASSERT(rw_lock_held(plock)); 1347 1.215 ad 1348 1.219 ad /* 1349 1.219 ad * Scored a hit. Negative is good too (ENOENT). If there's 1350 1.219 ad * a '-o union' mount here, punt and let lookup_once() deal 1351 1.219 ad * with it. 1352 1.219 ad */ 1353 1.215 ad if (foundobj == NULL) { 1354 1.219 ad if ((searchdir->v_vflag & VV_ROOT) != 0 && 1355 1.219 ad (searchdir->v_mount->mnt_flag & MNT_UNION) != 0) { 1356 1.238 riastrad error = SET_ERROR(EOPNOTSUPP); 1357 1.219 ad } else { 1358 1.238 riastrad error = SET_ERROR(ENOENT); 1359 1.221 ad terminal = ((cnp->cn_flags & ISLASTCN) != 0); 1360 1.221 ad } 1361 1.221 ad break; 1362 1.221 ad } 1363 1.221 ad 1364 1.221 ad /* 1365 1.221 ad * Stop and get a hold on the vnode if we've encountered 1366 1.239 andvar * something other than a directory. 1367 1.221 ad */ 1368 1.221 ad if (foundobj->v_type != VDIR) { 1369 1.221 ad error = vcache_tryvget(foundobj); 1370 1.221 ad if (error != 0) { 1371 1.221 ad foundobj = NULL; 1372 1.238 riastrad error = SET_ERROR(EOPNOTSUPP); 1373 1.224 ad } else { 1374 1.224 ad terminal = (foundobj->v_type != VLNK && 1375 1.224 ad (cnp->cn_flags & ISLASTCN) != 0); 1376 1.219 ad } 1377 1.215 ad break; 1378 1.190 yamt } 1379 1.215 ad 1380 1.215 ad /* 1381 1.221 ad * Try to cross mountpoints, bearing in mind that they can 1382 1.221 ad * be stacked. If at any point we can't go further, stop 1383 1.221 ad * and try to get a reference on the vnode. If we are able 1384 1.221 ad * to get a ref then lookup_crossmount() will take care of 1385 1.221 ad * it, otherwise we'll fall through to lookup_once(). 1386 1.221 ad */ 1387 1.221 ad if (foundobj->v_mountedhere != NULL) { 1388 1.221 ad while (foundobj->v_mountedhere != NULL && 1389 1.221 ad (cnp->cn_flags & NOCROSSMOUNT) == 0 && 1390 1.221 ad cache_cross_mount(&foundobj, &plock)) { 1391 1.221 ad KASSERT(foundobj != NULL); 1392 1.221 ad KASSERT(foundobj->v_type == VDIR); 1393 1.221 ad } 1394 1.221 ad if (foundobj->v_mountedhere != NULL) { 1395 1.221 ad error = vcache_tryvget(foundobj); 1396 1.221 ad if (error != 0) { 1397 1.221 ad foundobj = NULL; 1398 1.238 riastrad error = SET_ERROR(EOPNOTSUPP); 1399 1.221 ad } 1400 1.221 ad break; 1401 1.221 ad } else { 1402 1.221 ad searchdir = NULL; 1403 1.221 ad } 1404 1.221 ad } 1405 1.221 ad 1406 1.221 ad /* 1407 1.221 ad * Time to stop if we found the last component & traversed 1408 1.221 ad * all mounts. 1409 1.221 ad */ 1410 1.221 ad if ((cnp->cn_flags & ISLASTCN) != 0) { 1411 1.215 ad error = vcache_tryvget(foundobj); 1412 1.215 ad if (error != 0) { 1413 1.215 ad foundobj = NULL; 1414 1.238 riastrad error = SET_ERROR(EOPNOTSUPP); 1415 1.221 ad } else { 1416 1.221 ad terminal = (foundobj->v_type != VLNK); 1417 1.204 dholland } 1418 1.215 ad break; 1419 1.32 wrstuden } 1420 1.215 ad 1421 1.190 yamt /* 1422 1.215 ad * Otherwise, we're still in business. Set the found VDIR 1423 1.215 ad * vnode as the search dir for the next component and 1424 1.215 ad * continue on to it. 1425 1.190 yamt */ 1426 1.215 ad cnp->cn_nameptr = ndp->ni_next; 1427 1.215 ad searchdir = foundobj; 1428 1.215 ad } 1429 1.215 ad 1430 1.221 ad if (terminal) { 1431 1.221 ad /* 1432 1.221 ad * If we exited the loop above having successfully located 1433 1.221 ad * the last component with a zero error code, and it's not a 1434 1.223 riastrad * symbolic link, then the parent directory is not needed. 1435 1.221 ad * Release reference to the starting parent and make the 1436 1.221 ad * terminal parent disappear into thin air. 1437 1.221 ad */ 1438 1.221 ad KASSERT(plock != NULL); 1439 1.221 ad rw_exit(plock); 1440 1.221 ad vrele(*searchdir_ret); 1441 1.221 ad *searchdir_ret = NULL; 1442 1.221 ad } else if (searchdir != *searchdir_ret) { 1443 1.221 ad /* 1444 1.221 ad * Otherwise we need to return the parent. If we ended up 1445 1.221 ad * with a new search dir, ref it before dropping the 1446 1.221 ad * namecache's lock. The lock prevents both searchdir and 1447 1.221 ad * foundobj from disappearing. If we can't ref the new 1448 1.221 ad * searchdir, we have a bit of a problem. Roll back the 1449 1.221 ad * fastforward to the beginning and let lookup_once() take 1450 1.221 ad * care of it. 1451 1.221 ad */ 1452 1.224 ad if (searchdir == NULL) { 1453 1.224 ad /* 1454 1.224 ad * It's possible for searchdir to be NULL in the 1455 1.224 ad * case of a root vnode being reclaimed while 1456 1.224 ad * trying to cross a mount. 1457 1.224 ad */ 1458 1.238 riastrad error2 = SET_ERROR(EOPNOTSUPP); 1459 1.224 ad } else { 1460 1.224 ad error2 = vcache_tryvget(searchdir); 1461 1.224 ad } 1462 1.215 ad KASSERT(plock != NULL); 1463 1.215 ad rw_exit(plock); 1464 1.215 ad if (__predict_true(error2 == 0)) { 1465 1.215 ad /* Returning new searchdir, and maybe new foundobj. */ 1466 1.215 ad vrele(*searchdir_ret); 1467 1.215 ad *searchdir_ret = searchdir; 1468 1.190 yamt } else { 1469 1.215 ad /* Returning nothing. */ 1470 1.215 ad if (foundobj != NULL) { 1471 1.215 ad vrele(foundobj); 1472 1.215 ad foundobj = NULL; 1473 1.215 ad } 1474 1.215 ad cnp->cn_nameptr = oldnameptr; 1475 1.215 ad ndp->ni_pathlen = oldpathlen; 1476 1.230 hannken error = lookup_parsepath(state, *searchdir_ret); 1477 1.230 hannken if (error == 0) { 1478 1.238 riastrad error = SET_ERROR(EOPNOTSUPP); 1479 1.215 ad } 1480 1.190 yamt } 1481 1.215 ad } else if (plock != NULL) { 1482 1.215 ad /* Drop any namecache lock still held. */ 1483 1.215 ad rw_exit(plock); 1484 1.14 mycroft } 1485 1.14 mycroft 1486 1.215 ad KASSERT(error == 0 ? foundobj != NULL : foundobj == NULL); 1487 1.147 dholland *foundobj_ret = foundobj; 1488 1.175 yamt return error; 1489 1.118 dholland } 1490 1.118 dholland 1491 1.131 dholland ////////////////////////////// 1492 1.131 dholland 1493 1.173 dholland /* 1494 1.173 dholland * Do a complete path search from a single root directory. 1495 1.173 dholland * (This is called up to twice if TRYEMULROOT is in effect.) 1496 1.173 dholland */ 1497 1.131 dholland static int 1498 1.196 dholland namei_oneroot(struct namei_state *state, 1499 1.236 riastrad int neverfollow, int inhibitmagic, int isnfsd) 1500 1.131 dholland { 1501 1.131 dholland struct nameidata *ndp = state->ndp; 1502 1.131 dholland struct componentname *cnp = state->cnp; 1503 1.146 dholland struct vnode *searchdir, *foundobj; 1504 1.215 ad bool searchdir_locked = false; 1505 1.137 dholland int error; 1506 1.131 dholland 1507 1.196 dholland error = namei_start(state, isnfsd, &searchdir); 1508 1.131 dholland if (error) { 1509 1.164 dholland ndp->ni_dvp = NULL; 1510 1.164 dholland ndp->ni_vp = NULL; 1511 1.131 dholland return error; 1512 1.131 dholland } 1513 1.185 dholland KASSERT(searchdir->v_type == VDIR); 1514 1.131 dholland 1515 1.133 dholland /* 1516 1.139 dholland * Setup: break out flag bits into variables. 1517 1.139 dholland */ 1518 1.139 dholland state->docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE; 1519 1.139 dholland if (cnp->cn_nameiop == DELETE) 1520 1.139 dholland state->docache = 0; 1521 1.139 dholland state->rdonly = cnp->cn_flags & RDONLY; 1522 1.139 dholland 1523 1.139 dholland /* 1524 1.133 dholland * Keep going until we run out of path components. 1525 1.133 dholland */ 1526 1.139 dholland cnp->cn_nameptr = ndp->ni_pnbuf; 1527 1.185 dholland 1528 1.185 dholland /* drop leading slashes (already used them to choose startdir) */ 1529 1.185 dholland while (cnp->cn_nameptr[0] == '/') { 1530 1.185 dholland cnp->cn_nameptr++; 1531 1.185 dholland ndp->ni_pathlen--; 1532 1.185 dholland } 1533 1.185 dholland /* was it just "/"? */ 1534 1.185 dholland if (cnp->cn_nameptr[0] == '\0') { 1535 1.185 dholland foundobj = searchdir; 1536 1.185 dholland searchdir = NULL; 1537 1.185 dholland cnp->cn_flags |= ISLASTCN; 1538 1.185 dholland 1539 1.185 dholland /* bleh */ 1540 1.185 dholland goto skiploop; 1541 1.185 dholland } 1542 1.185 dholland 1543 1.131 dholland for (;;) { 1544 1.204 dholland KASSERT(searchdir != NULL); 1545 1.215 ad KASSERT(!searchdir_locked); 1546 1.215 ad 1547 1.215 ad /* 1548 1.215 ad * Parse out the first path name component that we need to 1549 1.215 ad * to consider. While doing this, attempt to use the name 1550 1.215 ad * cache to fast-forward through as many "easy" to find 1551 1.215 ad * components of the path as possible. 1552 1.215 ad */ 1553 1.215 ad error = lookup_fastforward(state, &searchdir, &foundobj); 1554 1.133 dholland 1555 1.133 dholland /* 1556 1.215 ad * If we didn't get a good answer from the namecache, then 1557 1.215 ad * go directly to the file system. 1558 1.133 dholland */ 1559 1.216 ad if (error == EOPNOTSUPP) { 1560 1.215 ad error = lookup_once(state, searchdir, &searchdir, 1561 1.215 ad &foundobj, &searchdir_locked); 1562 1.131 dholland } 1563 1.133 dholland 1564 1.133 dholland /* 1565 1.215 ad * If the vnode we found is mounted on, then cross the mount 1566 1.215 ad * and get the root vnode in foundobj. If this encounters 1567 1.215 ad * an error, it will dispose of foundobj, but searchdir is 1568 1.215 ad * untouched. 1569 1.133 dholland */ 1570 1.215 ad if (error == 0 && foundobj != NULL && 1571 1.215 ad foundobj->v_type == VDIR && 1572 1.215 ad foundobj->v_mountedhere != NULL && 1573 1.215 ad (cnp->cn_flags & NOCROSSMOUNT) == 0) { 1574 1.237 riastrad error = lookup_crossmount(state, &searchdir, 1575 1.237 riastrad &foundobj, &searchdir_locked); 1576 1.131 dholland } 1577 1.138 dholland 1578 1.139 dholland if (error) { 1579 1.204 dholland if (searchdir != NULL) { 1580 1.215 ad if (searchdir_locked) { 1581 1.215 ad searchdir_locked = false; 1582 1.215 ad vput(searchdir); 1583 1.215 ad } else { 1584 1.215 ad vrele(searchdir); 1585 1.215 ad } 1586 1.204 dholland } 1587 1.168 dholland ndp->ni_dvp = NULL; 1588 1.139 dholland ndp->ni_vp = NULL; 1589 1.138 dholland /* 1590 1.139 dholland * Note that if we're doing TRYEMULROOT we can 1591 1.139 dholland * retry with the normal root. Where this is 1592 1.139 dholland * currently set matches previous practice, 1593 1.139 dholland * but the previous practice didn't make much 1594 1.139 dholland * sense and somebody should sit down and 1595 1.139 dholland * figure out which cases should cause retry 1596 1.139 dholland * and which shouldn't. XXX. 1597 1.138 dholland */ 1598 1.139 dholland state->attempt_retry = 1; 1599 1.236 riastrad return error; 1600 1.139 dholland } 1601 1.157 dholland 1602 1.162 dholland if (foundobj == NULL) { 1603 1.162 dholland /* 1604 1.162 dholland * Success with no object returned means we're 1605 1.162 dholland * creating something and it isn't already 1606 1.181 dholland * there. Break out of the main loop now so 1607 1.162 dholland * the code below doesn't have to test for 1608 1.162 dholland * foundobj == NULL. 1609 1.162 dholland */ 1610 1.204 dholland /* lookup_once can't have dropped the searchdir */ 1611 1.222 ad KASSERT(searchdir != NULL || 1612 1.222 ad (cnp->cn_flags & ISLASTCN) != 0); 1613 1.181 dholland break; 1614 1.138 dholland } 1615 1.131 dholland 1616 1.131 dholland /* 1617 1.139 dholland * Check for symbolic link. If we've reached one, 1618 1.139 dholland * follow it, unless we aren't supposed to. Back up 1619 1.139 dholland * over any slashes that we skipped, as we will need 1620 1.139 dholland * them again. 1621 1.131 dholland */ 1622 1.146 dholland if (namei_atsymlink(state, foundobj)) { 1623 1.215 ad /* Don't need searchdir locked any more. */ 1624 1.215 ad if (searchdir_locked) { 1625 1.215 ad searchdir_locked = false; 1626 1.215 ad VOP_UNLOCK(searchdir); 1627 1.215 ad } 1628 1.139 dholland ndp->ni_pathlen += state->slashes; 1629 1.139 dholland ndp->ni_next -= state->slashes; 1630 1.134 dholland if (neverfollow) { 1631 1.238 riastrad error = SET_ERROR(EINVAL); 1632 1.204 dholland } else if (searchdir == NULL) { 1633 1.204 dholland /* 1634 1.204 dholland * dholland 20160410: lookup_once only 1635 1.204 dholland * drops searchdir if it crossed a 1636 1.204 dholland * mount point. Therefore, if we get 1637 1.204 dholland * here it means we crossed a mount 1638 1.204 dholland * point to a mounted filesystem whose 1639 1.204 dholland * root vnode is a symlink. In theory 1640 1.204 dholland * we could continue at this point by 1641 1.204 dholland * using the pre-crossing searchdir 1642 1.204 dholland * (e.g. just take out an extra 1643 1.204 dholland * reference on it before calling 1644 1.204 dholland * lookup_once so we still have it), 1645 1.204 dholland * but this will make an ugly mess and 1646 1.204 dholland * it should never happen in practice 1647 1.204 dholland * as only badly broken filesystems 1648 1.204 dholland * have non-directory root vnodes. (I 1649 1.204 dholland * have seen this sort of thing with 1650 1.204 dholland * NFS occasionally but even then it 1651 1.204 dholland * means something's badly wrong.) 1652 1.204 dholland */ 1653 1.238 riastrad error = SET_ERROR(ENOTDIR); 1654 1.134 dholland } else { 1655 1.152 dholland /* 1656 1.152 dholland * dholland 20110410: if we're at a 1657 1.152 dholland * union mount it might make sense to 1658 1.152 dholland * use the top of the union stack here 1659 1.152 dholland * rather than the layer we found the 1660 1.152 dholland * symlink in. (FUTURE) 1661 1.152 dholland */ 1662 1.141 dholland error = namei_follow(state, inhibitmagic, 1663 1.236 riastrad searchdir, foundobj, 1664 1.236 riastrad &searchdir); 1665 1.134 dholland } 1666 1.131 dholland if (error) { 1667 1.165 dholland KASSERT(searchdir != foundobj); 1668 1.204 dholland if (searchdir != NULL) { 1669 1.215 ad vrele(searchdir); 1670 1.204 dholland } 1671 1.215 ad vrele(foundobj); 1672 1.168 dholland ndp->ni_dvp = NULL; 1673 1.131 dholland ndp->ni_vp = NULL; 1674 1.131 dholland return error; 1675 1.131 dholland } 1676 1.174 jakllsch vrele(foundobj); 1677 1.167 dholland foundobj = NULL; 1678 1.189 riastrad 1679 1.189 riastrad /* 1680 1.189 riastrad * If we followed a symlink to `/' and there 1681 1.189 riastrad * are no more components after the symlink, 1682 1.189 riastrad * we're done with the loop and what we found 1683 1.189 riastrad * is the searchdir. 1684 1.189 riastrad */ 1685 1.189 riastrad if (cnp->cn_nameptr[0] == '\0') { 1686 1.204 dholland KASSERT(searchdir != NULL); 1687 1.189 riastrad foundobj = searchdir; 1688 1.189 riastrad searchdir = NULL; 1689 1.189 riastrad cnp->cn_flags |= ISLASTCN; 1690 1.189 riastrad break; 1691 1.189 riastrad } 1692 1.189 riastrad 1693 1.139 dholland continue; 1694 1.139 dholland } 1695 1.139 dholland 1696 1.139 dholland /* 1697 1.183 dholland * Not a symbolic link. 1698 1.183 dholland * 1699 1.139 dholland * Check for directory, if the component was 1700 1.139 dholland * followed by a series of slashes. 1701 1.139 dholland */ 1702 1.190 yamt if ((foundobj->v_type != VDIR) && 1703 1.190 yamt (cnp->cn_flags & REQUIREDIR)) { 1704 1.204 dholland KASSERT(foundobj != searchdir); 1705 1.204 dholland if (searchdir) { 1706 1.215 ad if (searchdir_locked) { 1707 1.215 ad searchdir_locked = false; 1708 1.215 ad vput(searchdir); 1709 1.215 ad } else { 1710 1.215 ad vrele(searchdir); 1711 1.215 ad } 1712 1.215 ad } else { 1713 1.215 ad KASSERT(!searchdir_locked); 1714 1.139 dholland } 1715 1.215 ad vrele(foundobj); 1716 1.168 dholland ndp->ni_dvp = NULL; 1717 1.168 dholland ndp->ni_vp = NULL; 1718 1.139 dholland state->attempt_retry = 1; 1719 1.238 riastrad return SET_ERROR(ENOTDIR); 1720 1.139 dholland } 1721 1.139 dholland 1722 1.139 dholland /* 1723 1.183 dholland * Stop if we've reached the last component. 1724 1.139 dholland */ 1725 1.183 dholland if (cnp->cn_flags & ISLASTCN) { 1726 1.183 dholland break; 1727 1.139 dholland } 1728 1.139 dholland 1729 1.183 dholland /* 1730 1.183 dholland * Continue with the next component. 1731 1.183 dholland */ 1732 1.183 dholland cnp->cn_nameptr = ndp->ni_next; 1733 1.215 ad if (searchdir != NULL) { 1734 1.215 ad if (searchdir_locked) { 1735 1.215 ad searchdir_locked = false; 1736 1.215 ad vput(searchdir); 1737 1.215 ad } else { 1738 1.215 ad vrele(searchdir); 1739 1.215 ad } 1740 1.183 dholland } 1741 1.183 dholland searchdir = foundobj; 1742 1.183 dholland foundobj = NULL; 1743 1.179 dholland } 1744 1.179 dholland 1745 1.215 ad KASSERT((cnp->cn_flags & LOCKPARENT) == 0 || searchdir == NULL || 1746 1.215 ad VOP_ISLOCKED(searchdir) == LK_EXCLUSIVE); 1747 1.215 ad 1748 1.236 riastrad skiploop: 1749 1.182 dholland if (foundobj != NULL) { 1750 1.146 dholland if (foundobj == ndp->ni_erootdir) { 1751 1.139 dholland /* 1752 1.139 dholland * We are about to return the emulation root. 1753 1.139 dholland * This isn't a good idea because code might 1754 1.139 dholland * repeatedly lookup ".." until the file 1755 1.139 dholland * matches that returned for "/" and loop 1756 1.139 dholland * forever. So convert it to the real root. 1757 1.139 dholland */ 1758 1.170 dholland if (searchdir != NULL) { 1759 1.215 ad if (searchdir_locked) { 1760 1.215 ad vput(searchdir); 1761 1.215 ad searchdir_locked = false; 1762 1.215 ad } else { 1763 1.170 dholland vrele(searchdir); 1764 1.215 ad } 1765 1.170 dholland searchdir = NULL; 1766 1.170 dholland } 1767 1.215 ad vrele(foundobj); 1768 1.146 dholland foundobj = ndp->ni_rootdir; 1769 1.146 dholland vref(foundobj); 1770 1.131 dholland } 1771 1.139 dholland 1772 1.139 dholland /* 1773 1.158 dholland * If the caller requested the parent node (i.e. it's 1774 1.158 dholland * a CREATE, DELETE, or RENAME), and we don't have one 1775 1.158 dholland * (because this is the root directory, or we crossed 1776 1.158 dholland * a mount point), then we must fail. 1777 1.226 dholland * 1778 1.226 dholland * 20210604 dholland when NONEXCLHACK is set (open 1779 1.226 dholland * with O_CREAT but not O_EXCL) skip this logic. Since 1780 1.226 dholland * we have a foundobj, open will not be creating, so 1781 1.226 dholland * it doesn't actually need or use the searchdir, so 1782 1.226 dholland * it's ok to return it even if it's on a different 1783 1.226 dholland * volume, and it's also ok to return NULL; by setting 1784 1.226 dholland * NONEXCLHACK the open code promises to cope with 1785 1.226 dholland * those cases correctly. (That is, it should do what 1786 1.226 dholland * it would do anyway, that is, just release the 1787 1.226 dholland * searchdir, except not crash if it's null.) This is 1788 1.226 dholland * needed because otherwise opening mountpoints with 1789 1.226 dholland * O_CREAT but not O_EXCL fails... which is a silly 1790 1.226 dholland * thing to do but ought to work. (This whole issue 1791 1.226 dholland * came to light because 3rd party code wanted to open 1792 1.226 dholland * certain procfs nodes with O_CREAT for some 3rd 1793 1.226 dholland * party reason, and it failed.) 1794 1.226 dholland * 1795 1.226 dholland * Note that NONEXCLHACK is properly a different 1796 1.226 dholland * nameiop (it is partway between LOOKUP and CREATE) 1797 1.226 dholland * but it was stuffed in as a flag instead to make the 1798 1.226 dholland * resulting patch less invasive for pullup. Blah. 1799 1.139 dholland */ 1800 1.158 dholland if (cnp->cn_nameiop != LOOKUP && 1801 1.158 dholland (searchdir == NULL || 1802 1.236 riastrad searchdir->v_mount != foundobj->v_mount) && 1803 1.226 dholland (cnp->cn_flags & NONEXCLHACK) == 0) { 1804 1.170 dholland if (searchdir) { 1805 1.215 ad if (searchdir_locked) { 1806 1.215 ad vput(searchdir); 1807 1.215 ad searchdir_locked = false; 1808 1.215 ad } else { 1809 1.215 ad vrele(searchdir); 1810 1.215 ad } 1811 1.215 ad searchdir = NULL; 1812 1.170 dholland } 1813 1.215 ad vrele(foundobj); 1814 1.170 dholland foundobj = NULL; 1815 1.170 dholland ndp->ni_dvp = NULL; 1816 1.170 dholland ndp->ni_vp = NULL; 1817 1.170 dholland state->attempt_retry = 1; 1818 1.170 dholland 1819 1.139 dholland switch (cnp->cn_nameiop) { 1820 1.236 riastrad case CREATE: 1821 1.238 riastrad return SET_ERROR(EEXIST); 1822 1.236 riastrad case DELETE: 1823 1.236 riastrad case RENAME: 1824 1.238 riastrad return SET_ERROR(EBUSY); 1825 1.236 riastrad default: 1826 1.139 dholland break; 1827 1.139 dholland } 1828 1.171 dholland panic("Invalid nameiop\n"); 1829 1.139 dholland } 1830 1.139 dholland 1831 1.139 dholland /* 1832 1.139 dholland * Disallow directory write attempts on read-only lookups. 1833 1.139 dholland * Prefers EEXIST over EROFS for the CREATE case. 1834 1.139 dholland */ 1835 1.139 dholland if (state->rdonly && 1836 1.139 dholland (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) { 1837 1.157 dholland if (searchdir) { 1838 1.215 ad if (searchdir_locked) { 1839 1.170 dholland vput(searchdir); 1840 1.215 ad searchdir_locked = false; 1841 1.170 dholland } else { 1842 1.170 dholland vrele(searchdir); 1843 1.170 dholland } 1844 1.170 dholland searchdir = NULL; 1845 1.157 dholland } 1846 1.215 ad vrele(foundobj); 1847 1.170 dholland foundobj = NULL; 1848 1.168 dholland ndp->ni_dvp = NULL; 1849 1.139 dholland ndp->ni_vp = NULL; 1850 1.139 dholland state->attempt_retry = 1; 1851 1.238 riastrad return SET_ERROR(EROFS); 1852 1.139 dholland } 1853 1.215 ad 1854 1.215 ad /* Lock the leaf node if requested. */ 1855 1.215 ad if ((cnp->cn_flags & (LOCKLEAF | LOCKPARENT)) == LOCKPARENT && 1856 1.215 ad searchdir == foundobj) { 1857 1.172 dholland /* 1858 1.172 dholland * Note: if LOCKPARENT but not LOCKLEAF is 1859 1.172 dholland * set, and searchdir == foundobj, this code 1860 1.172 dholland * necessarily unlocks the parent as well as 1861 1.172 dholland * the leaf. That is, just because you specify 1862 1.172 dholland * LOCKPARENT doesn't mean you necessarily get 1863 1.172 dholland * a locked parent vnode. The code in 1864 1.172 dholland * vfs_syscalls.c, and possibly elsewhere, 1865 1.172 dholland * that uses this combination "knows" this, so 1866 1.172 dholland * it can't be safely changed. Feh. XXX 1867 1.172 dholland */ 1868 1.215 ad KASSERT(searchdir_locked); 1869 1.237 riastrad VOP_UNLOCK(searchdir); 1870 1.237 riastrad searchdir_locked = false; 1871 1.215 ad } else if ((cnp->cn_flags & LOCKLEAF) != 0 && 1872 1.215 ad (searchdir != foundobj || 1873 1.236 riastrad (cnp->cn_flags & LOCKPARENT) == 0)) { 1874 1.215 ad const int lktype = (cnp->cn_flags & LOCKSHARED) != 0 ? 1875 1.215 ad LK_SHARED : LK_EXCLUSIVE; 1876 1.215 ad vn_lock(foundobj, lktype | LK_RETRY); 1877 1.131 dholland } 1878 1.179 dholland } 1879 1.139 dholland 1880 1.131 dholland /* 1881 1.133 dholland * Done. 1882 1.131 dholland */ 1883 1.131 dholland 1884 1.133 dholland /* 1885 1.133 dholland * If LOCKPARENT is not set, the parent directory isn't returned. 1886 1.133 dholland */ 1887 1.157 dholland if ((cnp->cn_flags & LOCKPARENT) == 0 && searchdir != NULL) { 1888 1.215 ad vrele(searchdir); 1889 1.157 dholland searchdir = NULL; 1890 1.131 dholland } 1891 1.131 dholland 1892 1.157 dholland ndp->ni_dvp = searchdir; 1893 1.165 dholland ndp->ni_vp = foundobj; 1894 1.137 dholland return 0; 1895 1.137 dholland } 1896 1.137 dholland 1897 1.173 dholland /* 1898 1.173 dholland * Do namei; wrapper layer that handles TRYEMULROOT. 1899 1.173 dholland */ 1900 1.137 dholland static int 1901 1.196 dholland namei_tryemulroot(struct namei_state *state, 1902 1.236 riastrad int neverfollow, int inhibitmagic, int isnfsd) 1903 1.137 dholland { 1904 1.137 dholland int error; 1905 1.137 dholland 1906 1.137 dholland struct nameidata *ndp = state->ndp; 1907 1.137 dholland struct componentname *cnp = state->cnp; 1908 1.137 dholland const char *savepath = NULL; 1909 1.137 dholland 1910 1.137 dholland KASSERT(cnp == &ndp->ni_cnd); 1911 1.137 dholland 1912 1.137 dholland if (cnp->cn_flags & TRYEMULROOT) { 1913 1.137 dholland savepath = pathbuf_stringcopy_get(ndp->ni_pathbuf); 1914 1.137 dholland } 1915 1.137 dholland 1916 1.236 riastrad emul_retry: 1917 1.137 dholland state->attempt_retry = 0; 1918 1.137 dholland 1919 1.196 dholland error = namei_oneroot(state, neverfollow, inhibitmagic, isnfsd); 1920 1.137 dholland if (error) { 1921 1.137 dholland /* 1922 1.137 dholland * Once namei has started up, the existence of ni_erootdir 1923 1.137 dholland * tells us whether we're working from an emulation root. 1924 1.137 dholland * The TRYEMULROOT flag isn't necessarily authoritative. 1925 1.137 dholland */ 1926 1.137 dholland if (ndp->ni_erootdir != NULL && state->attempt_retry) { 1927 1.137 dholland /* Retry the whole thing using the normal root */ 1928 1.137 dholland cnp->cn_flags &= ~TRYEMULROOT; 1929 1.137 dholland state->attempt_retry = 0; 1930 1.137 dholland 1931 1.137 dholland /* kinda gross */ 1932 1.137 dholland strcpy(ndp->ni_pathbuf->pb_path, savepath); 1933 1.137 dholland pathbuf_stringcopy_put(ndp->ni_pathbuf, savepath); 1934 1.137 dholland savepath = NULL; 1935 1.137 dholland 1936 1.137 dholland goto emul_retry; 1937 1.137 dholland } 1938 1.137 dholland } 1939 1.131 dholland if (savepath != NULL) { 1940 1.131 dholland pathbuf_stringcopy_put(ndp->ni_pathbuf, savepath); 1941 1.131 dholland } 1942 1.137 dholland return error; 1943 1.131 dholland } 1944 1.131 dholland 1945 1.173 dholland /* 1946 1.173 dholland * External interface. 1947 1.173 dholland */ 1948 1.131 dholland int 1949 1.131 dholland namei(struct nameidata *ndp) 1950 1.131 dholland { 1951 1.131 dholland struct namei_state state; 1952 1.131 dholland int error; 1953 1.131 dholland 1954 1.131 dholland namei_init(&state, ndp); 1955 1.196 dholland error = namei_tryemulroot(&state, 1956 1.236 riastrad 0/*!neverfollow*/, 0/*!inhibitmagic*/, 0/*isnfsd*/); 1957 1.131 dholland namei_cleanup(&state); 1958 1.131 dholland 1959 1.159 dholland if (error) { 1960 1.159 dholland /* make sure no stray refs leak out */ 1961 1.164 dholland KASSERT(ndp->ni_dvp == NULL); 1962 1.164 dholland KASSERT(ndp->ni_vp == NULL); 1963 1.159 dholland } 1964 1.159 dholland 1965 1.131 dholland return error; 1966 1.131 dholland } 1967 1.131 dholland 1968 1.131 dholland //////////////////////////////////////////////////////////// 1969 1.131 dholland 1970 1.12 mycroft /* 1971 1.173 dholland * External interface used by nfsd. This is basically different from 1972 1.173 dholland * namei only in that it has the ability to pass in the "current 1973 1.173 dholland * directory", and uses an extra flag "neverfollow" for which there's 1974 1.173 dholland * no physical flag defined in namei.h. (There used to be a cut&paste 1975 1.173 dholland * copy of about half of namei in nfsd to allow these minor 1976 1.173 dholland * adjustments to exist.) 1977 1.119 dholland * 1978 1.173 dholland * XXX: the namei interface should be adjusted so nfsd can just use 1979 1.173 dholland * ordinary namei(). 1980 1.118 dholland */ 1981 1.134 dholland int 1982 1.135 dholland lookup_for_nfsd(struct nameidata *ndp, struct vnode *forcecwd, int neverfollow) 1983 1.134 dholland { 1984 1.134 dholland struct namei_state state; 1985 1.134 dholland int error; 1986 1.120 dholland 1987 1.198 dholland KASSERT(ndp->ni_atdir == NULL); 1988 1.198 dholland ndp->ni_atdir = forcecwd; 1989 1.194 dholland 1990 1.134 dholland namei_init(&state, ndp); 1991 1.196 dholland error = namei_tryemulroot(&state, 1992 1.236 riastrad neverfollow, 1/*inhibitmagic*/, 1/*isnfsd*/); 1993 1.119 dholland namei_cleanup(&state); 1994 1.119 dholland 1995 1.159 dholland if (error) { 1996 1.159 dholland /* make sure no stray refs leak out */ 1997 1.164 dholland KASSERT(ndp->ni_dvp == NULL); 1998 1.164 dholland KASSERT(ndp->ni_vp == NULL); 1999 1.159 dholland } 2000 1.159 dholland 2001 1.119 dholland return error; 2002 1.119 dholland } 2003 1.119 dholland 2004 1.173 dholland /* 2005 1.173 dholland * A second external interface used by nfsd. This turns out to be a 2006 1.173 dholland * single lookup used by the WebNFS code (ha!) to get "index.html" or 2007 1.173 dholland * equivalent when asked for a directory. It should eventually evolve 2008 1.173 dholland * into some kind of namei_once() call; for the time being it's kind 2009 1.173 dholland * of a mess. XXX. 2010 1.173 dholland * 2011 1.173 dholland * dholland 20110109: I don't think it works, and I don't think it 2012 1.173 dholland * worked before I started hacking and slashing either, and I doubt 2013 1.173 dholland * anyone will ever notice. 2014 1.173 dholland */ 2015 1.173 dholland 2016 1.173 dholland /* 2017 1.173 dholland * Internals. This calls lookup_once() after setting up the assorted 2018 1.173 dholland * pieces of state the way they ought to be. 2019 1.173 dholland */ 2020 1.136 dholland static int 2021 1.196 dholland do_lookup_for_nfsd_index(struct namei_state *state) 2022 1.136 dholland { 2023 1.227 dholland int error; 2024 1.136 dholland 2025 1.136 dholland struct componentname *cnp = state->cnp; 2026 1.136 dholland struct nameidata *ndp = state->ndp; 2027 1.196 dholland struct vnode *startdir; 2028 1.147 dholland struct vnode *foundobj; 2029 1.215 ad bool startdir_locked; 2030 1.136 dholland const char *cp; /* pointer into pathname argument */ 2031 1.136 dholland 2032 1.136 dholland KASSERT(cnp == &ndp->ni_cnd); 2033 1.136 dholland 2034 1.198 dholland startdir = state->ndp->ni_atdir; 2035 1.196 dholland 2036 1.136 dholland cnp->cn_nameptr = ndp->ni_pnbuf; 2037 1.136 dholland state->docache = 1; 2038 1.136 dholland state->rdonly = cnp->cn_flags & RDONLY; 2039 1.136 dholland ndp->ni_dvp = NULL; 2040 1.136 dholland 2041 1.228 dholland error = VOP_PARSEPATH(startdir, cnp->cn_nameptr, &cnp->cn_namelen); 2042 1.227 dholland if (error) { 2043 1.227 dholland return error; 2044 1.227 dholland } 2045 1.227 dholland 2046 1.197 dholland cp = cnp->cn_nameptr + cnp->cn_namelen; 2047 1.191 christos KASSERT(cnp->cn_namelen <= KERNEL_NAME_MAX); 2048 1.136 dholland ndp->ni_pathlen -= cnp->cn_namelen; 2049 1.136 dholland ndp->ni_next = cp; 2050 1.136 dholland state->slashes = 0; 2051 1.136 dholland cnp->cn_flags &= ~REQUIREDIR; 2052 1.136 dholland cnp->cn_flags |= MAKEENTRY|ISLASTCN; 2053 1.136 dholland 2054 1.136 dholland if (cnp->cn_namelen == 2 && 2055 1.136 dholland cnp->cn_nameptr[1] == '.' && cnp->cn_nameptr[0] == '.') 2056 1.136 dholland cnp->cn_flags |= ISDOTDOT; 2057 1.136 dholland else 2058 1.136 dholland cnp->cn_flags &= ~ISDOTDOT; 2059 1.136 dholland 2060 1.160 dholland /* 2061 1.160 dholland * Because lookup_once can change the startdir, we need our 2062 1.160 dholland * own reference to it to avoid consuming the caller's. 2063 1.160 dholland */ 2064 1.160 dholland vref(startdir); 2065 1.215 ad error = lookup_once(state, startdir, &startdir, &foundobj, 2066 1.215 ad &startdir_locked); 2067 1.215 ad 2068 1.215 ad KASSERT((cnp->cn_flags & LOCKPARENT) == 0); 2069 1.215 ad if (startdir_locked) { 2070 1.215 ad VOP_UNLOCK(startdir); 2071 1.215 ad startdir_locked = false; 2072 1.190 yamt } 2073 1.162 dholland 2074 1.215 ad /* 2075 1.215 ad * If the vnode we found is mounted on, then cross the mount and get 2076 1.215 ad * the root vnode in foundobj. If this encounters an error, it will 2077 1.215 ad * dispose of foundobj, but searchdir is untouched. 2078 1.215 ad */ 2079 1.215 ad if (error == 0 && foundobj != NULL && 2080 1.215 ad foundobj->v_type == VDIR && 2081 1.215 ad foundobj->v_mountedhere != NULL && 2082 1.215 ad (cnp->cn_flags & NOCROSSMOUNT) == 0) { 2083 1.215 ad error = lookup_crossmount(state, &startdir, &foundobj, 2084 1.215 ad &startdir_locked); 2085 1.136 dholland } 2086 1.136 dholland 2087 1.215 ad /* Now toss startdir and see if we have an error. */ 2088 1.215 ad if (startdir != NULL) 2089 1.215 ad vrele(startdir); 2090 1.215 ad if (error) 2091 1.215 ad foundobj = NULL; 2092 1.215 ad else if (foundobj != NULL && (cnp->cn_flags & LOCKLEAF) != 0) 2093 1.215 ad vn_lock(foundobj, LK_EXCLUSIVE | LK_RETRY); 2094 1.136 dholland 2095 1.215 ad ndp->ni_vp = foundobj; 2096 1.236 riastrad return error; 2097 1.136 dholland } 2098 1.136 dholland 2099 1.173 dholland /* 2100 1.173 dholland * External interface. The partitioning between this function and the 2101 1.173 dholland * above isn't very clear - the above function exists mostly so code 2102 1.173 dholland * that uses "state->" can be shuffled around without having to change 2103 1.173 dholland * it to "state.". 2104 1.173 dholland */ 2105 1.118 dholland int 2106 1.128 dholland lookup_for_nfsd_index(struct nameidata *ndp, struct vnode *startdir) 2107 1.118 dholland { 2108 1.118 dholland struct namei_state state; 2109 1.118 dholland int error; 2110 1.118 dholland 2111 1.198 dholland KASSERT(ndp->ni_atdir == NULL); 2112 1.198 dholland ndp->ni_atdir = startdir; 2113 1.194 dholland 2114 1.133 dholland /* 2115 1.135 dholland * Note: the name sent in here (is not|should not be) allowed 2116 1.135 dholland * to contain a slash. 2117 1.133 dholland */ 2118 1.191 christos if (strlen(ndp->ni_pathbuf->pb_path) > KERNEL_NAME_MAX) { 2119 1.238 riastrad return SET_ERROR(ENAMETOOLONG); 2120 1.136 dholland } 2121 1.136 dholland if (strchr(ndp->ni_pathbuf->pb_path, '/')) { 2122 1.238 riastrad return SET_ERROR(EINVAL); 2123 1.136 dholland } 2124 1.133 dholland 2125 1.133 dholland ndp->ni_pathlen = strlen(ndp->ni_pathbuf->pb_path) + 1; 2126 1.133 dholland ndp->ni_pnbuf = NULL; 2127 1.133 dholland ndp->ni_cnd.cn_nameptr = NULL; 2128 1.133 dholland 2129 1.118 dholland namei_init(&state, ndp); 2130 1.196 dholland error = do_lookup_for_nfsd_index(&state); 2131 1.118 dholland namei_cleanup(&state); 2132 1.118 dholland 2133 1.118 dholland return error; 2134 1.118 dholland } 2135 1.118 dholland 2136 1.131 dholland //////////////////////////////////////////////////////////// 2137 1.131 dholland 2138 1.118 dholland /* 2139 1.12 mycroft * Reacquire a path name component. 2140 1.73 chs * dvp is locked on entry and exit. 2141 1.73 chs * *vpp is locked on exit unless it's NULL. 2142 1.12 mycroft */ 2143 1.12 mycroft int 2144 1.236 riastrad relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, 2145 1.236 riastrad int dummy) 2146 1.12 mycroft { 2147 1.12 mycroft int rdonly; /* lookup read-only flag bit */ 2148 1.12 mycroft int error = 0; 2149 1.52 yamt #ifdef DEBUG 2150 1.197 dholland size_t newlen; /* DEBUG: check name len */ 2151 1.197 dholland const char *cp; /* DEBUG: check name ptr */ 2152 1.52 yamt #endif /* DEBUG */ 2153 1.12 mycroft 2154 1.130 dholland (void)dummy; 2155 1.130 dholland 2156 1.12 mycroft /* 2157 1.12 mycroft * Setup: break out flag bits into variables. 2158 1.12 mycroft */ 2159 1.12 mycroft rdonly = cnp->cn_flags & RDONLY; 2160 1.12 mycroft 2161 1.12 mycroft /* 2162 1.12 mycroft * Search a new directory. 2163 1.12 mycroft * 2164 1.12 mycroft * The cn_hash value is for use by vfs_cache. 2165 1.12 mycroft * The last component of the filename is left accessible via 2166 1.12 mycroft * cnp->cn_nameptr for callers that need the name. Callers needing 2167 1.12 mycroft * the name set the SAVENAME flag. When done, they assume 2168 1.12 mycroft * responsibility for freeing the pathname buffer. 2169 1.12 mycroft */ 2170 1.52 yamt #ifdef DEBUG 2171 1.197 dholland #if 0 2172 1.39 lukem cp = NULL; 2173 1.39 lukem newhash = namei_hash(cnp->cn_nameptr, &cp); 2174 1.81 chs if ((uint32_t)newhash != (uint32_t)cnp->cn_hash) 2175 1.12 mycroft panic("relookup: bad hash"); 2176 1.197 dholland #endif 2177 1.228 dholland error = VOP_PARSEPATH(dvp, cnp->cn_nameptr, &newlen); 2178 1.227 dholland if (error) { 2179 1.227 dholland panic("relookup: parsepath failed with error %d", error); 2180 1.227 dholland } 2181 1.197 dholland if (cnp->cn_namelen != newlen) 2182 1.58 christos panic("relookup: bad len"); 2183 1.197 dholland cp = cnp->cn_nameptr + cnp->cn_namelen; 2184 1.53 yamt while (*cp == '/') 2185 1.53 yamt cp++; 2186 1.12 mycroft if (*cp != 0) 2187 1.12 mycroft panic("relookup: not last component"); 2188 1.52 yamt #endif /* DEBUG */ 2189 1.12 mycroft 2190 1.12 mycroft /* 2191 1.12 mycroft * Check for degenerate name (e.g. / or "") 2192 1.12 mycroft * which is a way of talking about a directory, 2193 1.12 mycroft * e.g. like "/." or ".". 2194 1.12 mycroft */ 2195 1.23 mycroft if (cnp->cn_nameptr[0] == '\0') 2196 1.23 mycroft panic("relookup: null name"); 2197 1.12 mycroft 2198 1.12 mycroft if (cnp->cn_flags & ISDOTDOT) 2199 1.58 christos panic("relookup: lookup on dot-dot"); 2200 1.12 mycroft 2201 1.12 mycroft /* 2202 1.12 mycroft * We now have a segment name to search for, and a directory to search. 2203 1.12 mycroft */ 2204 1.195 dholland *vpp = NULL; 2205 1.129 dholland error = VOP_LOOKUP(dvp, vpp, cnp); 2206 1.129 dholland if ((error) != 0) { 2207 1.205 riastrad KASSERTMSG((*vpp == NULL), 2208 1.205 riastrad "leaf `%s' should be empty but is %p", 2209 1.205 riastrad cnp->cn_nameptr, *vpp); 2210 1.12 mycroft if (error != EJUSTRETURN) 2211 1.12 mycroft goto bad; 2212 1.12 mycroft } 2213 1.12 mycroft 2214 1.12 mycroft /* 2215 1.12 mycroft * Check for symbolic link 2216 1.12 mycroft */ 2217 1.205 riastrad KASSERTMSG((*vpp == NULL || (*vpp)->v_type != VLNK || 2218 1.205 riastrad (cnp->cn_flags & FOLLOW) == 0), 2219 1.205 riastrad "relookup: symlink found"); 2220 1.12 mycroft 2221 1.12 mycroft /* 2222 1.94 pooka * Check for read-only lookups. 2223 1.12 mycroft */ 2224 1.81 chs if (rdonly && cnp->cn_nameiop != LOOKUP) { 2225 1.238 riastrad error = SET_ERROR(EROFS); 2226 1.81 chs if (*vpp) { 2227 1.201 hannken vrele(*vpp); 2228 1.81 chs } 2229 1.73 chs goto bad; 2230 1.12 mycroft } 2231 1.201 hannken /* 2232 1.201 hannken * Lock result. 2233 1.201 hannken */ 2234 1.201 hannken if (*vpp && *vpp != dvp) { 2235 1.201 hannken error = vn_lock(*vpp, LK_EXCLUSIVE); 2236 1.201 hannken if (error != 0) { 2237 1.201 hannken vrele(*vpp); 2238 1.201 hannken goto bad; 2239 1.201 hannken } 2240 1.201 hannken } 2241 1.236 riastrad return 0; 2242 1.12 mycroft 2243 1.12 mycroft bad: 2244 1.12 mycroft *vpp = NULL; 2245 1.236 riastrad return error; 2246 1.10 cgd } 2247 1.116 dholland 2248 1.116 dholland /* 2249 1.116 dholland * namei_simple - simple forms of namei. 2250 1.116 dholland * 2251 1.116 dholland * These are wrappers to allow the simple case callers of namei to be 2252 1.116 dholland * left alone while everything else changes under them. 2253 1.116 dholland */ 2254 1.116 dholland 2255 1.116 dholland /* Flags */ 2256 1.116 dholland struct namei_simple_flags_type { 2257 1.116 dholland int dummy; 2258 1.116 dholland }; 2259 1.116 dholland static const struct namei_simple_flags_type ns_nn, ns_nt, ns_fn, ns_ft; 2260 1.116 dholland const namei_simple_flags_t NSM_NOFOLLOW_NOEMULROOT = &ns_nn; 2261 1.116 dholland const namei_simple_flags_t NSM_NOFOLLOW_TRYEMULROOT = &ns_nt; 2262 1.116 dholland const namei_simple_flags_t NSM_FOLLOW_NOEMULROOT = &ns_fn; 2263 1.116 dholland const namei_simple_flags_t NSM_FOLLOW_TRYEMULROOT = &ns_ft; 2264 1.116 dholland 2265 1.236 riastrad static int 2266 1.116 dholland namei_simple_convert_flags(namei_simple_flags_t sflags) 2267 1.116 dholland { 2268 1.236 riastrad 2269 1.116 dholland if (sflags == NSM_NOFOLLOW_NOEMULROOT) 2270 1.116 dholland return NOFOLLOW | 0; 2271 1.116 dholland if (sflags == NSM_NOFOLLOW_TRYEMULROOT) 2272 1.116 dholland return NOFOLLOW | TRYEMULROOT; 2273 1.116 dholland if (sflags == NSM_FOLLOW_NOEMULROOT) 2274 1.116 dholland return FOLLOW | 0; 2275 1.116 dholland if (sflags == NSM_FOLLOW_TRYEMULROOT) 2276 1.116 dholland return FOLLOW | TRYEMULROOT; 2277 1.116 dholland panic("namei_simple_convert_flags: bogus sflags\n"); 2278 1.116 dholland return 0; 2279 1.116 dholland } 2280 1.116 dholland 2281 1.116 dholland int 2282 1.116 dholland namei_simple_kernel(const char *path, namei_simple_flags_t sflags, 2283 1.235 christos struct vnode **vp_ret) 2284 1.200 manu { 2285 1.236 riastrad 2286 1.200 manu return nameiat_simple_kernel(NULL, path, sflags, vp_ret); 2287 1.200 manu } 2288 1.200 manu 2289 1.200 manu int 2290 1.235 christos nameiat_simple(struct vnode *dvp, struct pathbuf *pb, 2291 1.235 christos namei_simple_flags_t sflags, struct vnode **vp_ret) 2292 1.235 christos { 2293 1.235 christos struct nameidata nd; 2294 1.235 christos int error; 2295 1.235 christos 2296 1.235 christos NDINIT(&nd, LOOKUP, namei_simple_convert_flags(sflags), pb); 2297 1.235 christos 2298 1.235 christos if (dvp != NULL) 2299 1.235 christos NDAT(&nd, dvp); 2300 1.235 christos 2301 1.235 christos error = namei(&nd); 2302 1.235 christos if (error != 0) 2303 1.235 christos return error; 2304 1.235 christos 2305 1.235 christos *vp_ret = nd.ni_vp; 2306 1.235 christos return 0; 2307 1.235 christos } 2308 1.235 christos 2309 1.235 christos int 2310 1.223 riastrad nameiat_simple_kernel(struct vnode *dvp, const char *path, 2311 1.235 christos namei_simple_flags_t sflags, struct vnode **vp_ret) 2312 1.116 dholland { 2313 1.123 dholland struct pathbuf *pb; 2314 1.235 christos int error; 2315 1.116 dholland 2316 1.123 dholland pb = pathbuf_create(path); 2317 1.235 christos if (pb == NULL) 2318 1.238 riastrad return SET_ERROR(ENOMEM); 2319 1.200 manu 2320 1.235 christos error = nameiat_simple(dvp, pb, sflags, vp_ret); 2321 1.200 manu 2322 1.123 dholland pathbuf_destroy(pb); 2323 1.235 christos return error; 2324 1.116 dholland } 2325 1.116 dholland 2326 1.116 dholland int 2327 1.116 dholland namei_simple_user(const char *path, namei_simple_flags_t sflags, 2328 1.235 christos struct vnode **vp_ret) 2329 1.200 manu { 2330 1.236 riastrad 2331 1.200 manu return nameiat_simple_user(NULL, path, sflags, vp_ret); 2332 1.200 manu } 2333 1.200 manu 2334 1.200 manu int 2335 1.200 manu nameiat_simple_user(struct vnode *dvp, const char *path, 2336 1.235 christos namei_simple_flags_t sflags, struct vnode **vp_ret) 2337 1.116 dholland { 2338 1.123 dholland struct pathbuf *pb; 2339 1.235 christos int error; 2340 1.116 dholland 2341 1.235 christos error = pathbuf_copyin(path, &pb); 2342 1.235 christos if (error) 2343 1.235 christos return error; 2344 1.200 manu 2345 1.235 christos error = nameiat_simple(dvp, pb, sflags, vp_ret); 2346 1.200 manu 2347 1.123 dholland pathbuf_destroy(pb); 2348 1.235 christos return error; 2349 1.116 dholland } 2350