]> git.saurik.com Git - apple/xnu.git/blob - bsd/vfs/vfs_lookup.c
77c525baac8014c906286e7d6489e74aa51f3943
[apple/xnu.git] / bsd / vfs / vfs_lookup.c
1 /*
2 * Copyright (c) 2000-2015 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
29 /*
30 * Copyright (c) 1982, 1986, 1989, 1993
31 * The Regents of the University of California. All rights reserved.
32 * (c) UNIX System Laboratories, Inc.
33 * All or some portions of this file are derived from material licensed
34 * to the University of California by American Telephone and Telegraph
35 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
36 * the permission of UNIX System Laboratories, Inc.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 * must display the following acknowledgement:
48 * This product includes software developed by the University of
49 * California, Berkeley and its contributors.
50 * 4. Neither the name of the University nor the names of its contributors
51 * may be used to endorse or promote products derived from this software
52 * without specific prior written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE.
65 *
66 * @(#)vfs_lookup.c 8.10 (Berkeley) 5/27/95
67 */
68 /*
69 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
70 * support for mandatory and extensible security protections. This notice
71 * is included in support of clause 2.2 (b) of the Apple Public License,
72 * Version 2.0.
73 */
74
75 #include <sys/param.h>
76 #include <sys/systm.h>
77 #include <sys/syslimits.h>
78 #include <sys/time.h>
79 #include <sys/namei.h>
80 #include <sys/vm.h>
81 #include <sys/vnode_internal.h>
82 #include <sys/mount_internal.h>
83 #include <sys/errno.h>
84 #include <sys/malloc.h>
85 #include <sys/filedesc.h>
86 #include <sys/proc_internal.h>
87 #include <sys/kdebug.h>
88 #include <sys/unistd.h> /* For _PC_NAME_MAX */
89 #include <sys/uio_internal.h>
90 #include <sys/kauth.h>
91 #include <kern/kalloc.h>
92 #include <security/audit/audit.h>
93 #include <sys/dtrace.h> /* to get the prototype for strstr() in sys/dtrace_glue.h */
94 #if CONFIG_MACF
95 #include <security/mac_framework.h>
96 #endif
97
98 #include <sys/paths.h>
99
100 #if NAMEDRSRCFORK
101 #include <sys/xattr.h>
102 #endif
103 /*
104 * The minimum volfs-style pathname is 9.
105 * Example: "/.vol/1/2"
106 */
107 #define VOLFS_MIN_PATH_LEN 9
108
109
110 #if CONFIG_VOLFS
111 static int vfs_getrealpath(const char * path, char * realpath, size_t bufsize, vfs_context_t ctx);
112 #define MAX_VOLFS_RESTARTS 5
113 #endif
114
115 static int lookup_traverse_mountpoints(struct nameidata *ndp, struct componentname *cnp, vnode_t dp, int vbusyflags, vfs_context_t ctx);
116 static int handle_symlink_for_namei(struct nameidata *ndp, vnode_t *new_dp, vfs_context_t ctx);
117 static int lookup_authorize_search(vnode_t dp, struct componentname *cnp, int dp_authorized_in_cache, vfs_context_t ctx);
118 static void lookup_consider_update_cache(vnode_t dvp, vnode_t vp, struct componentname *cnp, int nc_generation);
119 static int lookup_handle_found_vnode(struct nameidata *ndp, struct componentname *cnp, int rdonly,
120 int vbusyflags, int *keep_going, int nc_generation,
121 int wantparent, int atroot, vfs_context_t ctx);
122 static int lookup_handle_emptyname(struct nameidata *ndp, struct componentname *cnp, int wantparent);
123
124 #if NAMEDRSRCFORK
125 static int lookup_handle_rsrc_fork(vnode_t dp, struct nameidata *ndp, struct componentname *cnp, int wantparent, vfs_context_t ctx);
126 #endif
127
128
129
130 /*
131 * Convert a pathname into a pointer to a locked inode.
132 *
133 * The FOLLOW flag is set when symbolic links are to be followed
134 * when they occur at the end of the name translation process.
135 * Symbolic links are always followed for all other pathname
136 * components other than the last.
137 *
138 * The segflg defines whether the name is to be copied from user
139 * space or kernel space.
140 *
141 * Overall outline of namei:
142 *
143 * copy in name
144 * get starting directory
145 * while (!done && !error) {
146 * call lookup to search path.
147 * if symbolic link, massage name in buffer and continue
148 * }
149 *
150 * Returns: 0 Success
151 * ENOENT No such file or directory
152 * ELOOP Too many levels of symbolic links
153 * ENAMETOOLONG Filename too long
154 * copyinstr:EFAULT Bad address
155 * copyinstr:ENAMETOOLONG Filename too long
156 * lookup:EBADF Bad file descriptor
157 * lookup:EROFS
158 * lookup:EACCES
159 * lookup:EPERM
160 * lookup:ERECYCLE vnode was recycled from underneath us in lookup.
161 * This means we should re-drive lookup from this point.
162 * lookup: ???
163 * VNOP_READLINK:???
164 */
165 int
166 namei(struct nameidata *ndp)
167 {
168 struct filedesc *fdp; /* pointer to file descriptor state */
169 struct vnode *dp; /* the directory we are searching */
170 struct vnode *rootdir_with_usecount = NULLVP;
171 struct vnode *startdir_with_usecount = NULLVP;
172 struct vnode *usedvp = ndp->ni_dvp; /* store pointer to vp in case we must loop due to
173 * heavy vnode pressure */
174 u_long cnpflags = ndp->ni_cnd.cn_flags; /* store in case we have to restore after loop */
175 int error;
176 struct componentname *cnp = &ndp->ni_cnd;
177 vfs_context_t ctx = cnp->cn_context;
178 proc_t p = vfs_context_proc(ctx);
179 #if CONFIG_AUDIT
180 /* XXX ut should be from context */
181 uthread_t ut = (struct uthread *)get_bsdthread_info(current_thread());
182 #endif
183
184 #if CONFIG_VOLFS
185 int volfs_restarts = 0;
186 #endif
187 size_t bytes_copied = 0;
188
189 fdp = p->p_fd;
190
191 #if DIAGNOSTIC
192 if (!vfs_context_ucred(ctx) || !p) {
193 panic("namei: bad cred/proc");
194 }
195 if (cnp->cn_nameiop & (~OPMASK)) {
196 panic("namei: nameiop contaminated with flags");
197 }
198 if (cnp->cn_flags & OPMASK) {
199 panic("namei: flags contaminated with nameiops");
200 }
201 #endif
202
203 /*
204 * A compound VNOP found something that needs further processing:
205 * either a trigger vnode, a covered directory, or a symlink.
206 */
207 if (ndp->ni_flag & NAMEI_CONTLOOKUP) {
208 int rdonly, vbusyflags, keep_going, wantparent;
209
210 rdonly = cnp->cn_flags & RDONLY;
211 vbusyflags = ((cnp->cn_flags & CN_NBMOUNTLOOK) != 0) ? LK_NOWAIT : 0;
212 keep_going = 0;
213 wantparent = cnp->cn_flags & (LOCKPARENT | WANTPARENT);
214
215 ndp->ni_flag &= ~(NAMEI_CONTLOOKUP);
216
217 error = lookup_handle_found_vnode(ndp, &ndp->ni_cnd, rdonly, vbusyflags,
218 &keep_going, ndp->ni_ncgeneration, wantparent, 0, ctx);
219 if (error) {
220 goto out_drop;
221 }
222 if (keep_going) {
223 if ((cnp->cn_flags & ISSYMLINK) == 0) {
224 panic("We need to keep going on a continued lookup, but for vp type %d (tag %d)\n", ndp->ni_vp->v_type, ndp->ni_vp->v_tag);
225 }
226 goto continue_symlink;
227 }
228
229 return 0;
230 }
231
232 vnode_recycled:
233
234 /*
235 * Get a buffer for the name to be translated, and copy the
236 * name into the buffer.
237 */
238 if ((cnp->cn_flags & HASBUF) == 0) {
239 cnp->cn_pnbuf = ndp->ni_pathbuf;
240 cnp->cn_pnlen = PATHBUFLEN;
241 }
242 #if LP64_DEBUG
243 if ((UIO_SEG_IS_USER_SPACE(ndp->ni_segflg) == 0)
244 && (ndp->ni_segflg != UIO_SYSSPACE)
245 && (ndp->ni_segflg != UIO_SYSSPACE32)) {
246 panic("%s :%d - invalid ni_segflg\n", __FILE__, __LINE__);
247 }
248 #endif /* LP64_DEBUG */
249
250 retry_copy:
251 if (UIO_SEG_IS_USER_SPACE(ndp->ni_segflg)) {
252 error = copyinstr(ndp->ni_dirp, cnp->cn_pnbuf,
253 cnp->cn_pnlen, &bytes_copied);
254 } else {
255 error = copystr(CAST_DOWN(void *, ndp->ni_dirp), cnp->cn_pnbuf,
256 cnp->cn_pnlen, &bytes_copied);
257 }
258 if (error == ENAMETOOLONG && !(cnp->cn_flags & HASBUF)) {
259 MALLOC_ZONE(cnp->cn_pnbuf, caddr_t, MAXPATHLEN, M_NAMEI, M_WAITOK);
260 if (cnp->cn_pnbuf == NULL) {
261 error = ENOMEM;
262 goto error_out;
263 }
264
265 cnp->cn_flags |= HASBUF;
266 cnp->cn_pnlen = MAXPATHLEN;
267 bytes_copied = 0;
268
269 goto retry_copy;
270 }
271 if (error) {
272 goto error_out;
273 }
274 ndp->ni_pathlen = bytes_copied;
275 bytes_copied = 0;
276
277 /*
278 * Since the name cache may contain positive entries of
279 * the incorrect case, force lookup() to bypass the cache
280 * and call directly into the filesystem for each path
281 * component. Note: the FS may still consult the cache,
282 * but can apply rules to validate the results.
283 */
284 if (proc_is_forcing_hfs_case_sensitivity(p)) {
285 cnp->cn_flags |= CN_SKIPNAMECACHE;
286 }
287
288 #if CONFIG_VOLFS
289 /*
290 * Check for legacy volfs style pathnames.
291 *
292 * For compatibility reasons we currently allow these paths,
293 * but future versions of the OS may not support them.
294 */
295 if (ndp->ni_pathlen >= VOLFS_MIN_PATH_LEN &&
296 cnp->cn_pnbuf[0] == '/' &&
297 cnp->cn_pnbuf[1] == '.' &&
298 cnp->cn_pnbuf[2] == 'v' &&
299 cnp->cn_pnbuf[3] == 'o' &&
300 cnp->cn_pnbuf[4] == 'l' &&
301 cnp->cn_pnbuf[5] == '/') {
302 char * realpath;
303 int realpath_err;
304 /* Attempt to resolve a legacy volfs style pathname. */
305 MALLOC_ZONE(realpath, caddr_t, MAXPATHLEN, M_NAMEI, M_WAITOK);
306 if (realpath) {
307 /*
308 * We only error out on the ENAMETOOLONG cases where we know that
309 * vfs_getrealpath translation succeeded but the path could not fit into
310 * MAXPATHLEN characters. In other failure cases, we may be dealing with a path
311 * that legitimately looks like /.vol/1234/567 and is not meant to be translated
312 */
313 if ((realpath_err = vfs_getrealpath(&cnp->cn_pnbuf[6], realpath, MAXPATHLEN, ctx))) {
314 FREE_ZONE(realpath, MAXPATHLEN, M_NAMEI);
315 if (realpath_err == ENOSPC || realpath_err == ENAMETOOLONG) {
316 error = ENAMETOOLONG;
317 goto error_out;
318 }
319 } else {
320 if (cnp->cn_flags & HASBUF) {
321 FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI);
322 }
323 cnp->cn_pnbuf = realpath;
324 cnp->cn_pnlen = MAXPATHLEN;
325 ndp->ni_pathlen = strlen(realpath) + 1;
326 cnp->cn_flags |= HASBUF | CN_VOLFSPATH;
327 }
328 }
329 }
330 #endif /* CONFIG_VOLFS */
331
332 #if CONFIG_AUDIT
333 /* If we are auditing the kernel pathname, save the user pathname */
334 if (cnp->cn_flags & AUDITVNPATH1) {
335 AUDIT_ARG(upath, ut->uu_cdir, cnp->cn_pnbuf, ARG_UPATH1);
336 }
337 if (cnp->cn_flags & AUDITVNPATH2) {
338 AUDIT_ARG(upath, ut->uu_cdir, cnp->cn_pnbuf, ARG_UPATH2);
339 }
340 #endif /* CONFIG_AUDIT */
341
342 /*
343 * Do not allow empty pathnames
344 */
345 if (*cnp->cn_pnbuf == '\0') {
346 error = ENOENT;
347 goto error_out;
348 }
349 ndp->ni_loopcnt = 0;
350
351 /*
352 * determine the starting point for the translation.
353 *
354 * We may need to upto 2 usecounts on vnodes before starting the translation
355 * We need to have a usecount on the root directory for the process
356 * for the entire duration of the lookup. This is because symlink
357 * translation can restart translation at / if a symlink is encountered.
358 *
359 * For the duration of this lookup at rootdir for this lookup is the one
360 * we fetch now under the proc_fdlock even the if the proc rootdir changes
361 * once we let go of the proc_fdlock.
362 *
363 * In the future we may consider holding off a chroot till we complete
364 * in progress lookups.
365 *
366 * If the starting directory is not the process rootdir then we need
367 * a usecount on the starting directory as well for the duration of the
368 * lookup.
369 *
370 * Getting an addtional usecount involves first getting an iocount under
371 * the lock that ensures that a usecount is on the directory. Once we
372 * get an iocount we can release the lock and we will be free to get a
373 * usecount without the vnode getting recycled. Once we get the usecount
374 * we can release the icoount which we used to get our usecount.
375 */
376 proc_fdlock(p);
377 if (!(fdp->fd_flags & FD_CHROOT)) {
378 ndp->ni_rootdir = rootvnode;
379 } else {
380 ndp->ni_rootdir = fdp->fd_rdir;
381 }
382
383 if (!ndp->ni_rootdir) {
384 if (!(fdp->fd_flags & FD_CHROOT)) {
385 proc_fdunlock(p);
386 printf("rootvnode is not set\n");
387 } else {
388 proc_fdunlock(p);
389 /* This should be a panic */
390 printf("fdp->fd_rdir is not set\n");
391 }
392 error = ENOENT;
393 goto error_out;
394 }
395
396 /*
397 * We have the proc_fdlock here so we still have a usecount
398 * on ndp->ni_rootdir.
399 *
400 * However we need to get our own usecount on it in order to
401 * ensure that the vnode isn't recycled to something else.
402 *
403 * Note : It's fine if the vnode is force reclaimed but with
404 * a usecount it won't be reused until we release the reference.
405 *
406 * In order to get that usecount however, we need to first
407 * get non blocking iocount since we'll be doing this under
408 * the proc_fdlock.
409 */
410 if (vnode_get(ndp->ni_rootdir) != 0) {
411 proc_fdunlock(p);
412 error = ENOENT;
413 goto error_out;
414 }
415
416 proc_fdunlock(p);
417
418 /* Now we can safely get our own ref on ni_rootdir */
419 error = vnode_ref_ext(ndp->ni_rootdir, O_EVTONLY, 0);
420 vnode_put(ndp->ni_rootdir);
421 if (error) {
422 ndp->ni_rootdir = NULLVP;
423 goto error_out;
424 }
425
426 rootdir_with_usecount = ndp->ni_rootdir;
427
428 cnp->cn_nameptr = cnp->cn_pnbuf;
429
430 ndp->ni_usedvp = NULLVP;
431
432 bool dp_needs_put = false;
433 if (*(cnp->cn_nameptr) == '/') {
434 while (*(cnp->cn_nameptr) == '/') {
435 cnp->cn_nameptr++;
436 ndp->ni_pathlen--;
437 }
438 dp = ndp->ni_rootdir;
439 } else if (cnp->cn_flags & USEDVP) {
440 dp = ndp->ni_dvp;
441 ndp->ni_usedvp = dp;
442 } else {
443 dp = vfs_context_get_cwd(ctx);
444 if (dp) {
445 dp_needs_put = true;
446 }
447 }
448
449 if (dp == NULLVP || (dp->v_lflag & VL_DEAD)) {
450 if (dp_needs_put) {
451 vnode_put(dp);
452 dp_needs_put = false;
453 }
454 dp = NULLVP;
455 error = ENOENT;
456 goto error_out;
457 }
458
459 if (dp != rootdir_with_usecount) {
460 error = vnode_ref_ext(dp, O_EVTONLY, 0);
461 if (error) {
462 if (dp_needs_put) {
463 vnode_put(dp);
464 dp_needs_put = false;
465 }
466 dp = NULLVP;
467 goto error_out;
468 }
469 startdir_with_usecount = dp;
470 }
471
472 if (dp_needs_put) {
473 vnode_put(dp);
474 dp_needs_put = false;
475 }
476
477 ndp->ni_dvp = NULLVP;
478 ndp->ni_vp = NULLVP;
479
480 for (;;) {
481 #if CONFIG_MACF
482 /*
483 * Give MACF policies a chance to reject the lookup
484 * before performing any filesystem operations.
485 * This hook is called before resolving the path and
486 * again each time a symlink is encountered.
487 * NB: policies receive path information as supplied
488 * by the caller and thus cannot be trusted.
489 */
490 error = mac_vnode_check_lookup_preflight(ctx, dp, cnp->cn_nameptr, cnp->cn_namelen);
491 if (error) {
492 goto error_out;
493 }
494 #endif
495
496 ndp->ni_startdir = dp;
497 dp = NULLVP;
498
499 if ((error = lookup(ndp))) {
500 goto error_out;
501 }
502
503 /*
504 * Check for symbolic link
505 */
506 if ((cnp->cn_flags & ISSYMLINK) == 0) {
507 if (startdir_with_usecount) {
508 vnode_rele_ext(startdir_with_usecount, O_EVTONLY, 0);
509 startdir_with_usecount = NULLVP;
510 }
511 if (rootdir_with_usecount) {
512 vnode_rele_ext(rootdir_with_usecount, O_EVTONLY, 0);
513 rootdir_with_usecount = NULLVP;
514 }
515 return 0;
516 }
517
518 continue_symlink:
519 /*
520 * Gives us a new path to process, and a starting dir (with an iocount).
521 * The iocount is needed to take a usecount on the vnode returned
522 * (if it is not a vnode we already have a usecount on).
523 */
524 error = handle_symlink_for_namei(ndp, &dp, ctx);
525 if (error != 0) {
526 break;
527 }
528
529 if (dp == ndp->ni_rootdir && startdir_with_usecount) {
530 vnode_rele_ext(startdir_with_usecount, O_EVTONLY, 0);
531 startdir_with_usecount = NULLVP;
532 } else if (dp != startdir_with_usecount) {
533 if (startdir_with_usecount) {
534 vnode_rele_ext(startdir_with_usecount, O_EVTONLY, 0);
535 startdir_with_usecount = NULLVP;
536 }
537 error = vnode_ref_ext(dp, O_EVTONLY, 0);
538 if (error) {
539 vnode_put(dp);
540 dp = NULLVP;
541 goto error_out;
542 }
543 startdir_with_usecount = dp;
544 }
545 /* iocount not required on dp anymore */
546 vnode_put(dp);
547 }
548 /*
549 * only come here if we fail to handle a SYMLINK...
550 * if either ni_dvp or ni_vp is non-NULL, then
551 * we need to drop the iocount that was picked
552 * up in the lookup routine
553 */
554 out_drop:
555 if (ndp->ni_dvp) {
556 vnode_put(ndp->ni_dvp);
557 }
558 if (ndp->ni_vp) {
559 vnode_put(ndp->ni_vp);
560 }
561 error_out:
562 if ((cnp->cn_flags & HASBUF)) {
563 cnp->cn_flags &= ~HASBUF;
564 FREE_ZONE(cnp->cn_pnbuf, cnp->cn_pnlen, M_NAMEI);
565 }
566 cnp->cn_pnbuf = NULL;
567 ndp->ni_vp = NULLVP;
568 ndp->ni_dvp = NULLVP;
569
570 if (startdir_with_usecount) {
571 vnode_rele_ext(startdir_with_usecount, O_EVTONLY, 0);
572 startdir_with_usecount = NULLVP;
573 }
574 if (rootdir_with_usecount) {
575 vnode_rele_ext(rootdir_with_usecount, O_EVTONLY, 0);
576 rootdir_with_usecount = NULLVP;
577 }
578
579 #if CONFIG_VOLFS
580 /*
581 * Deal with volfs fallout.
582 *
583 * At this point, if we were originally given a volfs path that
584 * looks like /.vol/123/456, then we would have had to convert it into
585 * a full path. Assuming that part worked properly, we will now attempt
586 * to conduct a lookup of the item in the namespace. Under normal
587 * circumstances, if a user looked up /tmp/foo and it was not there, it
588 * would be permissible to return ENOENT.
589 *
590 * However, we may not want to do that here. Specifically, the volfs path
591 * uniquely identifies a certain item in the namespace regardless of where it
592 * lives. If the item has moved in between the time we constructed the
593 * path and now, when we're trying to do a lookup/authorization on the full
594 * path, we may have gotten an ENOENT.
595 *
596 * At this point we can no longer tell if the path no longer exists
597 * or if the item in question no longer exists. It could have been renamed
598 * away, in which case the /.vol identifier is still valid.
599 *
600 * Do this dance a maximum of MAX_VOLFS_RESTARTS times.
601 */
602 if ((error == ENOENT) && (ndp->ni_cnd.cn_flags & CN_VOLFSPATH)) {
603 if (volfs_restarts < MAX_VOLFS_RESTARTS) {
604 volfs_restarts++;
605 goto vnode_recycled;
606 }
607 }
608 #endif
609
610 if (error == ERECYCLE) {
611 /* vnode was recycled underneath us. re-drive lookup to start at
612 * the beginning again, since recycling invalidated last lookup*/
613 ndp->ni_cnd.cn_flags = cnpflags;
614 ndp->ni_dvp = usedvp;
615 goto vnode_recycled;
616 }
617
618
619 return error;
620 }
621
622 int
623 namei_compound_available(vnode_t dp, struct nameidata *ndp)
624 {
625 if ((ndp->ni_flag & NAMEI_COMPOUNDOPEN) != 0) {
626 return vnode_compound_open_available(dp);
627 }
628
629 return 0;
630 }
631
632 static int
633 lookup_authorize_search(vnode_t dp, struct componentname *cnp, int dp_authorized_in_cache, vfs_context_t ctx)
634 {
635 #if !CONFIG_MACF
636 #pragma unused(cnp)
637 #endif
638
639 int error;
640
641 if (!dp_authorized_in_cache) {
642 error = vnode_authorize(dp, NULL, KAUTH_VNODE_SEARCH, ctx);
643 if (error) {
644 return error;
645 }
646 }
647 #if CONFIG_MACF
648 error = mac_vnode_check_lookup(ctx, dp, cnp);
649 if (error) {
650 return error;
651 }
652 #endif /* CONFIG_MACF */
653
654 return 0;
655 }
656
657 static void
658 lookup_consider_update_cache(vnode_t dvp, vnode_t vp, struct componentname *cnp, int nc_generation)
659 {
660 int isdot_or_dotdot;
661 isdot_or_dotdot = (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') || (cnp->cn_flags & ISDOTDOT);
662
663 if (vp->v_name == NULL || vp->v_parent == NULLVP) {
664 int update_flags = 0;
665
666 if (isdot_or_dotdot == 0) {
667 if (vp->v_name == NULL) {
668 update_flags |= VNODE_UPDATE_NAME;
669 }
670 if (dvp != NULLVP && vp->v_parent == NULLVP) {
671 update_flags |= VNODE_UPDATE_PARENT;
672 }
673
674 if (update_flags) {
675 vnode_update_identity(vp, dvp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_hash, update_flags);
676 }
677 }
678 }
679 if ((cnp->cn_flags & MAKEENTRY) && (vp->v_flag & VNCACHEABLE) && LIST_FIRST(&vp->v_nclinks) == NULL) {
680 /*
681 * missing from name cache, but should
682 * be in it... this can happen if volfs
683 * causes the vnode to be created or the
684 * name cache entry got recycled but the
685 * vnode didn't...
686 * check to make sure that ni_dvp is valid
687 * cache_lookup_path may return a NULL
688 * do a quick check to see if the generation of the
689 * directory matches our snapshot... this will get
690 * rechecked behind the name cache lock, but if it
691 * already fails to match, no need to go any further
692 */
693 if (dvp != NULLVP && (nc_generation == dvp->v_nc_generation) && (!isdot_or_dotdot)) {
694 cache_enter_with_gen(dvp, vp, cnp, nc_generation);
695 }
696 }
697 }
698
699 #if NAMEDRSRCFORK
700 /*
701 * Can change ni_dvp and ni_vp. On success, returns with iocounts on stream vnode (always) and
702 * data fork if requested. On failure, returns with iocount data fork (always) and its parent directory
703 * (if one was provided).
704 */
705 static int
706 lookup_handle_rsrc_fork(vnode_t dp, struct nameidata *ndp, struct componentname *cnp, int wantparent, vfs_context_t ctx)
707 {
708 vnode_t svp = NULLVP;
709 enum nsoperation nsop;
710 int nsflags;
711 int error;
712
713 if (dp->v_type != VREG) {
714 error = ENOENT;
715 goto out;
716 }
717 switch (cnp->cn_nameiop) {
718 case DELETE:
719 if (cnp->cn_flags & CN_ALLOWRSRCFORK) {
720 nsop = NS_DELETE;
721 } else {
722 error = EPERM;
723 goto out;
724 }
725 break;
726 case CREATE:
727 if (cnp->cn_flags & CN_ALLOWRSRCFORK) {
728 nsop = NS_CREATE;
729 } else {
730 error = EPERM;
731 goto out;
732 }
733 break;
734 case LOOKUP:
735 /* Make sure our lookup of "/..namedfork/rsrc" is allowed. */
736 if (cnp->cn_flags & CN_ALLOWRSRCFORK) {
737 nsop = NS_OPEN;
738 } else {
739 error = EPERM;
740 goto out;
741 }
742 break;
743 default:
744 error = EPERM;
745 goto out;
746 }
747
748 nsflags = 0;
749 if (cnp->cn_flags & CN_RAW_ENCRYPTED) {
750 nsflags |= NS_GETRAWENCRYPTED;
751 }
752
753 /* Ask the file system for the resource fork. */
754 error = vnode_getnamedstream(dp, &svp, XATTR_RESOURCEFORK_NAME, nsop, nsflags, ctx);
755
756 /* During a create, it OK for stream vnode to be missing. */
757 if (error == ENOATTR || error == ENOENT) {
758 error = (nsop == NS_CREATE) ? 0 : ENOENT;
759 }
760 if (error) {
761 goto out;
762 }
763 /* The "parent" of the stream is the file. */
764 if (wantparent) {
765 if (ndp->ni_dvp) {
766 vnode_put(ndp->ni_dvp);
767 }
768 ndp->ni_dvp = dp;
769 } else {
770 vnode_put(dp);
771 }
772 ndp->ni_vp = svp; /* on create this may be null */
773
774 /* Restore the truncated pathname buffer (for audits). */
775 if (ndp->ni_pathlen == 1 && ndp->ni_next[0] == '\0') {
776 /*
777 * While we replaced only '/' with '\0' and would ordinarily
778 * need to just switch that back, the buffer in which we did
779 * this may not be what the pathname buffer is now when symlinks
780 * are involved. If we just restore the "/" we will make the
781 * string not terminated anymore, so be safe and restore the
782 * entire suffix.
783 */
784 strncpy(ndp->ni_next, _PATH_RSRCFORKSPEC, sizeof(_PATH_RSRCFORKSPEC));
785 cnp->cn_nameptr = ndp->ni_next + 1;
786 cnp->cn_namelen = sizeof(_PATH_RSRCFORKSPEC) - 1;
787 ndp->ni_next += cnp->cn_namelen;
788 if (ndp->ni_next[0] != '\0') {
789 panic("Incorrect termination of path in %s", __FUNCTION__);
790 }
791 }
792 cnp->cn_flags &= ~MAKEENTRY;
793
794 return 0;
795 out:
796 return error;
797 }
798 #endif /* NAMEDRSRCFORK */
799
800 /*
801 * iocounts in:
802 * --One on ni_vp. One on ni_dvp if there is more path, or we didn't come through the
803 * cache, or we came through the cache and the caller doesn't want the parent.
804 *
805 * iocounts out:
806 * --Leaves us in the correct state for the next step, whatever that might be.
807 * --If we find a symlink, returns with iocounts on both ni_vp and ni_dvp.
808 * --If we are to look up another component, then we have an iocount on ni_vp and
809 * nothing else.
810 * --If we are done, returns an iocount on ni_vp, and possibly on ni_dvp depending on nameidata flags.
811 * --In the event of an error, may return with ni_dvp NULL'ed out (in which case, iocount
812 * was dropped).
813 */
814 static int
815 lookup_handle_found_vnode(struct nameidata *ndp, struct componentname *cnp, int rdonly,
816 int vbusyflags, int *keep_going, int nc_generation,
817 int wantparent, int atroot, vfs_context_t ctx)
818 {
819 vnode_t dp;
820 int error;
821 char *cp;
822
823 dp = ndp->ni_vp;
824 *keep_going = 0;
825
826 if (ndp->ni_vp == NULLVP) {
827 panic("NULL ni_vp in %s\n", __FUNCTION__);
828 }
829
830 if (atroot) {
831 goto nextname;
832 }
833
834 /*
835 * Take into account any additional components consumed by
836 * the underlying filesystem.
837 */
838 if (cnp->cn_consume > 0) {
839 cnp->cn_nameptr += cnp->cn_consume;
840 ndp->ni_next += cnp->cn_consume;
841 ndp->ni_pathlen -= cnp->cn_consume;
842 cnp->cn_consume = 0;
843 } else {
844 lookup_consider_update_cache(ndp->ni_dvp, dp, cnp, nc_generation);
845 }
846
847 /*
848 * Check to see if the vnode has been mounted on...
849 * if so find the root of the mounted file system.
850 * Updates ndp->ni_vp.
851 */
852 error = lookup_traverse_mountpoints(ndp, cnp, dp, vbusyflags, ctx);
853 dp = ndp->ni_vp;
854 if (error) {
855 goto out;
856 }
857
858 #if CONFIG_MACF
859 if (vfs_flags(vnode_mount(dp)) & MNT_MULTILABEL) {
860 error = vnode_label(vnode_mount(dp), NULL, dp, NULL, 0, ctx);
861 if (error) {
862 goto out;
863 }
864 }
865 #endif
866
867 /*
868 * Check for symbolic link
869 */
870 if ((dp->v_type == VLNK) &&
871 ((cnp->cn_flags & FOLLOW) || (ndp->ni_flag & NAMEI_TRAILINGSLASH) || *ndp->ni_next == '/')) {
872 cnp->cn_flags |= ISSYMLINK;
873 *keep_going = 1;
874 return 0;
875 }
876
877 /*
878 * Check for bogus trailing slashes.
879 */
880 if ((ndp->ni_flag & NAMEI_TRAILINGSLASH)) {
881 if (dp->v_type != VDIR) {
882 error = ENOTDIR;
883 goto out;
884 }
885 ndp->ni_flag &= ~(NAMEI_TRAILINGSLASH);
886 }
887
888 #if NAMEDSTREAMS
889 /*
890 * Deny namei/lookup requests to resolve paths that point to shadow files.
891 * Access to shadow files must be conducted by explicit calls to VNOP_LOOKUP
892 * directly, and not use lookup/namei
893 */
894 if (vnode_isshadow(dp)) {
895 error = ENOENT;
896 goto out;
897 }
898 #endif
899
900 nextname:
901 /*
902 * Not a symbolic link. If more pathname,
903 * continue at next component, else return.
904 *
905 * Definitely have a dvp if there's another slash
906 */
907 if (*ndp->ni_next == '/') {
908 cnp->cn_nameptr = ndp->ni_next + 1;
909 ndp->ni_pathlen--;
910 while (*cnp->cn_nameptr == '/') {
911 cnp->cn_nameptr++;
912 ndp->ni_pathlen--;
913 }
914
915 cp = cnp->cn_nameptr;
916 vnode_put(ndp->ni_dvp);
917 ndp->ni_dvp = NULLVP;
918
919 if (*cp == '\0') {
920 goto emptyname;
921 }
922
923 *keep_going = 1;
924 return 0;
925 }
926
927 /*
928 * Disallow directory write attempts on read-only file systems.
929 */
930 if (rdonly &&
931 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
932 error = EROFS;
933 goto out;
934 }
935
936 /* If SAVESTART is set, we should have a dvp */
937 if (cnp->cn_flags & SAVESTART) {
938 /*
939 * note that we already hold a reference
940 * on both dp and ni_dvp, but for some reason
941 * can't get another one... in this case we
942 * need to do vnode_put on dp in 'bad2'
943 */
944 if ((vnode_get(ndp->ni_dvp))) {
945 error = ENOENT;
946 goto out;
947 }
948 ndp->ni_startdir = ndp->ni_dvp;
949 }
950 if (!wantparent && ndp->ni_dvp) {
951 vnode_put(ndp->ni_dvp);
952 ndp->ni_dvp = NULLVP;
953 }
954
955 if (cnp->cn_flags & AUDITVNPATH1) {
956 AUDIT_ARG(vnpath, dp, ARG_VNODE1);
957 } else if (cnp->cn_flags & AUDITVNPATH2) {
958 AUDIT_ARG(vnpath, dp, ARG_VNODE2);
959 }
960
961 #if NAMEDRSRCFORK
962 /*
963 * Caller wants the resource fork.
964 */
965 if ((cnp->cn_flags & CN_WANTSRSRCFORK) && (dp != NULLVP)) {
966 error = lookup_handle_rsrc_fork(dp, ndp, cnp, wantparent, ctx);
967 if (error != 0) {
968 goto out;
969 }
970
971 dp = ndp->ni_vp;
972 }
973 #endif
974 if (kdebug_enable) {
975 kdebug_lookup(ndp->ni_vp, cnp);
976 }
977
978 return 0;
979
980 emptyname:
981 error = lookup_handle_emptyname(ndp, cnp, wantparent);
982 if (error != 0) {
983 goto out;
984 }
985
986 return 0;
987 out:
988 return error;
989 }
990
991 /*
992 * Comes in iocount on ni_vp. May overwrite ni_dvp, but doesn't interpret incoming value.
993 */
994 static int
995 lookup_handle_emptyname(struct nameidata *ndp, struct componentname *cnp, int wantparent)
996 {
997 vnode_t dp;
998 int error = 0;
999
1000 dp = ndp->ni_vp;
1001 cnp->cn_namelen = 0;
1002 /*
1003 * A degenerate name (e.g. / or "") which is a way of
1004 * talking about a directory, e.g. like "/." or ".".
1005 */
1006 if (dp->v_type != VDIR) {
1007 error = ENOTDIR;
1008 goto out;
1009 }
1010 if (cnp->cn_nameiop != LOOKUP) {
1011 error = EISDIR;
1012 goto out;
1013 }
1014 if (wantparent) {
1015 /*
1016 * note that we already hold a reference
1017 * on dp, but for some reason can't
1018 * get another one... in this case we
1019 * need to do vnode_put on dp in 'bad'
1020 */
1021 if ((vnode_get(dp))) {
1022 error = ENOENT;
1023 goto out;
1024 }
1025 ndp->ni_dvp = dp;
1026 }
1027 cnp->cn_flags &= ~ISDOTDOT;
1028 cnp->cn_flags |= ISLASTCN;
1029 ndp->ni_next = cnp->cn_nameptr;
1030 ndp->ni_vp = dp;
1031
1032 if (cnp->cn_flags & AUDITVNPATH1) {
1033 AUDIT_ARG(vnpath, dp, ARG_VNODE1);
1034 } else if (cnp->cn_flags & AUDITVNPATH2) {
1035 AUDIT_ARG(vnpath, dp, ARG_VNODE2);
1036 }
1037 if (cnp->cn_flags & SAVESTART) {
1038 panic("lookup: SAVESTART");
1039 }
1040
1041 return 0;
1042 out:
1043 return error;
1044 }
1045 /*
1046 * Search a pathname.
1047 * This is a very central and rather complicated routine.
1048 *
1049 * The pathname is pointed to by ni_ptr and is of length ni_pathlen.
1050 * The starting directory is taken from ni_startdir. The pathname is
1051 * descended until done, or a symbolic link is encountered. The variable
1052 * ni_more is clear if the path is completed; it is set to one if a
1053 * symbolic link needing interpretation is encountered.
1054 *
1055 * The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on
1056 * whether the name is to be looked up, created, renamed, or deleted.
1057 * When CREATE, RENAME, or DELETE is specified, information usable in
1058 * creating, renaming, or deleting a directory entry may be calculated.
1059 * If flag has LOCKPARENT or'ed into it, the parent directory is returned
1060 * locked. If flag has WANTPARENT or'ed into it, the parent directory is
1061 * returned unlocked. Otherwise the parent directory is not returned. If
1062 * the target of the pathname exists and LOCKLEAF is or'ed into the flag
1063 * the target is returned locked, otherwise it is returned unlocked.
1064 * When creating or renaming and LOCKPARENT is specified, the target may not
1065 * be ".". When deleting and LOCKPARENT is specified, the target may be ".".
1066 *
1067 * Overall outline of lookup:
1068 *
1069 * dirloop:
1070 * identify next component of name at ndp->ni_ptr
1071 * handle degenerate case where name is null string
1072 * if .. and crossing mount points and on mounted filesys, find parent
1073 * call VNOP_LOOKUP routine for next component name
1074 * directory vnode returned in ni_dvp, unlocked unless LOCKPARENT set
1075 * component vnode returned in ni_vp (if it exists), locked.
1076 * if result vnode is mounted on and crossing mount points,
1077 * find mounted on vnode
1078 * if more components of name, do next level at dirloop
1079 * return the answer in ni_vp, locked if LOCKLEAF set
1080 * if LOCKPARENT set, return locked parent in ni_dvp
1081 * if WANTPARENT set, return unlocked parent in ni_dvp
1082 *
1083 * Returns: 0 Success
1084 * ENOENT No such file or directory
1085 * EBADF Bad file descriptor
1086 * ENOTDIR Not a directory
1087 * EROFS Read-only file system [CREATE]
1088 * EISDIR Is a directory [CREATE]
1089 * cache_lookup_path:ERECYCLE (vnode was recycled from underneath us, redrive lookup again)
1090 * vnode_authorize:EROFS
1091 * vnode_authorize:EACCES
1092 * vnode_authorize:EPERM
1093 * vnode_authorize:???
1094 * VNOP_LOOKUP:ENOENT No such file or directory
1095 * VNOP_LOOKUP:EJUSTRETURN Restart system call (INTERNAL)
1096 * VNOP_LOOKUP:???
1097 * VFS_ROOT:ENOTSUP
1098 * VFS_ROOT:ENOENT
1099 * VFS_ROOT:???
1100 */
1101 int
1102 lookup(struct nameidata *ndp)
1103 {
1104 char *cp; /* pointer into pathname argument */
1105 vnode_t tdp; /* saved dp */
1106 vnode_t dp; /* the directory we are searching */
1107 int docache = 1; /* == 0 do not cache last component */
1108 int wantparent; /* 1 => wantparent or lockparent flag */
1109 int rdonly; /* lookup read-only flag bit */
1110 int dp_authorized = 0;
1111 int error = 0;
1112 struct componentname *cnp = &ndp->ni_cnd;
1113 vfs_context_t ctx = cnp->cn_context;
1114 int vbusyflags = 0;
1115 int nc_generation = 0;
1116 vnode_t last_dp = NULLVP;
1117 int keep_going;
1118 int atroot;
1119
1120 /*
1121 * Setup: break out flag bits into variables.
1122 */
1123 if (cnp->cn_flags & NOCACHE) {
1124 docache = 0;
1125 }
1126 wantparent = cnp->cn_flags & (LOCKPARENT | WANTPARENT);
1127 rdonly = cnp->cn_flags & RDONLY;
1128 cnp->cn_flags &= ~ISSYMLINK;
1129 cnp->cn_consume = 0;
1130
1131 dp = ndp->ni_startdir;
1132 ndp->ni_startdir = NULLVP;
1133
1134 if ((cnp->cn_flags & CN_NBMOUNTLOOK) != 0) {
1135 vbusyflags = LK_NOWAIT;
1136 }
1137 cp = cnp->cn_nameptr;
1138
1139 if (*cp == '\0') {
1140 if ((vnode_getwithref(dp))) {
1141 dp = NULLVP;
1142 error = ENOENT;
1143 goto bad;
1144 }
1145 ndp->ni_vp = dp;
1146 error = lookup_handle_emptyname(ndp, cnp, wantparent);
1147 if (error) {
1148 goto bad;
1149 }
1150
1151 return 0;
1152 }
1153 dirloop:
1154 atroot = 0;
1155 ndp->ni_vp = NULLVP;
1156
1157 if ((error = cache_lookup_path(ndp, cnp, dp, ctx, &dp_authorized, last_dp))) {
1158 dp = NULLVP;
1159 goto bad;
1160 }
1161 if ((cnp->cn_flags & ISLASTCN)) {
1162 if (docache) {
1163 cnp->cn_flags |= MAKEENTRY;
1164 }
1165 } else {
1166 cnp->cn_flags |= MAKEENTRY;
1167 }
1168
1169 dp = ndp->ni_dvp;
1170
1171 if (ndp->ni_vp != NULLVP) {
1172 /*
1173 * cache_lookup_path returned a non-NULL ni_vp then,
1174 * we're guaranteed that the dp is a VDIR, it's
1175 * been authorized, and vp is not ".."
1176 *
1177 * make sure we don't try to enter the name back into
1178 * the cache if this vp is purged before we get to that
1179 * check since we won't have serialized behind whatever
1180 * activity is occurring in the FS that caused the purge
1181 */
1182 if (dp != NULLVP) {
1183 nc_generation = dp->v_nc_generation - 1;
1184 }
1185
1186 goto returned_from_lookup_path;
1187 }
1188
1189 /*
1190 * Handle "..": two special cases.
1191 * 1. If at root directory (e.g. after chroot)
1192 * or at absolute root directory
1193 * then ignore it so can't get out.
1194 * 2. If this vnode is the root of a mounted
1195 * filesystem, then replace it with the
1196 * vnode which was mounted on so we take the
1197 * .. in the other file system.
1198 */
1199 if ((cnp->cn_flags & ISDOTDOT)) {
1200 /*
1201 * if this is a chroot'ed process, check if the current
1202 * directory is still a subdirectory of the process's
1203 * root directory.
1204 */
1205 if (ndp->ni_rootdir && (ndp->ni_rootdir != rootvnode) &&
1206 dp != ndp->ni_rootdir) {
1207 int sdir_error;
1208 int is_subdir = FALSE;
1209
1210 sdir_error = vnode_issubdir(dp, ndp->ni_rootdir,
1211 &is_subdir, vfs_context_kernel());
1212
1213 /*
1214 * If we couldn't determine if dp is a subdirectory of
1215 * ndp->ni_rootdir (sdir_error != 0), we let the request
1216 * proceed.
1217 */
1218 if (!sdir_error && !is_subdir) {
1219 vnode_put(dp);
1220 dp = ndp->ni_rootdir;
1221 /*
1222 * There's a ref on the process's root directory
1223 * but we can't use vnode_getwithref here as
1224 * there is nothing preventing that ref being
1225 * released by another thread.
1226 */
1227 if (vnode_get(dp)) {
1228 error = ENOENT;
1229 goto bad;
1230 }
1231 }
1232 }
1233
1234 for (;;) {
1235 if (dp == ndp->ni_rootdir || dp == rootvnode) {
1236 ndp->ni_dvp = dp;
1237 ndp->ni_vp = dp;
1238 /*
1239 * we're pinned at the root
1240 * we've already got one reference on 'dp'
1241 * courtesy of cache_lookup_path... take
1242 * another one for the ".."
1243 * if we fail to get the new reference, we'll
1244 * drop our original down in 'bad'
1245 */
1246 if ((vnode_get(dp))) {
1247 error = ENOENT;
1248 goto bad;
1249 }
1250 atroot = 1;
1251 goto returned_from_lookup_path;
1252 }
1253 if ((dp->v_flag & VROOT) == 0 ||
1254 (cnp->cn_flags & NOCROSSMOUNT)) {
1255 break;
1256 }
1257 if (dp->v_mount == NULL) { /* forced umount */
1258 error = EBADF;
1259 goto bad;
1260 }
1261 tdp = dp;
1262 dp = tdp->v_mount->mnt_vnodecovered;
1263
1264 if ((vnode_getwithref(dp))) {
1265 vnode_put(tdp);
1266 dp = NULLVP;
1267 error = ENOENT;
1268 goto bad;
1269 }
1270
1271 vnode_put(tdp);
1272
1273 ndp->ni_dvp = dp;
1274 dp_authorized = 0;
1275 }
1276 }
1277
1278 /*
1279 * We now have a segment name to search for, and a directory to search.
1280 */
1281 unionlookup:
1282 ndp->ni_vp = NULLVP;
1283
1284 if (dp->v_type != VDIR) {
1285 error = ENOTDIR;
1286 goto lookup_error;
1287 }
1288 if ((cnp->cn_flags & DONOTAUTH) != DONOTAUTH) {
1289 error = lookup_authorize_search(dp, cnp, dp_authorized, ctx);
1290 if (error) {
1291 goto lookup_error;
1292 }
1293 }
1294
1295 /*
1296 * Now that we've authorized a lookup, can bail out if the filesystem
1297 * will be doing a batched operation. Return an iocount on dvp.
1298 */
1299 #if NAMEDRSRCFORK
1300 if ((cnp->cn_flags & ISLASTCN) && namei_compound_available(dp, ndp) && !(cnp->cn_flags & CN_WANTSRSRCFORK)) {
1301 #else
1302 if ((cnp->cn_flags & ISLASTCN) && namei_compound_available(dp, ndp)) {
1303 #endif /* NAMEDRSRCFORK */
1304 ndp->ni_flag |= NAMEI_UNFINISHED;
1305 ndp->ni_ncgeneration = dp->v_nc_generation;
1306 return 0;
1307 }
1308
1309 nc_generation = dp->v_nc_generation;
1310
1311 /*
1312 * Note:
1313 * Filesystems that support hardlinks may want to call vnode_update_identity
1314 * if the lookup operation below will modify the in-core vnode to belong to a new point
1315 * in the namespace. VFS cannot infer whether or not the look up operation makes the vnode
1316 * name change or change parents. Without this, the lookup may make update
1317 * filesystem-specific in-core metadata but fail to update the v_parent or v_name
1318 * fields in the vnode. If VFS were to do this, it would be necessary to call
1319 * vnode_update_identity on every lookup operation -- expensive!
1320 *
1321 * However, even with this in place, multiple lookups may occur in between this lookup
1322 * and the subsequent vnop, so, at best, we could only guarantee that you would get a
1323 * valid path back, and not necessarily the one that you wanted.
1324 *
1325 * Example:
1326 * /tmp/a == /foo/b
1327 *
1328 * If you are now looking up /foo/b and the vnode for this link represents /tmp/a,
1329 * vnode_update_identity will fix the parentage so that you can get /foo/b back
1330 * through the v_parent chain (preventing you from getting /tmp/b back). It would
1331 * not fix whether or not you should or should not get /tmp/a vs. /foo/b.
1332 */
1333
1334 error = VNOP_LOOKUP(dp, &ndp->ni_vp, cnp, ctx);
1335
1336 if (error) {
1337 lookup_error:
1338 if ((error == ENOENT) &&
1339 (dp->v_mount != NULL) &&
1340 (dp->v_mount->mnt_flag & MNT_UNION)) {
1341 tdp = dp;
1342 error = lookup_traverse_union(tdp, &dp, ctx);
1343 vnode_put(tdp);
1344 if (error) {
1345 dp = NULLVP;
1346 goto bad;
1347 }
1348
1349 ndp->ni_dvp = dp;
1350 dp_authorized = 0;
1351 goto unionlookup;
1352 }
1353
1354 if (error != EJUSTRETURN) {
1355 goto bad;
1356 }
1357
1358 if (ndp->ni_vp != NULLVP) {
1359 panic("leaf should be empty");
1360 }
1361
1362 #if NAMEDRSRCFORK
1363 /*
1364 * At this point, error should be EJUSTRETURN.
1365 *
1366 * If CN_WANTSRSRCFORK is set, that implies that the
1367 * underlying filesystem could not find the "parent" of the
1368 * resource fork (the data fork), and we are doing a lookup
1369 * for a CREATE event.
1370 *
1371 * However, this should be converted to an error, as the
1372 * failure to find this parent should disallow further
1373 * progress to try and acquire a resource fork vnode.
1374 */
1375 if (cnp->cn_flags & CN_WANTSRSRCFORK) {
1376 error = ENOENT;
1377 goto bad;
1378 }
1379 #endif
1380
1381 error = lookup_validate_creation_path(ndp);
1382 if (error) {
1383 goto bad;
1384 }
1385 /*
1386 * We return with ni_vp NULL to indicate that the entry
1387 * doesn't currently exist, leaving a pointer to the
1388 * referenced directory vnode in ndp->ni_dvp.
1389 */
1390 if (cnp->cn_flags & SAVESTART) {
1391 if ((vnode_get(ndp->ni_dvp))) {
1392 error = ENOENT;
1393 goto bad;
1394 }
1395 ndp->ni_startdir = ndp->ni_dvp;
1396 }
1397 if (!wantparent) {
1398 vnode_put(ndp->ni_dvp);
1399 }
1400
1401 if (kdebug_enable) {
1402 kdebug_lookup(ndp->ni_dvp, cnp);
1403 }
1404 return 0;
1405 }
1406 returned_from_lookup_path:
1407 /* We'll always have an iocount on ni_vp when this finishes. */
1408 error = lookup_handle_found_vnode(ndp, cnp, rdonly, vbusyflags, &keep_going, nc_generation, wantparent, atroot, ctx);
1409 if (error != 0) {
1410 goto bad2;
1411 }
1412
1413 if (keep_going) {
1414 dp = ndp->ni_vp;
1415
1416 /* namei() will handle symlinks */
1417 if ((dp->v_type == VLNK) &&
1418 ((cnp->cn_flags & FOLLOW) || (ndp->ni_flag & NAMEI_TRAILINGSLASH) || *ndp->ni_next == '/')) {
1419 return 0;
1420 }
1421
1422 /*
1423 * Otherwise, there's more path to process.
1424 * cache_lookup_path is now responsible for dropping io ref on dp
1425 * when it is called again in the dirloop. This ensures we hold
1426 * a ref on dp until we complete the next round of lookup.
1427 */
1428 last_dp = dp;
1429
1430 goto dirloop;
1431 }
1432
1433 return 0;
1434 bad2:
1435 if (ndp->ni_dvp) {
1436 vnode_put(ndp->ni_dvp);
1437 }
1438
1439 vnode_put(ndp->ni_vp);
1440 ndp->ni_vp = NULLVP;
1441
1442 if (kdebug_enable) {
1443 kdebug_lookup(dp, cnp);
1444 }
1445 return error;
1446
1447 bad:
1448 if (dp) {
1449 vnode_put(dp);
1450 }
1451 ndp->ni_vp = NULLVP;
1452
1453 if (kdebug_enable) {
1454 kdebug_lookup(dp, cnp);
1455 }
1456 return error;
1457 }
1458
1459 /*
1460 * Given a vnode in a union mount, traverse to the equivalent
1461 * vnode in the underlying mount.
1462 */
1463 int
1464 lookup_traverse_union(vnode_t dvp, vnode_t *new_dvp, vfs_context_t ctx)
1465 {
1466 char *path = NULL, *pp;
1467 const char *name, *np;
1468 int len;
1469 int error = 0;
1470 struct nameidata nd;
1471 vnode_t vp = dvp;
1472
1473 *new_dvp = NULL;
1474
1475 if (vp && vp->v_flag & VROOT) {
1476 *new_dvp = vp->v_mount->mnt_vnodecovered;
1477 if (vnode_getwithref(*new_dvp)) {
1478 return ENOENT;
1479 }
1480 return 0;
1481 }
1482
1483 path = (char *) kalloc(MAXPATHLEN);
1484 if (path == NULL) {
1485 error = ENOMEM;
1486 goto done;
1487 }
1488
1489 /*
1490 * Walk back up to the mountpoint following the
1491 * v_parent chain and build a slash-separated path.
1492 * Then lookup that path starting with the covered vnode.
1493 */
1494 pp = path + (MAXPATHLEN - 1);
1495 *pp = '\0';
1496
1497 while (1) {
1498 name = vnode_getname(vp);
1499 if (name == NULL) {
1500 printf("lookup_traverse_union: null parent name: .%s\n", pp);
1501 error = ENOENT;
1502 goto done;
1503 }
1504 len = strlen(name);
1505 if ((len + 1) > (pp - path)) { // Enough space for this name ?
1506 error = ENAMETOOLONG;
1507 vnode_putname(name);
1508 goto done;
1509 }
1510 for (np = name + len; len > 0; len--) { // Copy name backwards
1511 *--pp = *--np;
1512 }
1513 vnode_putname(name);
1514 vp = vp->v_parent;
1515 if (vp == NULLVP || vp->v_flag & VROOT) {
1516 break;
1517 }
1518 *--pp = '/';
1519 }
1520
1521 /* Evaluate the path in the underlying mount */
1522 NDINIT(&nd, LOOKUP, OP_LOOKUP, USEDVP, UIO_SYSSPACE, CAST_USER_ADDR_T(pp), ctx);
1523 nd.ni_dvp = dvp->v_mount->mnt_vnodecovered;
1524 error = namei(&nd);
1525 if (error == 0) {
1526 *new_dvp = nd.ni_vp;
1527 }
1528 nameidone(&nd);
1529 done:
1530 if (path) {
1531 kfree(path, MAXPATHLEN);
1532 }
1533 return error;
1534 }
1535
1536 int
1537 lookup_validate_creation_path(struct nameidata *ndp)
1538 {
1539 struct componentname *cnp = &ndp->ni_cnd;
1540
1541 /*
1542 * If creating and at end of pathname, then can consider
1543 * allowing file to be created.
1544 */
1545 if (cnp->cn_flags & RDONLY) {
1546 return EROFS;
1547 }
1548 if ((cnp->cn_flags & ISLASTCN) && (ndp->ni_flag & NAMEI_TRAILINGSLASH) && !(cnp->cn_flags & WILLBEDIR)) {
1549 return ENOENT;
1550 }
1551
1552 return 0;
1553 }
1554
1555 /*
1556 * Modifies only ni_vp. Always returns with ni_vp still valid (iocount held).
1557 */
1558 static int
1559 lookup_traverse_mountpoints(struct nameidata *ndp, struct componentname *cnp, vnode_t dp,
1560 int vbusyflags, vfs_context_t ctx)
1561 {
1562 mount_t mp;
1563 vnode_t tdp;
1564 int error = 0;
1565 uint32_t depth = 0;
1566 vnode_t mounted_on_dp;
1567 int current_mount_generation = 0;
1568 #if CONFIG_TRIGGERS
1569 vnode_t triggered_dp = NULLVP;
1570 int retry_cnt = 0;
1571 #define MAX_TRIGGER_RETRIES 1
1572 #endif
1573
1574 if (dp->v_type != VDIR || cnp->cn_flags & NOCROSSMOUNT) {
1575 return 0;
1576 }
1577
1578 mounted_on_dp = dp;
1579 #if CONFIG_TRIGGERS
1580 restart:
1581 #endif
1582 current_mount_generation = mount_generation;
1583
1584 while (dp->v_mountedhere) {
1585 vnode_lock_spin(dp);
1586 if ((mp = dp->v_mountedhere)) {
1587 mp->mnt_crossref++;
1588 vnode_unlock(dp);
1589 } else {
1590 vnode_unlock(dp);
1591 break;
1592 }
1593
1594 if (ISSET(mp->mnt_lflag, MNT_LFORCE)) {
1595 mount_dropcrossref(mp, dp, 0);
1596 break; // don't traverse into a forced unmount
1597 }
1598
1599
1600 if (vfs_busy(mp, vbusyflags)) {
1601 mount_dropcrossref(mp, dp, 0);
1602 if (vbusyflags == LK_NOWAIT) {
1603 error = ENOENT;
1604 goto out;
1605 }
1606
1607 continue;
1608 }
1609
1610 error = VFS_ROOT(mp, &tdp, ctx);
1611
1612 mount_dropcrossref(mp, dp, 0);
1613 vfs_unbusy(mp);
1614
1615 if (error) {
1616 goto out;
1617 }
1618
1619 vnode_put(dp);
1620 ndp->ni_vp = dp = tdp;
1621 if (dp->v_type != VDIR) {
1622 #if DEVELOPMENT || DEBUG
1623 panic("%s : Root of filesystem not a directory\n",
1624 __FUNCTION__);
1625 #else
1626 break;
1627 #endif
1628 }
1629 depth++;
1630 }
1631
1632 #if CONFIG_TRIGGERS
1633 /*
1634 * The triggered_dp check here is required but is susceptible to a
1635 * (unlikely) race in which trigger mount is done from here and is
1636 * unmounted before we get past vfs_busy above. We retry to deal with
1637 * that case but it has the side effect of unwanted retries for
1638 * "special" processes which don't want to trigger mounts.
1639 */
1640 if (dp->v_resolve && retry_cnt < MAX_TRIGGER_RETRIES) {
1641 error = vnode_trigger_resolve(dp, ndp, ctx);
1642 if (error) {
1643 goto out;
1644 }
1645 if (dp == triggered_dp) {
1646 retry_cnt += 1;
1647 } else {
1648 retry_cnt = 0;
1649 }
1650 triggered_dp = dp;
1651 goto restart;
1652 }
1653 #endif /* CONFIG_TRIGGERS */
1654
1655 if (depth) {
1656 mp = mounted_on_dp->v_mountedhere;
1657
1658 if (mp) {
1659 mount_lock_spin(mp);
1660 mp->mnt_realrootvp_vid = dp->v_id;
1661 mp->mnt_realrootvp = dp;
1662 mp->mnt_generation = current_mount_generation;
1663 mount_unlock(mp);
1664 }
1665 }
1666
1667 return 0;
1668
1669 out:
1670 return error;
1671 }
1672
1673 /*
1674 * Takes ni_vp and ni_dvp non-NULL. Returns with *new_dp set to the location
1675 * at which to start a lookup with a resolved path and with an iocount.
1676 */
1677 static int
1678 handle_symlink_for_namei(struct nameidata *ndp, vnode_t *new_dp, vfs_context_t ctx)
1679 {
1680 int error;
1681 char *cp; /* pointer into pathname argument */
1682 uio_t auio;
1683 union {
1684 union {
1685 struct user_iovec s_uiovec;
1686 struct kern_iovec s_kiovec;
1687 } u_iovec;
1688 struct uio s_uio;
1689 char uio_buf[UIO_SIZEOF(1)];
1690 } u_uio_buf; /* union only for aligning uio_buf correctly */
1691 int need_newpathbuf;
1692 u_int linklen;
1693 struct componentname *cnp = &ndp->ni_cnd;
1694 vnode_t dp;
1695 char *tmppn;
1696 u_int rsrclen = (cnp->cn_flags & CN_WANTSRSRCFORK) ? sizeof(_PATH_RSRCFORKSPEC) : 0;
1697
1698 if (ndp->ni_loopcnt++ >= MAXSYMLINKS) {
1699 return ELOOP;
1700 }
1701 #if CONFIG_MACF
1702 if ((error = mac_vnode_check_readlink(ctx, ndp->ni_vp)) != 0) {
1703 return error;
1704 }
1705 #endif /* MAC */
1706 if (ndp->ni_pathlen > 1 || !(cnp->cn_flags & HASBUF)) {
1707 need_newpathbuf = 1;
1708 } else {
1709 need_newpathbuf = 0;
1710 }
1711
1712 if (need_newpathbuf) {
1713 MALLOC_ZONE(cp, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
1714 if (cp == NULL) {
1715 return ENOMEM;
1716 }
1717 } else {
1718 cp = cnp->cn_pnbuf;
1719 }
1720 auio = uio_createwithbuffer(1, 0, UIO_SYSSPACE, UIO_READ,
1721 &u_uio_buf.uio_buf[0], sizeof(u_uio_buf.uio_buf));
1722
1723 uio_addiov(auio, CAST_USER_ADDR_T(cp), MAXPATHLEN);
1724
1725 error = VNOP_READLINK(ndp->ni_vp, auio, ctx);
1726 if (error) {
1727 if (need_newpathbuf) {
1728 FREE_ZONE(cp, MAXPATHLEN, M_NAMEI);
1729 }
1730 return error;
1731 }
1732
1733 /*
1734 * Safe to set unsigned with a [larger] signed type here
1735 * because 0 <= uio_resid <= MAXPATHLEN and MAXPATHLEN
1736 * is only 1024.
1737 */
1738 linklen = MAXPATHLEN - (u_int)uio_resid(auio);
1739 if (linklen + ndp->ni_pathlen + rsrclen > MAXPATHLEN) {
1740 if (need_newpathbuf) {
1741 FREE_ZONE(cp, MAXPATHLEN, M_NAMEI);
1742 }
1743
1744 return ENAMETOOLONG;
1745 }
1746 if (need_newpathbuf) {
1747 long len = cnp->cn_pnlen;
1748
1749 tmppn = cnp->cn_pnbuf;
1750 bcopy(ndp->ni_next, cp + linklen, ndp->ni_pathlen);
1751 cnp->cn_pnbuf = cp;
1752 cnp->cn_pnlen = MAXPATHLEN;
1753
1754 if ((cnp->cn_flags & HASBUF)) {
1755 FREE_ZONE(tmppn, len, M_NAMEI);
1756 } else {
1757 cnp->cn_flags |= HASBUF;
1758 }
1759 } else {
1760 cnp->cn_pnbuf[linklen] = '\0';
1761 }
1762
1763 ndp->ni_pathlen += linklen;
1764 cnp->cn_nameptr = cnp->cn_pnbuf;
1765
1766 /*
1767 * starting point for 'relative'
1768 * symbolic link path
1769 *
1770 * If the starting point is not the root we have to return an iocounted
1771 * dp to namei so we don't release the icoount here.
1772 */
1773 dp = ndp->ni_dvp;
1774 ndp->ni_dvp = NULLVP;
1775
1776 /*
1777 * get rid of references returned via 'lookup'
1778 */
1779 vnode_put(ndp->ni_vp);
1780 ndp->ni_vp = NULLVP;
1781
1782 /*
1783 * Check if symbolic link restarts us at the root
1784 */
1785 if (*(cnp->cn_nameptr) == '/') {
1786 while (*(cnp->cn_nameptr) == '/') {
1787 cnp->cn_nameptr++;
1788 ndp->ni_pathlen--;
1789 }
1790 vnode_put(dp);
1791 if ((dp = ndp->ni_rootdir) == NULLVP) {
1792 return ENOENT;
1793 }
1794 if (vnode_get(dp) != 0) {
1795 return ENOENT;
1796 }
1797 }
1798
1799 if (dp == NULLVP || (dp->v_lflag & VL_DEAD)) {
1800 if (dp) {
1801 vnode_put(dp);
1802 }
1803 return ENOENT;
1804 }
1805
1806 *new_dp = dp;
1807
1808 return 0;
1809 }
1810
1811 /*
1812 * relookup - lookup a path name component
1813 * Used by lookup to re-aquire things.
1814 */
1815 int
1816 relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
1817 {
1818 struct vnode *dp = NULL; /* the directory we are searching */
1819 int wantparent; /* 1 => wantparent or lockparent flag */
1820 int rdonly; /* lookup read-only flag bit */
1821 int error = 0;
1822 #ifdef NAMEI_DIAGNOSTIC
1823 int i, newhash; /* DEBUG: check name hash */
1824 char *cp; /* DEBUG: check name ptr/len */
1825 #endif
1826 vfs_context_t ctx = cnp->cn_context;;
1827
1828 /*
1829 * Setup: break out flag bits into variables.
1830 */
1831 wantparent = cnp->cn_flags & (LOCKPARENT | WANTPARENT);
1832 rdonly = cnp->cn_flags & RDONLY;
1833 cnp->cn_flags &= ~ISSYMLINK;
1834
1835 if (cnp->cn_flags & NOCACHE) {
1836 cnp->cn_flags &= ~MAKEENTRY;
1837 } else {
1838 cnp->cn_flags |= MAKEENTRY;
1839 }
1840
1841 dp = dvp;
1842
1843 /*
1844 * Check for degenerate name (e.g. / or "")
1845 * which is a way of talking about a directory,
1846 * e.g. like "/." or ".".
1847 */
1848 if (cnp->cn_nameptr[0] == '\0') {
1849 if (cnp->cn_nameiop != LOOKUP || wantparent) {
1850 error = EISDIR;
1851 goto bad;
1852 }
1853 if (dp->v_type != VDIR) {
1854 error = ENOTDIR;
1855 goto bad;
1856 }
1857 if ((vnode_get(dp))) {
1858 error = ENOENT;
1859 goto bad;
1860 }
1861 *vpp = dp;
1862
1863 if (cnp->cn_flags & SAVESTART) {
1864 panic("lookup: SAVESTART");
1865 }
1866 return 0;
1867 }
1868 /*
1869 * We now have a segment name to search for, and a directory to search.
1870 */
1871 if ((error = VNOP_LOOKUP(dp, vpp, cnp, ctx))) {
1872 if (error != EJUSTRETURN) {
1873 goto bad;
1874 }
1875 #if DIAGNOSTIC
1876 if (*vpp != NULL) {
1877 panic("leaf should be empty");
1878 }
1879 #endif
1880 /*
1881 * If creating and at end of pathname, then can consider
1882 * allowing file to be created.
1883 */
1884 if (rdonly) {
1885 error = EROFS;
1886 goto bad;
1887 }
1888 /*
1889 * We return with ni_vp NULL to indicate that the entry
1890 * doesn't currently exist, leaving a pointer to the
1891 * (possibly locked) directory inode in ndp->ni_dvp.
1892 */
1893 return 0;
1894 }
1895 dp = *vpp;
1896
1897 #if DIAGNOSTIC
1898 /*
1899 * Check for symbolic link
1900 */
1901 if (dp->v_type == VLNK && (cnp->cn_flags & FOLLOW)) {
1902 panic("relookup: symlink found.\n");
1903 }
1904 #endif
1905
1906 /*
1907 * Disallow directory write attempts on read-only file systems.
1908 */
1909 if (rdonly &&
1910 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) {
1911 error = EROFS;
1912 goto bad2;
1913 }
1914 /* ASSERT(dvp == ndp->ni_startdir) */
1915
1916 return 0;
1917
1918 bad2:
1919 vnode_put(dp);
1920 bad:
1921 *vpp = NULL;
1922
1923 return error;
1924 }
1925
1926 /*
1927 * Free pathname buffer
1928 */
1929 void
1930 nameidone(struct nameidata *ndp)
1931 {
1932 if (ndp->ni_cnd.cn_flags & HASBUF) {
1933 char *tmp = ndp->ni_cnd.cn_pnbuf;
1934
1935 ndp->ni_cnd.cn_pnbuf = NULL;
1936 ndp->ni_cnd.cn_flags &= ~HASBUF;
1937 FREE_ZONE(tmp, ndp->ni_cnd.cn_pnlen, M_NAMEI);
1938 }
1939 }
1940
1941
1942 /*
1943 * Log (part of) a pathname using the KERNEL_DEBUG_CONSTANT mechanism, as used
1944 * by fs_usage. The path up to and including the current component name are
1945 * logged. Up to NUMPARMS*4 bytes of pathname will be logged. If the path
1946 * to be logged is longer than that, then the last NUMPARMS*4 bytes are logged.
1947 * That is, the truncation removes the leading portion of the path.
1948 *
1949 * The logging is done via multiple KERNEL_DEBUG_CONSTANT calls. The first one
1950 * is marked with DBG_FUNC_START. The last one is marked with DBG_FUNC_END
1951 * (in addition to DBG_FUNC_START if it is also the first). There may be
1952 * intermediate ones with neither DBG_FUNC_START nor DBG_FUNC_END.
1953 *
1954 * The first KERNEL_DEBUG_CONSTANT passes the vnode pointer and 12 bytes of
1955 * pathname. The remaining KERNEL_DEBUG_CONSTANT calls add 16 bytes of pathname
1956 * each. The minimum number of KERNEL_DEBUG_CONSTANT calls required to pass
1957 * the path are used. Any excess padding in the final KERNEL_DEBUG_CONSTANT
1958 * (because not all of the 12 or 16 bytes are needed for the remainder of the
1959 * path) is set to zero bytes, or '>' if there is more path beyond the
1960 * current component name (usually because an intermediate component was not
1961 * found).
1962 *
1963 * NOTE: If the path length is greater than NUMPARMS*4, or is not of the form
1964 * 12+N*16, there will be no padding.
1965 *
1966 * TODO: If there is more path beyond the current component name, should we
1967 * force some padding? For example, a lookup for /foo_bar_baz/spam that
1968 * fails because /foo_bar_baz is not found will only log "/foo_bar_baz", with
1969 * no '>' padding. But /foo_bar/spam would log "/foo_bar>>>>".
1970 */
1971 #if (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST)
1972
1973 void
1974 kdebug_vfs_lookup(long *dbg_parms, int dbg_namelen, void *dp, uint32_t flags)
1975 {
1976 int code;
1977 unsigned int i;
1978 bool lookup = flags & KDBG_VFS_LOOKUP_FLAG_LOOKUP;
1979 bool noprocfilt = flags & KDBG_VFS_LOOKUP_FLAG_NOPROCFILT;
1980
1981 /*
1982 * In the event that we collect multiple, consecutive pathname
1983 * entries, we must mark the start of the path's string and the end.
1984 */
1985 if (lookup) {
1986 code = VFS_LOOKUP | DBG_FUNC_START;
1987 } else {
1988 code = VFS_LOOKUP_DONE | DBG_FUNC_START;
1989 }
1990
1991 if (dbg_namelen <= (int)(3 * sizeof(long))) {
1992 code |= DBG_FUNC_END;
1993 }
1994
1995 if (noprocfilt) {
1996 KDBG_RELEASE_NOPROCFILT(code, kdebug_vnode(dp), dbg_parms[0],
1997 dbg_parms[1], dbg_parms[2]);
1998 } else {
1999 KDBG_RELEASE(code, kdebug_vnode(dp), dbg_parms[0], dbg_parms[1],
2000 dbg_parms[2]);
2001 }
2002
2003 code &= ~DBG_FUNC_START;
2004
2005 for (i = 3, dbg_namelen -= (3 * sizeof(long)); dbg_namelen > 0; i += 4, dbg_namelen -= (4 * sizeof(long))) {
2006 if (dbg_namelen <= (int)(4 * sizeof(long))) {
2007 code |= DBG_FUNC_END;
2008 }
2009
2010 if (noprocfilt) {
2011 KDBG_RELEASE_NOPROCFILT(code, dbg_parms[i], dbg_parms[i + 1],
2012 dbg_parms[i + 2], dbg_parms[i + 3]);
2013 } else {
2014 KDBG_RELEASE(code, dbg_parms[i], dbg_parms[i + 1], dbg_parms[i + 2],
2015 dbg_parms[i + 3]);
2016 }
2017 }
2018 }
2019
2020 void
2021 kdebug_lookup_gen_events(long *dbg_parms, int dbg_namelen, void *dp,
2022 bool lookup)
2023 {
2024 kdebug_vfs_lookup(dbg_parms, dbg_namelen, dp,
2025 lookup ? KDBG_VFS_LOOKUP_FLAG_LOOKUP : 0);
2026 }
2027
2028 void
2029 kdebug_lookup(vnode_t dp, struct componentname *cnp)
2030 {
2031 int dbg_namelen;
2032 char *dbg_nameptr;
2033 long dbg_parms[NUMPARMS];
2034
2035 /* Collect the pathname for tracing */
2036 dbg_namelen = (cnp->cn_nameptr - cnp->cn_pnbuf) + cnp->cn_namelen;
2037 dbg_nameptr = cnp->cn_nameptr + cnp->cn_namelen;
2038
2039 if (dbg_namelen > (int)sizeof(dbg_parms)) {
2040 dbg_namelen = sizeof(dbg_parms);
2041 }
2042 dbg_nameptr -= dbg_namelen;
2043
2044 /* Copy the (possibly truncated) path itself */
2045 memcpy(dbg_parms, dbg_nameptr, dbg_namelen);
2046
2047 /* Pad with '\0' or '>' */
2048 if (dbg_namelen < (int)sizeof(dbg_parms)) {
2049 memset((char *)dbg_parms + dbg_namelen,
2050 *(cnp->cn_nameptr + cnp->cn_namelen) ? '>' : 0,
2051 sizeof(dbg_parms) - dbg_namelen);
2052 }
2053 kdebug_vfs_lookup(dbg_parms, dbg_namelen, (void *)dp,
2054 KDBG_VFS_LOOKUP_FLAG_LOOKUP);
2055 }
2056
2057 #else /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */
2058
2059 void
2060 kdebug_vfs_lookup(long *dbg_parms __unused, int dbg_namelen __unused,
2061 void *dp __unused, __unused uint32_t flags)
2062 {
2063 }
2064
2065 static void
2066 kdebug_lookup(struct vnode *dp __unused, struct componentname *cnp __unused)
2067 {
2068 }
2069 #endif /* (KDEBUG_LEVEL >= KDEBUG_LEVEL_IST) */
2070
2071 int
2072 vfs_getbyid(fsid_t *fsid, ino64_t ino, vnode_t *vpp, vfs_context_t ctx)
2073 {
2074 mount_t mp;
2075 int error;
2076
2077 mp = mount_lookupby_volfsid(fsid->val[0], 1);
2078 if (mp == NULL) {
2079 return EINVAL;
2080 }
2081
2082 /* Get the target vnode. */
2083 if (ino == 2) {
2084 error = VFS_ROOT(mp, vpp, ctx);
2085 } else {
2086 error = VFS_VGET(mp, ino, vpp, ctx);
2087 }
2088
2089 vfs_unbusy(mp);
2090 return error;
2091 }
2092 /*
2093 * Obtain the real path from a legacy volfs style path.
2094 *
2095 * Valid formats of input path:
2096 *
2097 * "555/@"
2098 * "555/2"
2099 * "555/123456"
2100 * "555/123456/foobar"
2101 *
2102 * Where:
2103 * 555 represents the volfs file system id
2104 * '@' and '2' are aliases to the root of a file system
2105 * 123456 represents a file id
2106 * "foobar" represents a file name
2107 */
2108 #if CONFIG_VOLFS
2109 static int
2110 vfs_getrealpath(const char * path, char * realpath, size_t bufsize, vfs_context_t ctx)
2111 {
2112 vnode_t vp;
2113 struct mount *mp = NULL;
2114 char *str;
2115 char ch;
2116 uint32_t id;
2117 ino64_t ino;
2118 int error;
2119 int length;
2120
2121 /* Get file system id and move str to next component. */
2122 id = strtoul(path, &str, 10);
2123 if (id == 0 || str[0] != '/') {
2124 return EINVAL;
2125 }
2126 while (*str == '/') {
2127 str++;
2128 }
2129 ch = *str;
2130
2131 mp = mount_lookupby_volfsid(id, 1);
2132 if (mp == NULL) {
2133 return EINVAL; /* unexpected failure */
2134 }
2135 /* Check for an alias to a file system root. */
2136 if (ch == '@' && str[1] == '\0') {
2137 ino = 2;
2138 str++;
2139 } else {
2140 /* Get file id and move str to next component. */
2141 ino = strtouq(str, &str, 10);
2142 }
2143
2144 /* Get the target vnode. */
2145 if (ino == 2) {
2146 struct vfs_attr vfsattr;
2147 int use_vfs_root = TRUE;
2148
2149 VFSATTR_INIT(&vfsattr);
2150 VFSATTR_WANTED(&vfsattr, f_capabilities);
2151 if (vfs_getattr(mp, &vfsattr, vfs_context_kernel()) == 0 &&
2152 VFSATTR_IS_SUPPORTED(&vfsattr, f_capabilities)) {
2153 if ((vfsattr.f_capabilities.capabilities[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_VOL_GROUPS) &&
2154 (vfsattr.f_capabilities.valid[VOL_CAPABILITIES_FORMAT] & VOL_CAP_FMT_VOL_GROUPS)) {
2155 use_vfs_root = FALSE;
2156 }
2157 }
2158
2159 if (use_vfs_root) {
2160 error = VFS_ROOT(mp, &vp, ctx);
2161 } else {
2162 error = VFS_VGET(mp, ino, &vp, ctx);
2163 }
2164 } else {
2165 error = VFS_VGET(mp, ino, &vp, ctx);
2166 }
2167 vfs_unbusy(mp);
2168 if (error) {
2169 goto out;
2170 }
2171 realpath[0] = '\0';
2172
2173 /* Get the absolute path to this vnode. */
2174 error = build_path(vp, realpath, bufsize, &length, 0, ctx);
2175 vnode_put(vp);
2176
2177 if (error == 0 && *str != '\0') {
2178 int attempt = strlcat(realpath, str, MAXPATHLEN);
2179 if (attempt > MAXPATHLEN) {
2180 error = ENAMETOOLONG;
2181 }
2182 }
2183 out:
2184 return error;
2185 }
2186 #endif
2187
2188 void
2189 lookup_compound_vnop_post_hook(int error, vnode_t dvp, vnode_t vp, struct nameidata *ndp, int did_create)
2190 {
2191 if (error == 0 && vp == NULLVP) {
2192 panic("NULL vp with error == 0.\n");
2193 }
2194
2195 /*
2196 * We don't want to do any of this if we didn't use the compound vnop
2197 * to perform the lookup... i.e. if we're allowing and using the legacy pattern,
2198 * where we did a full lookup.
2199 */
2200 if ((ndp->ni_flag & NAMEI_COMPOUND_OP_MASK) == 0) {
2201 return;
2202 }
2203
2204 /*
2205 * If we're going to continue the lookup, we'll handle
2206 * all lookup-related updates at that time.
2207 */
2208 if (error == EKEEPLOOKING) {
2209 return;
2210 }
2211
2212 /*
2213 * Only audit or update cache for *found* vnodes. For creation
2214 * neither would happen in the non-compound-vnop case.
2215 */
2216 if ((vp != NULLVP) && !did_create) {
2217 /*
2218 * If MAKEENTRY isn't set, and we've done a successful compound VNOP,
2219 * then we certainly don't want to update cache or identity.
2220 */
2221 if ((error != 0) || (ndp->ni_cnd.cn_flags & MAKEENTRY)) {
2222 lookup_consider_update_cache(dvp, vp, &ndp->ni_cnd, ndp->ni_ncgeneration);
2223 }
2224 if (ndp->ni_cnd.cn_flags & AUDITVNPATH1) {
2225 AUDIT_ARG(vnpath, vp, ARG_VNODE1);
2226 } else if (ndp->ni_cnd.cn_flags & AUDITVNPATH2) {
2227 AUDIT_ARG(vnpath, vp, ARG_VNODE2);
2228 }
2229 }
2230
2231 /*
2232 * If you created (whether you opened or not), cut a lookup tracepoint
2233 * for the parent dir (as would happen without a compound vnop). Note: we may need
2234 * a vnode despite failure in this case!
2235 *
2236 * If you did not create:
2237 * Found child (succeeded or not): cut a tracepoint for the child.
2238 * Did not find child: cut a tracepoint with the parent.
2239 */
2240 if (kdebug_enable) {
2241 kdebug_lookup(vp ? vp : dvp, &ndp->ni_cnd);
2242 }
2243 }