genfs_rename.c revision 1.5 1 /* $NetBSD: genfs_rename.c,v 1.5 2020/09/05 02:47:03 riastradh Exp $ */
2
3 /*-
4 * Copyright (c) 2012 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Taylor R Campbell.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Generic rename abstraction.
34 *
35 * Rename is unbelievably hairy. Try to use this if you can --
36 * otherwise you are practically guaranteed to get it wrong.
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: genfs_rename.c,v 1.5 2020/09/05 02:47:03 riastradh Exp $");
41
42 #include <sys/param.h>
43 #include <sys/kauth.h>
44 #include <sys/mount.h>
45 #include <sys/namei.h>
46 #include <sys/stat.h>
47 #include <sys/vnode.h>
48 #include <sys/types.h>
49
50 #include <miscfs/genfs/genfs.h>
51
52 /*
53 * Sample copypasta for implementing VOP_RENAME via genfs_rename.
54 * Don't change this template without carefully considering whether
55 * every other file system that already uses it needs to change too.
56 * That way, once we have changed all the file systems to use it, we
57 * can easily replace mumblefs_rename by mumblefs_sane_rename and
58 * eliminate the insane API altogether.
59 */
60
61 /* begin sample copypasta */
62 #if 0
63
64 static const struct genfs_rename_ops mumblefs_genfs_rename_ops;
65
66 /*
67 * mumblefs_sane_rename: The hairiest vop, with the saner API.
68 *
69 * Arguments:
70 *
71 * . fdvp (from directory vnode),
72 * . fcnp (from component name),
73 * . tdvp (to directory vnode),
74 * . tcnp (to component name),
75 * . cred (credentials structure), and
76 * . posixly_correct (flag for behaviour if target & source link same file).
77 *
78 * fdvp and tdvp may be the same, and must be referenced and unlocked.
79 */
80 static int
81 mumblefs_sane_rename(
82 struct vnode *fdvp, struct componentname *fcnp,
83 struct vnode *tdvp, struct componentname *tcnp,
84 kauth_cred_t cred, bool posixly_correct)
85 {
86 struct mumblefs_lookup_results fulr, tulr;
87
88 return genfs_sane_rename(&mumblefs_genfs_rename_ops,
89 fdvp, fcnp, &fulr, tdvp, tcnp, &tulr,
90 cred, posixly_correct);
91 }
92
93 /*
94 * mumblefs_rename: The hairiest vop, with the insanest API. Defer to
95 * genfs_insane_rename immediately.
96 */
97 int
98 mumblefs_rename(void *v)
99 {
100
101 return genfs_insane_rename(v, &mumblefs_sane_rename);
102 }
103
104 #endif
105 /* end sample copypasta */
106
107 /*
108 * Forward declarations
109 */
110
111 static int genfs_rename_enter(const struct genfs_rename_ops *, struct mount *,
112 kauth_cred_t,
113 struct vnode *, struct componentname *, void *, struct vnode **,
114 struct vnode *, struct componentname *, void *, struct vnode **);
115 static int genfs_rename_enter_common(const struct genfs_rename_ops *,
116 struct mount *, kauth_cred_t, struct vnode *,
117 struct componentname *, void *, struct vnode **,
118 struct componentname *, void *, struct vnode **);
119 static int genfs_rename_enter_separate(const struct genfs_rename_ops *,
120 struct mount *, kauth_cred_t,
121 struct vnode *, struct componentname *, void *, struct vnode **,
122 struct vnode *, struct componentname *, void *, struct vnode **);
123 static int genfs_rename_lock(const struct genfs_rename_ops *, struct mount *,
124 kauth_cred_t, int, int, int,
125 struct vnode *, struct componentname *, bool, void *, struct vnode **,
126 struct vnode *, struct componentname *, bool, void *, struct vnode **);
127 static void genfs_rename_exit(const struct genfs_rename_ops *, struct mount *,
128 struct vnode *, struct vnode *,
129 struct vnode *, struct vnode *);
130 static int genfs_rename_remove(const struct genfs_rename_ops *, struct mount *,
131 kauth_cred_t,
132 struct vnode *, struct componentname *, void *, struct vnode *);
133
134 /*
135 * genfs_insane_rename: Generic implementation of the insane API for
136 * the rename vop.
137 *
138 * Arguments:
139 *
140 * . fdvp (from directory vnode),
141 * . fvp (from vnode),
142 * . fcnp (from component name),
143 * . tdvp (to directory vnode),
144 * . tvp (to vnode, or NULL), and
145 * . tcnp (to component name).
146 *
147 * Any pair of vnode parameters may have the same vnode.
148 *
149 * On entry,
150 *
151 * . fdvp, fvp, tdvp, and tvp are referenced,
152 * . fdvp and fvp are unlocked, and
153 * . tdvp and tvp (if nonnull) are locked.
154 *
155 * On exit,
156 *
157 * . fdvp, fvp, tdvp, and tvp (if nonnull) are unreferenced, and
158 * . tdvp and tvp (if nonnull) are unlocked.
159 */
160 int
161 genfs_insane_rename(void *v,
162 int (*sane_rename)(struct vnode *fdvp, struct componentname *fcnp,
163 struct vnode *tdvp, struct componentname *tcnp,
164 kauth_cred_t cred, bool posixly_correct))
165 {
166 struct vop_rename_args /* {
167 struct vnode *a_fdvp;
168 struct vnode *a_fvp;
169 struct componentname *a_fcnp;
170 struct vnode *a_tdvp;
171 struct vnode *a_tvp;
172 struct componentname *a_tcnp;
173 } */ *ap = v;
174 struct vnode *fdvp = ap->a_fdvp;
175 struct vnode *fvp = ap->a_fvp;
176 struct componentname *fcnp = ap->a_fcnp;
177 struct vnode *tdvp = ap->a_tdvp;
178 struct vnode *tvp = ap->a_tvp;
179 struct componentname *tcnp = ap->a_tcnp;
180 kauth_cred_t cred;
181 int error;
182
183 KASSERT(fdvp != NULL);
184 KASSERT(fvp != NULL);
185 KASSERT(fcnp != NULL);
186 KASSERT(fcnp->cn_nameptr != NULL);
187 KASSERT(tdvp != NULL);
188 KASSERT(tcnp != NULL);
189 KASSERT(fcnp->cn_nameptr != NULL);
190 /* KASSERT(VOP_ISLOCKED(fdvp) != LK_EXCLUSIVE); */
191 /* KASSERT(VOP_ISLOCKED(fvp) != LK_EXCLUSIVE); */
192 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE);
193 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE));
194 KASSERT(fdvp->v_type == VDIR);
195 KASSERT(tdvp->v_type == VDIR);
196
197 cred = fcnp->cn_cred;
198
199 /*
200 * XXX Want a better equality test. `tcnp->cn_cred == cred'
201 * hoses p2k because puffs transmits the creds separately and
202 * allocates distinct but equivalent structures for them.
203 */
204 KASSERT(kauth_cred_uidmatch(cred, tcnp->cn_cred));
205
206 /*
207 * Sanitize our world from the VFS insanity. Unlock the target
208 * directory and node, which are locked. Release the children,
209 * which are referenced, since we'll be looking them up again
210 * later.
211 */
212
213 VOP_UNLOCK(tdvp);
214 if ((tvp != NULL) && (tvp != tdvp))
215 VOP_UNLOCK(tvp);
216
217 vrele(fvp);
218 if (tvp != NULL)
219 vrele(tvp);
220
221 error = (*sane_rename)(fdvp, fcnp, tdvp, tcnp, cred, false);
222
223 /*
224 * All done, whether with success or failure. Release the
225 * directory nodes now, as the caller expects from the VFS
226 * protocol.
227 */
228 vrele(fdvp);
229 vrele(tdvp);
230
231 return error;
232 }
233
234 /*
235 * genfs_sane_rename: Generic implementation of the saner API for the
236 * rename vop. Handles ancestry checks, locking, and permissions
237 * checks. Caller is responsible for implementing the genfs rename
238 * operations.
239 *
240 * fdvp and tdvp must be referenced and unlocked.
241 */
242 int
243 genfs_sane_rename(const struct genfs_rename_ops *ops,
244 struct vnode *fdvp, struct componentname *fcnp, void *fde,
245 struct vnode *tdvp, struct componentname *tcnp, void *tde,
246 kauth_cred_t cred, bool posixly_correct)
247 {
248 struct mount *mp;
249 struct vnode *fvp = NULL, *tvp = NULL;
250 int error;
251
252 KASSERT(ops != NULL);
253 KASSERT(fdvp != NULL);
254 KASSERT(fcnp != NULL);
255 KASSERT(tdvp != NULL);
256 KASSERT(tcnp != NULL);
257 /* KASSERT(VOP_ISLOCKED(fdvp) != LK_EXCLUSIVE); */
258 /* KASSERT(VOP_ISLOCKED(tdvp) != LK_EXCLUSIVE); */
259 KASSERT(fdvp->v_type == VDIR);
260 KASSERT(tdvp->v_type == VDIR);
261 KASSERT(fdvp->v_mount == tdvp->v_mount);
262 KASSERT(fcnp != tcnp);
263 KASSERT(fcnp->cn_nameiop == DELETE);
264 KASSERT(tcnp->cn_nameiop == RENAME);
265
266 /* XXX Want a better equality test. */
267 KASSERT(kauth_cred_uidmatch(cred, fcnp->cn_cred));
268 KASSERT(kauth_cred_uidmatch(cred, tcnp->cn_cred));
269
270 mp = fdvp->v_mount;
271 KASSERT(mp != NULL);
272 KASSERT(mp == tdvp->v_mount);
273 /* XXX How can we be sure this stays true? */
274 KASSERT((mp->mnt_flag & MNT_RDONLY) == 0);
275
276 /* Reject rename("x/..", ...) and rename(..., "x/..") early. */
277 if ((fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT)
278 return EINVAL; /* XXX EISDIR? */
279
280 error = genfs_rename_enter(ops, mp, cred,
281 fdvp, fcnp, fde, &fvp,
282 tdvp, tcnp, tde, &tvp);
283 if (error)
284 return error;
285
286 /*
287 * Check that everything is locked and looks right.
288 */
289 KASSERT(fvp != NULL);
290 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE);
291 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE);
292 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE);
293 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE));
294
295 /*
296 * If the source and destination are the same object, we need
297 * only at most delete the source entry. We are guaranteed at
298 * this point that the entries are distinct.
299 */
300 if (fvp == tvp) {
301 KASSERT(tvp != NULL);
302 if (fvp->v_type == VDIR)
303 /* XXX This shouldn't be possible. */
304 error = EINVAL;
305 else if (posixly_correct)
306 /* POSIX sez to leave them alone. */
307 error = 0;
308 else if ((fdvp == tdvp) &&
309 (fcnp->cn_namelen == tcnp->cn_namelen) &&
310 (memcmp(fcnp->cn_nameptr, tcnp->cn_nameptr,
311 fcnp->cn_namelen) == 0))
312 /* Renaming an entry over itself does nothing. */
313 error = 0;
314 else
315 /* XXX Can't use VOP_REMOVE because of locking. */
316 error = genfs_rename_remove(ops, mp, cred,
317 fdvp, fcnp, fde, fvp);
318 goto out;
319 }
320 KASSERT(fvp != tvp);
321 KASSERT((fdvp != tdvp) ||
322 (fcnp->cn_namelen != tcnp->cn_namelen) ||
323 (memcmp(fcnp->cn_nameptr, tcnp->cn_nameptr, fcnp->cn_namelen)
324 != 0));
325
326 /*
327 * If the target exists, refuse to rename a directory over a
328 * non-directory or vice versa, or to clobber a non-empty
329 * directory.
330 */
331 if (tvp != NULL) {
332 if (fvp->v_type == VDIR && tvp->v_type == VDIR)
333 error =
334 (ops->gro_directory_empty_p(mp, cred, tvp, tdvp)?
335 0 : ENOTEMPTY);
336 else if (fvp->v_type == VDIR && tvp->v_type != VDIR)
337 error = ENOTDIR;
338 else if (fvp->v_type != VDIR && tvp->v_type == VDIR)
339 error = EISDIR;
340 else
341 error = 0;
342 if (error)
343 goto out;
344 KASSERT((fvp->v_type == VDIR) == (tvp->v_type == VDIR));
345 }
346
347 /*
348 * Authorize the rename.
349 */
350 error = ops->gro_rename_check_possible(mp, fdvp, fvp, tdvp, tvp);
351 if (error)
352 goto out;
353 error = ops->gro_rename_check_permitted(mp, cred, fdvp, fvp, tdvp, tvp);
354 error = kauth_authorize_vnode(cred, KAUTH_VNODE_DELETE, fvp, fdvp,
355 error);
356 error = kauth_authorize_vnode(cred, KAUTH_VNODE_RENAME, tvp, tdvp,
357 error);
358 if (error)
359 goto out;
360
361 /*
362 * Everything is hunky-dory. Shuffle the directory entries.
363 */
364 error = ops->gro_rename(mp, cred,
365 fdvp, fcnp, fde, fvp,
366 tdvp, tcnp, tde, tvp);
367 if (error)
368 goto out;
369
370 /* Success! */
371
372 out: genfs_rename_exit(ops, mp, fdvp, fvp, tdvp, tvp);
373 return error;
374 }
375
376 /*
377 * genfs_rename_knote: Note events about the various vnodes in a
378 * rename. To be called by gro_rename on success. The only pair of
379 * vnodes that may be identical is {fdvp, tdvp}. deleted_p is true iff
380 * the rename overwrote the last link to tvp.
381 */
382 void
383 genfs_rename_knote(struct vnode *fdvp, struct vnode *fvp,
384 struct vnode *tdvp, struct vnode *tvp, bool deleted_p)
385 {
386 long fdvp_events, tdvp_events;
387 bool directory_p, reparent_p, replaced_p;
388
389 KASSERT(fdvp != NULL);
390 KASSERT(fvp != NULL);
391 KASSERT(tdvp != NULL);
392 KASSERT(fdvp != fvp);
393 KASSERT(fdvp != tvp);
394 KASSERT(tdvp != fvp);
395 KASSERT(tdvp != tvp);
396 KASSERT(fvp != tvp);
397 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE);
398 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE);
399 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE);
400 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE));
401
402 directory_p = (fvp->v_type == VDIR);
403 reparent_p = (fdvp != tdvp);
404 replaced_p = (tvp != NULL);
405
406 KASSERT((tvp == NULL) || (directory_p == (tvp->v_type == VDIR)));
407 KASSERT(!deleted_p || replaced_p);
408
409 fdvp_events = NOTE_WRITE;
410 if (directory_p && reparent_p)
411 fdvp_events |= NOTE_LINK;
412 VN_KNOTE(fdvp, fdvp_events);
413
414 VN_KNOTE(fvp, NOTE_RENAME);
415
416 if (reparent_p) {
417 tdvp_events = NOTE_WRITE;
418 if (!replaced_p) {
419 tdvp_events |= NOTE_EXTEND;
420 if (directory_p)
421 tdvp_events |= NOTE_LINK;
422 }
423 VN_KNOTE(tdvp, tdvp_events);
424 }
425
426 if (replaced_p)
427 VN_KNOTE(tvp, (deleted_p? NOTE_DELETE : NOTE_LINK));
428 }
429
430 /*
431 * genfs_rename_cache_purge: Purge the name cache. To be called by
432 * gro_rename on success. The only pair of vnodes that may be
433 * identical is {fdvp, tdvp}.
434 */
435 void
436 genfs_rename_cache_purge(struct vnode *fdvp, struct vnode *fvp,
437 struct vnode *tdvp, struct vnode *tvp)
438 {
439
440 KASSERT(fdvp != NULL);
441 KASSERT(fvp != NULL);
442 KASSERT(tdvp != NULL);
443 KASSERT(fdvp != fvp);
444 KASSERT(fdvp != tvp);
445 KASSERT(tdvp != fvp);
446 KASSERT(tdvp != tvp);
447 KASSERT(fvp != tvp);
448 KASSERT(fdvp->v_type == VDIR);
449 KASSERT(tdvp->v_type == VDIR);
450
451 /*
452 * XXX What actually needs to be purged?
453 */
454
455 cache_purge(fdvp);
456
457 if (fvp->v_type == VDIR)
458 cache_purge(fvp);
459
460 if (tdvp != fdvp)
461 cache_purge(tdvp);
462
463 if ((tvp != NULL) && (tvp->v_type == VDIR))
464 cache_purge(tvp);
465 }
466
467 /*
468 * genfs_rename_enter: Look up fcnp in fdvp, and store the lookup
469 * results in *fde_ret and the associated vnode in *fvp_ret; fail if
470 * not found. Look up tcnp in tdvp, and store the lookup results in
471 * *tde_ret and the associated vnode in *tvp_ret; store null instead if
472 * not found. Fail if anything has been mounted on any of the nodes
473 * involved.
474 *
475 * fdvp and tdvp must be referenced.
476 *
477 * On entry, nothing is locked.
478 *
479 * On success, everything is locked, and *fvp_ret, and *tvp_ret if
480 * nonnull, are referenced. The only pairs of vnodes that may be
481 * identical are {fdvp, tdvp} and {fvp, tvp}.
482 *
483 * On failure, everything remains as was.
484 *
485 * Locking everything including the source and target nodes is
486 * necessary to make sure that, e.g., link count updates are OK. The
487 * locking order is, in general, ancestor-first, matching the order you
488 * need to use to look up a descendant anyway.
489 */
490 static int
491 genfs_rename_enter(const struct genfs_rename_ops *ops,
492 struct mount *mp, kauth_cred_t cred,
493 struct vnode *fdvp, struct componentname *fcnp,
494 void *fde_ret, struct vnode **fvp_ret,
495 struct vnode *tdvp, struct componentname *tcnp,
496 void *tde_ret, struct vnode **tvp_ret)
497 {
498 int error;
499
500 KASSERT(mp != NULL);
501 KASSERT(fdvp != NULL);
502 KASSERT(fcnp != NULL);
503 KASSERT(fvp_ret != NULL);
504 KASSERT(tdvp != NULL);
505 KASSERT(tcnp != NULL);
506 KASSERT(tvp_ret != NULL);
507 KASSERT(fvp_ret != tvp_ret);
508 KASSERT(fdvp->v_type == VDIR);
509 KASSERT(tdvp->v_type == VDIR);
510 KASSERT(fdvp->v_mount == mp);
511 KASSERT(tdvp->v_mount == mp);
512
513 if (fdvp == tdvp)
514 error = genfs_rename_enter_common(ops, mp, cred, fdvp,
515 fcnp, fde_ret, fvp_ret,
516 tcnp, tde_ret, tvp_ret);
517 else
518 error = genfs_rename_enter_separate(ops, mp, cred,
519 fdvp, fcnp, fde_ret, fvp_ret,
520 tdvp, tcnp, tde_ret, tvp_ret);
521
522 if (error)
523 return error;
524
525 KASSERT(*fvp_ret != NULL);
526 KASSERT(VOP_ISLOCKED(*fvp_ret) == LK_EXCLUSIVE);
527 KASSERT((*tvp_ret == NULL) || (VOP_ISLOCKED(*tvp_ret) == LK_EXCLUSIVE));
528 KASSERT(*fvp_ret != fdvp);
529 KASSERT(*fvp_ret != tdvp);
530 KASSERT(*tvp_ret != fdvp);
531 KASSERT(*tvp_ret != tdvp);
532 return 0;
533 }
534
535 /*
536 * genfs_rename_enter_common: Lock and look up with a common
537 * source/target directory.
538 */
539 static int
540 genfs_rename_enter_common(const struct genfs_rename_ops *ops,
541 struct mount *mp, kauth_cred_t cred, struct vnode *dvp,
542 struct componentname *fcnp,
543 void *fde_ret, struct vnode **fvp_ret,
544 struct componentname *tcnp,
545 void *tde_ret, struct vnode **tvp_ret)
546 {
547 struct vnode *fvp, *tvp;
548 int error;
549
550 KASSERT(ops != NULL);
551 KASSERT(mp != NULL);
552 KASSERT(dvp != NULL);
553 KASSERT(fcnp != NULL);
554 KASSERT(fvp_ret != NULL);
555 KASSERT(tcnp != NULL);
556 KASSERT(tvp_ret != NULL);
557 KASSERT(dvp->v_type == VDIR);
558 KASSERT(dvp->v_mount == mp);
559
560 error = ops->gro_lock_directory(mp, dvp);
561 if (error)
562 goto fail0;
563
564 /* Did we lose a race with mount? */
565 if (dvp->v_mountedhere != NULL) {
566 error = EBUSY;
567 goto fail1;
568 }
569
570 KASSERT(fcnp->cn_nameiop == DELETE);
571 error = ops->gro_lookup(mp, dvp, fcnp, fde_ret, &fvp);
572 if (error)
573 goto fail1;
574
575 KASSERT(fvp != NULL);
576
577 /* Refuse to rename `.'. */
578 if (fvp == dvp) {
579 error = EINVAL;
580 goto fail2;
581 }
582 KASSERT(fvp != dvp);
583
584 KASSERT(tcnp->cn_nameiop == RENAME);
585 error = ops->gro_lookup(mp, dvp, tcnp, tde_ret, &tvp);
586 if (error == ENOENT) {
587 tvp = NULL;
588 } else if (error) {
589 goto fail2;
590 } else {
591 KASSERT(tvp != NULL);
592
593 /* Refuse to rename over `.'. */
594 if (tvp == dvp) {
595 error = EISDIR; /* XXX EINVAL? */
596 goto fail2;
597 }
598 }
599 KASSERT(tvp != dvp);
600
601 /*
602 * We've looked up both nodes. Now lock them and check them.
603 */
604
605 vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY);
606 KASSERT(fvp->v_mount == mp);
607 /* Refuse to rename a mount point. */
608 if ((fvp->v_type == VDIR) && (fvp->v_mountedhere != NULL)) {
609 error = EBUSY;
610 goto fail3;
611 }
612
613 if ((tvp != NULL) && (tvp != fvp)) {
614 vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY);
615 KASSERT(tvp->v_mount == mp);
616 /* Refuse to rename over a mount point. */
617 if ((tvp->v_type == VDIR) && (tvp->v_mountedhere != NULL)) {
618 error = EBUSY;
619 goto fail4;
620 }
621 }
622
623 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE);
624 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE);
625 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE));
626
627 *fvp_ret = fvp;
628 *tvp_ret = tvp;
629 return 0;
630
631 fail4: if ((tvp != NULL) && (tvp != fvp))
632 VOP_UNLOCK(tvp);
633 fail3: VOP_UNLOCK(fvp);
634 if (tvp != NULL)
635 vrele(tvp);
636 fail2: vrele(fvp);
637 fail1: VOP_UNLOCK(dvp);
638 fail0: return error;
639 }
640
641 /*
642 * genfs_rename_enter_separate: Lock and look up with separate source
643 * and target directories.
644 */
645 static int
646 genfs_rename_enter_separate(const struct genfs_rename_ops *ops,
647 struct mount *mp, kauth_cred_t cred,
648 struct vnode *fdvp, struct componentname *fcnp,
649 void *fde_ret, struct vnode **fvp_ret,
650 struct vnode *tdvp, struct componentname *tcnp,
651 void *tde_ret, struct vnode **tvp_ret)
652 {
653 struct vnode *intermediate_node;
654 struct vnode *fvp, *tvp;
655 int error;
656
657 KASSERT(ops != NULL);
658 KASSERT(mp != NULL);
659 KASSERT(fdvp != NULL);
660 KASSERT(fcnp != NULL);
661 KASSERT(fvp_ret != NULL);
662 KASSERT(tdvp != NULL);
663 KASSERT(tcnp != NULL);
664 KASSERT(tvp_ret != NULL);
665 KASSERT(fdvp != tdvp);
666 KASSERT(fcnp != tcnp);
667 KASSERT(fcnp->cn_nameiop == DELETE);
668 KASSERT(tcnp->cn_nameiop == RENAME);
669 KASSERT(fvp_ret != tvp_ret);
670 KASSERT(fdvp->v_type == VDIR);
671 KASSERT(tdvp->v_type == VDIR);
672 KASSERT(fdvp->v_mount == mp);
673 KASSERT(tdvp->v_mount == mp);
674
675 error = ops->gro_genealogy(mp, cred, fdvp, tdvp, &intermediate_node);
676 if (error)
677 return error;
678
679 /*
680 * intermediate_node == NULL means fdvp is not an ancestor of tdvp.
681 */
682 if (intermediate_node == NULL)
683 error = genfs_rename_lock(ops, mp, cred,
684 ENOTEMPTY, EISDIR, EINVAL,
685 tdvp, tcnp, true, tde_ret, &tvp,
686 fdvp, fcnp, false, fde_ret, &fvp);
687 else
688 error = genfs_rename_lock(ops, mp, cred,
689 EINVAL, EISDIR, EINVAL,
690 fdvp, fcnp, false, fde_ret, &fvp,
691 tdvp, tcnp, true, tde_ret, &tvp);
692 if (error)
693 goto out;
694
695 KASSERT(fvp != NULL);
696
697 /*
698 * Reject rename("foo/bar", "foo/bar/baz/quux/zot").
699 */
700 if (fvp == intermediate_node) {
701 genfs_rename_exit(ops, mp, fdvp, fvp, tdvp, tvp);
702 error = EINVAL;
703 goto out;
704 }
705
706 *fvp_ret = fvp;
707 *tvp_ret = tvp;
708 error = 0;
709
710 out: if (intermediate_node != NULL)
711 vrele(intermediate_node);
712 return error;
713 }
714
715 /*
716 * genfs_rename_lock: Lookup and lock it all. The lock order is:
717 *
718 * a_dvp -> a_vp -> b_dvp -> b_vp,
719 *
720 * except if a_vp is a nondirectory in which case the lock order is:
721 *
722 * a_dvp -> b_dvp -> b_vp -> a_vp,
723 *
724 * which can't violate ancestor->descendant because a_vp has no
725 * descendants in this case. This edge case is necessary because some
726 * file systems can only lookup/lock/unlock, and we can't hold a_vp
727 * locked when we lookup/lock/unlock b_vp if they turn out to be the
728 * same, and we can't find out that they're the same until after the
729 * lookup.
730 *
731 * b_dvp must not be an ancestor of a_dvp, although a_dvp may be an
732 * ancestor of b_dvp.
733 *
734 * Fail with overlap_error if node a is directory b. Neither
735 * componentname may be `.' or `..'.
736 *
737 * a_dvp and b_dvp must be referenced.
738 *
739 * On entry, a_dvp and b_dvp are unlocked.
740 *
741 * On success,
742 * . a_dvp and b_dvp are locked,
743 * . *a_dirent_ret is filled with a directory entry whose node is
744 * locked and referenced,
745 * . *b_vp_ret is filled with the corresponding vnode,
746 * . *b_dirent_ret is filled either with null or with a directory entry
747 * whose node is locked and referenced,
748 * . *b_vp is filled either with null or with the corresponding vnode,
749 * and
750 * . the only pair of vnodes that may be identical is a_vp and b_vp.
751 *
752 * On failure, a_dvp and b_dvp are left unlocked, and *a_dirent_ret,
753 * *a_vp, *b_dirent_ret, and *b_vp are left alone.
754 */
755 static int
756 genfs_rename_lock(const struct genfs_rename_ops *ops,
757 struct mount *mp, kauth_cred_t cred,
758 int overlap_error, int a_dot_error, int b_dot_error,
759 struct vnode *a_dvp, struct componentname *a_cnp, bool a_missing_ok,
760 void *a_de_ret, struct vnode **a_vp_ret,
761 struct vnode *b_dvp, struct componentname *b_cnp, bool b_missing_ok,
762 void *b_de_ret, struct vnode **b_vp_ret)
763 {
764 struct vnode *a_vp, *b_vp;
765 int error;
766
767 KASSERT(ops != NULL);
768 KASSERT(mp != NULL);
769 KASSERT(a_dvp != NULL);
770 KASSERT(a_cnp != NULL);
771 KASSERT(a_vp_ret != NULL);
772 KASSERT(b_dvp != NULL);
773 KASSERT(b_cnp != NULL);
774 KASSERT(b_vp_ret != NULL);
775 KASSERT(a_dvp != b_dvp);
776 KASSERT(a_vp_ret != b_vp_ret);
777 KASSERT(a_dvp->v_type == VDIR);
778 KASSERT(b_dvp->v_type == VDIR);
779 KASSERT(a_dvp->v_mount == mp);
780 KASSERT(b_dvp->v_mount == mp);
781 KASSERT(a_missing_ok != b_missing_ok);
782
783 /*
784 * 1. Lock a_dvp.
785 */
786 error = ops->gro_lock_directory(mp, a_dvp);
787 if (error)
788 goto fail0;
789
790 /* Did we lose a race with mount? */
791 if (a_dvp->v_mountedhere != NULL) {
792 error = EBUSY;
793 goto fail1;
794 }
795
796 /*
797 * 2. Lookup a_vp. May lock/unlock a_vp.
798 */
799 error = ops->gro_lookup(mp, a_dvp, a_cnp, a_de_ret, &a_vp);
800 if (error) {
801 if (a_missing_ok && (error == ENOENT))
802 a_vp = NULL;
803 else
804 goto fail1;
805 } else {
806 KASSERT(a_vp != NULL);
807
808 /* Refuse to rename (over) `.'. */
809 if (a_vp == a_dvp) {
810 error = a_dot_error;
811 goto fail2;
812 }
813
814 /* Reject rename("x", "x/y") or rename("x/y", "x"). */
815 if (a_vp == b_dvp) {
816 error = overlap_error;
817 goto fail2;
818 }
819 }
820
821 KASSERT(a_vp != a_dvp);
822 KASSERT(a_vp != b_dvp);
823
824 /*
825 * 3. Lock a_vp, if it is a directory.
826 *
827 * We already ruled out a_vp == a_dvp (i.e., a_cnp is `.'), so
828 * this is not locking against self, and we already ruled out
829 * a_vp == b_dvp, so this won't cause subsequent locking of
830 * b_dvp to lock against self.
831 *
832 * If a_vp is a nondirectory, we can't hold it when we lookup
833 * b_vp in case (a) the file system can only lookup/lock/unlock
834 * and (b) b_vp turns out to be the same file as a_vp due to
835 * hard links -- and we can't even detect that case until after
836 * we've looked up b_vp. Fortunately, if a_vp is a
837 * nondirectory, then it is a leaf, so we can safely lock it
838 * last.
839 */
840 if (a_vp != NULL && a_vp->v_type == VDIR) {
841 vn_lock(a_vp, LK_EXCLUSIVE | LK_RETRY);
842 KASSERT(a_vp->v_mount == mp);
843 /* Refuse to rename (over) a mount point. */
844 if (a_vp->v_mountedhere != NULL) {
845 error = EBUSY;
846 goto fail3;
847 }
848 }
849
850 /*
851 * 4. Lock b_dvp.
852 */
853 error = ops->gro_lock_directory(mp, b_dvp);
854 if (error)
855 goto fail3;
856
857 /* Did we lose a race with mount? */
858 if (b_dvp->v_mountedhere != NULL) {
859 error = EBUSY;
860 goto fail4;
861 }
862
863 /*
864 * 5. Lookup b_vp. May lock/unlock b_vp.
865 */
866 error = ops->gro_lookup(mp, b_dvp, b_cnp, b_de_ret, &b_vp);
867 if (error) {
868 if (b_missing_ok && (error == ENOENT))
869 b_vp = NULL;
870 else
871 goto fail4;
872 } else {
873 KASSERT(b_vp != NULL);
874
875 /* Refuse to rename (over) `.'. */
876 if (b_vp == b_dvp) {
877 error = b_dot_error;
878 goto fail5;
879 }
880
881 /*
882 * b_dvp must not be an ancestor of a_dvp, so if we
883 * find b_dvp/b_vp=a_dvp/a_vp something is wrong.
884 */
885 if (b_vp == a_dvp) {
886 /*
887 * We have a directory hard link before us.
888 * XXX What error should this return? EDEADLK?
889 * Panic?
890 */
891 error = EIO;
892 goto fail5;
893 }
894 }
895 KASSERT(b_vp != b_dvp);
896 KASSERT(b_vp != a_dvp);
897
898 /*
899 * 6. Lock a_vp, if it is a nondirectory.
900 *
901 * In this case a_vp is a leaf, so it is either equal to or
902 * incommensurate with b_vp, and so we can safely lock it at
903 * any point now.
904 */
905 if (a_vp != NULL && a_vp->v_type != VDIR) {
906 vn_lock(a_vp, LK_EXCLUSIVE | LK_RETRY);
907 KASSERT(a_vp->v_mount == mp);
908 /* (not a directory so can't have anything mounted here) */
909 }
910
911 /*
912 * 7. Lock b_vp, if it is not a_vp.
913 *
914 * b_vp and a_vp may the same inode if they are hard links to
915 * one another.
916 */
917 if ((b_vp != NULL) && (b_vp != a_vp)) {
918 vn_lock(b_vp, LK_EXCLUSIVE | LK_RETRY);
919 KASSERT(b_vp->v_mount == mp);
920 /* Refuse to rename (over) a mount point. */
921 if ((b_vp->v_type == VDIR) && (b_vp->v_mountedhere != NULL)) {
922 error = EBUSY;
923 goto fail6;
924 }
925 }
926
927 KASSERT(VOP_ISLOCKED(a_dvp) == LK_EXCLUSIVE);
928 KASSERT(VOP_ISLOCKED(b_dvp) == LK_EXCLUSIVE);
929 KASSERT(a_missing_ok || (a_vp != NULL));
930 KASSERT(b_missing_ok || (b_vp != NULL));
931 KASSERT((a_vp == NULL) || (VOP_ISLOCKED(a_vp) == LK_EXCLUSIVE));
932 KASSERT((b_vp == NULL) || (VOP_ISLOCKED(b_vp) == LK_EXCLUSIVE));
933
934 *a_vp_ret = a_vp;
935 *b_vp_ret = b_vp;
936 return 0;
937
938 fail6: if ((b_vp != NULL) && (b_vp != a_vp))
939 VOP_UNLOCK(b_vp);
940 if (a_vp != NULL && a_vp->v_type != VDIR)
941 VOP_UNLOCK(a_vp);
942 fail5: if (b_vp != NULL)
943 vrele(b_vp);
944 fail4: VOP_UNLOCK(b_dvp);
945 fail3: if (a_vp != NULL && a_vp->v_type == VDIR)
946 VOP_UNLOCK(a_vp);
947 fail2: if (a_vp != NULL)
948 vrele(a_vp);
949 fail1: VOP_UNLOCK(a_dvp);
950 fail0: return error;
951 }
952
953 /*
954 * genfs_rename_exit: Unlock everything we locked for rename.
955 *
956 * fdvp and tdvp must be referenced.
957 *
958 * On entry, everything is locked, and fvp and tvp referenced.
959 *
960 * On exit, everything is unlocked, and fvp and tvp are released.
961 */
962 static void
963 genfs_rename_exit(const struct genfs_rename_ops *ops,
964 struct mount *mp,
965 struct vnode *fdvp, struct vnode *fvp,
966 struct vnode *tdvp, struct vnode *tvp)
967 {
968
969 (void)ops;
970 KASSERT(ops != NULL);
971 KASSERT(mp != NULL);
972 KASSERT(fdvp != NULL);
973 KASSERT(fvp != NULL);
974 KASSERT(fdvp != fvp);
975 KASSERT(fdvp != tvp);
976 KASSERT(tdvp != tvp);
977 KASSERT(tdvp != fvp);
978 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE);
979 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE);
980 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE);
981 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE));
982
983 if ((tvp != NULL) && (tvp != fvp))
984 VOP_UNLOCK(tvp);
985 VOP_UNLOCK(fvp);
986 if (tvp != NULL)
987 vrele(tvp);
988 if (tdvp != fdvp)
989 VOP_UNLOCK(tdvp);
990 vrele(fvp);
991 VOP_UNLOCK(fdvp);
992 }
993
994 /*
995 * genfs_rename_remove: Remove the entry for the non-directory vp with
996 * componentname cnp from the directory dvp, using the lookup results
997 * de. It is the responsibility of gro_remove to purge the name cache
998 * and note kevents.
999 *
1000 * Everything must be locked and referenced.
1001 */
1002 static int
1003 genfs_rename_remove(const struct genfs_rename_ops *ops,
1004 struct mount *mp, kauth_cred_t cred,
1005 struct vnode *dvp, struct componentname *cnp, void *de, struct vnode *vp)
1006 {
1007 int error;
1008
1009 KASSERT(ops != NULL);
1010 KASSERT(mp != NULL);
1011 KASSERT(dvp != NULL);
1012 KASSERT(cnp != NULL);
1013 KASSERT(vp != NULL);
1014 KASSERT(dvp != vp);
1015 KASSERT(dvp->v_type == VDIR);
1016 KASSERT(vp->v_type != VDIR);
1017 KASSERT(dvp->v_mount == mp);
1018 KASSERT(vp->v_mount == mp);
1019 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE);
1020 KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE);
1021
1022 error = ops->gro_remove_check_possible(mp, dvp, vp);
1023 if (error)
1024 return error;
1025
1026 error = ops->gro_remove_check_permitted(mp, cred, dvp, vp);
1027 error = kauth_authorize_vnode(cred, KAUTH_VNODE_DELETE, vp, dvp,
1028 error);
1029 if (error)
1030 return error;
1031
1032 error = ops->gro_remove(mp, cred, dvp, cnp, de, vp);
1033 if (error)
1034 return error;
1035
1036 return 0;
1037 }
1038
1039 static int
1040 genfs_ufslike_check_sticky(kauth_cred_t, mode_t, uid_t, struct vnode *, uid_t);
1041
1042 /*
1043 * genfs_ufslike_rename_check_possible: Check whether a rename is
1044 * possible independent of credentials, assuming UFS-like inode flag
1045 * semantics. clobber_p is true iff the target node already exists.
1046 */
1047 int
1048 genfs_ufslike_rename_check_possible(
1049 unsigned long fdflags, unsigned long fflags,
1050 unsigned long tdflags, unsigned long tflags, bool clobber_p,
1051 unsigned long immutable, unsigned long append)
1052 {
1053
1054 if ((fdflags | fflags) & (immutable | append))
1055 return EPERM;
1056
1057 if (tdflags & (immutable | (clobber_p? append : 0)))
1058 return EPERM;
1059
1060 if (clobber_p && (tflags & (immutable | append)))
1061 return EPERM;
1062
1063 return 0;
1064 }
1065
1066 /*
1067 * genfs_ufslike_rename_check_permitted: Check whether a rename is
1068 * permitted given our credentials, assuming UFS-like permission and
1069 * ownership semantics.
1070 *
1071 * The only pair of vnodes that may be identical is {fdvp, tdvp}.
1072 *
1073 * Everything must be locked and referenced.
1074 */
1075 int
1076 genfs_ufslike_rename_check_permitted(kauth_cred_t cred,
1077 struct vnode *fdvp, mode_t fdmode, uid_t fduid,
1078 struct vnode *fvp, uid_t fuid,
1079 struct vnode *tdvp, mode_t tdmode, uid_t tduid,
1080 struct vnode *tvp, uid_t tuid)
1081 {
1082 int error;
1083
1084 KASSERT(fdvp != NULL);
1085 KASSERT(fvp != NULL);
1086 KASSERT(tdvp != NULL);
1087 KASSERT(fdvp != fvp);
1088 KASSERT(fdvp != tvp);
1089 KASSERT(tdvp != fvp);
1090 KASSERT(tdvp != tvp);
1091 KASSERT(fvp != tvp);
1092 KASSERT(fdvp->v_type == VDIR);
1093 KASSERT(tdvp->v_type == VDIR);
1094 KASSERT(fdvp->v_mount == fvp->v_mount);
1095 KASSERT(fdvp->v_mount == tdvp->v_mount);
1096 KASSERT((tvp == NULL) || (fdvp->v_mount == tvp->v_mount));
1097 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE);
1098 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE);
1099 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE);
1100 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE));
1101
1102 /*
1103 * We need to remove or change an entry in the source directory.
1104 */
1105 error = VOP_ACCESS(fdvp, VWRITE, cred);
1106 if (error)
1107 return error;
1108
1109 /*
1110 * If we are changing directories, then we need to write to the
1111 * target directory to add or change an entry. Also, if fvp is
1112 * a directory, we need to write to it to change its `..'
1113 * entry.
1114 */
1115 if (fdvp != tdvp) {
1116 error = VOP_ACCESS(tdvp, VWRITE, cred);
1117 if (error)
1118 return error;
1119 if (fvp->v_type == VDIR) {
1120 error = VOP_ACCESS(fvp, VWRITE, cred);
1121 if (error)
1122 return error;
1123 }
1124 }
1125
1126 error = genfs_ufslike_check_sticky(cred, fdmode, fduid, fvp, fuid);
1127 if (error)
1128 return error;
1129
1130 error = genfs_ufslike_check_sticky(cred, tdmode, tduid, tvp, tuid);
1131 if (error)
1132 return error;
1133
1134 return 0;
1135 }
1136
1137 /*
1138 * genfs_ufslike_remove_check_possible: Check whether a remove is
1139 * possible independent of credentials, assuming UFS-like inode flag
1140 * semantics.
1141 */
1142 int
1143 genfs_ufslike_remove_check_possible(unsigned long dflags, unsigned long flags,
1144 unsigned long immutable, unsigned long append)
1145 {
1146
1147 /*
1148 * We want to delete the entry. If the directory is immutable,
1149 * we can't write to it to delete the entry. If the directory
1150 * is append-only, the only change we can make is to add
1151 * entries, so we can't delete entries. If the node is
1152 * immutable, we can't change the links to it, so we can't
1153 * delete the entry. If the node is append-only...well, this
1154 * is what UFS does.
1155 */
1156 if ((dflags | flags) & (immutable | append))
1157 return EPERM;
1158
1159 return 0;
1160 }
1161
1162 /*
1163 * genfs_ufslike_remove_check_permitted: Check whether a remove is
1164 * permitted given our credentials, assuming UFS-like permission and
1165 * ownership semantics.
1166 *
1167 * Everything must be locked and referenced.
1168 */
1169 int
1170 genfs_ufslike_remove_check_permitted(kauth_cred_t cred,
1171 struct vnode *dvp, mode_t dmode, uid_t duid,
1172 struct vnode *vp, uid_t uid)
1173 {
1174 int error;
1175
1176 KASSERT(dvp != NULL);
1177 KASSERT(vp != NULL);
1178 KASSERT(dvp != vp);
1179 KASSERT(dvp->v_type == VDIR);
1180 KASSERT(vp->v_type != VDIR);
1181 KASSERT(dvp->v_mount == vp->v_mount);
1182 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE);
1183 KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE);
1184
1185 /*
1186 * We need to write to the directory to remove from it.
1187 */
1188 error = VOP_ACCESS(dvp, VWRITE, cred);
1189 if (error)
1190 return error;
1191
1192 error = genfs_ufslike_check_sticky(cred, dmode, duid, vp, uid);
1193 if (error)
1194 return error;
1195
1196 return 0;
1197 }
1198
1199 /*
1200 * genfs_ufslike_check_sticky: Check whether a party with credentials
1201 * cred may change an entry in a sticky directory, assuming UFS-like
1202 * permission, ownership, and stickiness semantics: If the directory is
1203 * sticky and the entry exists, the user must own either the directory
1204 * or the entry's node in order to change the entry.
1205 *
1206 * Everything must be locked and referenced.
1207 */
1208 int
1209 genfs_ufslike_check_sticky(kauth_cred_t cred, mode_t dmode, uid_t duid,
1210 struct vnode *vp, uid_t uid)
1211 {
1212
1213 if ((dmode & S_ISTXT) && (vp != NULL))
1214 return genfs_can_sticky(vp, cred, duid, uid);
1215
1216 return 0;
1217 }
1218