1 /* $NetBSD: genfs_rename.c,v 1.7 2021/10/20 13:29:06 thorpej 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.7 2021/10/20 13:29:06 thorpej 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 *, nlink_t *); 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 nlink_t tvp_new_nlink = 0; 251 int error; 252 253 KASSERT(ops != NULL); 254 KASSERT(fdvp != NULL); 255 KASSERT(fcnp != NULL); 256 KASSERT(tdvp != NULL); 257 KASSERT(tcnp != NULL); 258 /* KASSERT(VOP_ISLOCKED(fdvp) != LK_EXCLUSIVE); */ 259 /* KASSERT(VOP_ISLOCKED(tdvp) != LK_EXCLUSIVE); */ 260 KASSERT(fdvp->v_type == VDIR); 261 KASSERT(tdvp->v_type == VDIR); 262 KASSERT(fdvp->v_mount == tdvp->v_mount); 263 KASSERT(fcnp != tcnp); 264 KASSERT(fcnp->cn_nameiop == DELETE); 265 KASSERT(tcnp->cn_nameiop == RENAME); 266 267 /* XXX Want a better equality test. */ 268 KASSERT(kauth_cred_uidmatch(cred, fcnp->cn_cred)); 269 KASSERT(kauth_cred_uidmatch(cred, tcnp->cn_cred)); 270 271 mp = fdvp->v_mount; 272 KASSERT(mp != NULL); 273 KASSERT(mp == tdvp->v_mount); 274 /* XXX How can we be sure this stays true? */ 275 KASSERT((mp->mnt_flag & MNT_RDONLY) == 0); 276 277 /* Reject rename("x/..", ...) and rename(..., "x/..") early. */ 278 if ((fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT) 279 return EINVAL; /* XXX EISDIR? */ 280 281 error = genfs_rename_enter(ops, mp, cred, 282 fdvp, fcnp, fde, &fvp, 283 tdvp, tcnp, tde, &tvp); 284 if (error) 285 return error; 286 287 /* 288 * Check that everything is locked and looks right. 289 */ 290 KASSERT(fvp != NULL); 291 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE); 292 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 293 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 294 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 295 296 /* 297 * If the source and destination are the same object, we need 298 * only at most delete the source entry. We are guaranteed at 299 * this point that the entries are distinct. 300 */ 301 if (fvp == tvp) { 302 KASSERT(tvp != NULL); 303 if (fvp->v_type == VDIR) 304 /* XXX This shouldn't be possible. */ 305 error = EINVAL; 306 else if (posixly_correct) 307 /* POSIX sez to leave them alone. */ 308 error = 0; 309 else if ((fdvp == tdvp) && 310 (fcnp->cn_namelen == tcnp->cn_namelen) && 311 (memcmp(fcnp->cn_nameptr, tcnp->cn_nameptr, 312 fcnp->cn_namelen) == 0)) 313 /* Renaming an entry over itself does nothing. */ 314 error = 0; 315 else { 316 /* XXX Can't use VOP_REMOVE because of locking. */ 317 error = genfs_rename_remove(ops, mp, cred, 318 fdvp, fcnp, fde, fvp, &tvp_new_nlink); 319 VN_KNOTE(fdvp, NOTE_WRITE); 320 VN_KNOTE(fvp, 321 tvp_new_nlink == 0 ? NOTE_DELETE : NOTE_LINK); 322 } 323 goto out; 324 } 325 KASSERT(fvp != tvp); 326 KASSERT((fdvp != tdvp) || 327 (fcnp->cn_namelen != tcnp->cn_namelen) || 328 (memcmp(fcnp->cn_nameptr, tcnp->cn_nameptr, fcnp->cn_namelen) 329 != 0)); 330 331 /* 332 * If the target exists, refuse to rename a directory over a 333 * non-directory or vice versa, or to clobber a non-empty 334 * directory. 335 */ 336 if (tvp != NULL) { 337 if (fvp->v_type == VDIR && tvp->v_type == VDIR) 338 error = 339 (ops->gro_directory_empty_p(mp, cred, tvp, tdvp)? 340 0 : ENOTEMPTY); 341 else if (fvp->v_type == VDIR && tvp->v_type != VDIR) 342 error = ENOTDIR; 343 else if (fvp->v_type != VDIR && tvp->v_type == VDIR) 344 error = EISDIR; 345 else 346 error = 0; 347 if (error) 348 goto out; 349 KASSERT((fvp->v_type == VDIR) == (tvp->v_type == VDIR)); 350 } 351 352 /* 353 * Authorize the rename. 354 */ 355 error = ops->gro_rename_check_possible(mp, fdvp, fvp, tdvp, tvp); 356 if (error) 357 goto out; 358 error = ops->gro_rename_check_permitted(mp, cred, fdvp, fvp, tdvp, tvp); 359 error = kauth_authorize_vnode(cred, KAUTH_VNODE_DELETE, fvp, fdvp, 360 error); 361 error = kauth_authorize_vnode(cred, KAUTH_VNODE_RENAME, tvp, tdvp, 362 error); 363 if (error) 364 goto out; 365 366 /* 367 * Everything is hunky-dory. Shuffle the directory entries. 368 */ 369 error = ops->gro_rename(mp, cred, 370 fdvp, fcnp, fde, fvp, 371 tdvp, tcnp, tde, tvp, 372 &tvp_new_nlink); 373 if (error) 374 goto out; 375 376 /* Success! */ 377 genfs_rename_knote(fdvp, fvp, tdvp, tvp, tvp_new_nlink); 378 379 out: 380 genfs_rename_exit(ops, mp, fdvp, fvp, tdvp, tvp); 381 return error; 382 } 383 384 /* 385 * genfs_rename_knote: Note events about the various vnodes in a 386 * rename. To be called by gro_rename on success. The only pair of 387 * vnodes that may be identical is {fdvp, tdvp}. tvp_new_nlink is 388 * the resulting link count of tvp. 389 */ 390 void 391 genfs_rename_knote(struct vnode *fdvp, struct vnode *fvp, 392 struct vnode *tdvp, struct vnode *tvp, nlink_t tvp_new_nlink) 393 { 394 long fdvp_events, tdvp_events; 395 bool directory_p, reparent_p, replaced_p; 396 397 KASSERT(fdvp != NULL); 398 KASSERT(fvp != NULL); 399 KASSERT(tdvp != NULL); 400 KASSERT(fdvp != fvp); 401 KASSERT(fdvp != tvp); 402 KASSERT(tdvp != fvp); 403 KASSERT(tdvp != tvp); 404 KASSERT(fvp != tvp); 405 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE); 406 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 407 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 408 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 409 410 directory_p = (fvp->v_type == VDIR); 411 reparent_p = (fdvp != tdvp); 412 replaced_p = (tvp != NULL); 413 414 KASSERT((tvp == NULL) || (directory_p == (tvp->v_type == VDIR))); 415 416 fdvp_events = NOTE_WRITE; 417 if (directory_p && reparent_p) 418 fdvp_events |= NOTE_LINK; 419 VN_KNOTE(fdvp, fdvp_events); 420 421 VN_KNOTE(fvp, NOTE_RENAME); 422 423 if (reparent_p) { 424 tdvp_events = NOTE_WRITE; 425 if (!replaced_p) { 426 tdvp_events |= NOTE_EXTEND; 427 if (directory_p) 428 tdvp_events |= NOTE_LINK; 429 } 430 VN_KNOTE(tdvp, tdvp_events); 431 } 432 433 if (replaced_p) 434 VN_KNOTE(tvp, (tvp_new_nlink == 0 ? NOTE_DELETE : NOTE_LINK)); 435 } 436 437 /* 438 * genfs_rename_cache_purge: Purge the name cache. To be called by 439 * gro_rename on success. The only pair of vnodes that may be 440 * identical is {fdvp, tdvp}. 441 */ 442 void 443 genfs_rename_cache_purge(struct vnode *fdvp, struct vnode *fvp, 444 struct vnode *tdvp, struct vnode *tvp) 445 { 446 447 KASSERT(fdvp != NULL); 448 KASSERT(fvp != NULL); 449 KASSERT(tdvp != NULL); 450 KASSERT(fdvp != fvp); 451 KASSERT(fdvp != tvp); 452 KASSERT(tdvp != fvp); 453 KASSERT(tdvp != tvp); 454 KASSERT(fvp != tvp); 455 KASSERT(fdvp->v_type == VDIR); 456 KASSERT(tdvp->v_type == VDIR); 457 458 /* 459 * XXX What actually needs to be purged? 460 */ 461 462 cache_purge(fdvp); 463 464 if (fvp->v_type == VDIR) 465 cache_purge(fvp); 466 467 if (tdvp != fdvp) 468 cache_purge(tdvp); 469 470 if ((tvp != NULL) && (tvp->v_type == VDIR)) 471 cache_purge(tvp); 472 } 473 474 /* 475 * genfs_rename_enter: Look up fcnp in fdvp, and store the lookup 476 * results in *fde_ret and the associated vnode in *fvp_ret; fail if 477 * not found. Look up tcnp in tdvp, and store the lookup results in 478 * *tde_ret and the associated vnode in *tvp_ret; store null instead if 479 * not found. Fail if anything has been mounted on any of the nodes 480 * involved. 481 * 482 * fdvp and tdvp must be referenced. 483 * 484 * On entry, nothing is locked. 485 * 486 * On success, everything is locked, and *fvp_ret, and *tvp_ret if 487 * nonnull, are referenced. The only pairs of vnodes that may be 488 * identical are {fdvp, tdvp} and {fvp, tvp}. 489 * 490 * On failure, everything remains as was. 491 * 492 * Locking everything including the source and target nodes is 493 * necessary to make sure that, e.g., link count updates are OK. The 494 * locking order is, in general, ancestor-first, matching the order you 495 * need to use to look up a descendant anyway. 496 */ 497 static int 498 genfs_rename_enter(const struct genfs_rename_ops *ops, 499 struct mount *mp, kauth_cred_t cred, 500 struct vnode *fdvp, struct componentname *fcnp, 501 void *fde_ret, struct vnode **fvp_ret, 502 struct vnode *tdvp, struct componentname *tcnp, 503 void *tde_ret, struct vnode **tvp_ret) 504 { 505 int error; 506 507 KASSERT(mp != NULL); 508 KASSERT(fdvp != NULL); 509 KASSERT(fcnp != NULL); 510 KASSERT(fvp_ret != NULL); 511 KASSERT(tdvp != NULL); 512 KASSERT(tcnp != NULL); 513 KASSERT(tvp_ret != NULL); 514 KASSERT(fvp_ret != tvp_ret); 515 KASSERT(fdvp->v_type == VDIR); 516 KASSERT(tdvp->v_type == VDIR); 517 KASSERT(fdvp->v_mount == mp); 518 KASSERT(tdvp->v_mount == mp); 519 520 if (fdvp == tdvp) 521 error = genfs_rename_enter_common(ops, mp, cred, fdvp, 522 fcnp, fde_ret, fvp_ret, 523 tcnp, tde_ret, tvp_ret); 524 else 525 error = genfs_rename_enter_separate(ops, mp, cred, 526 fdvp, fcnp, fde_ret, fvp_ret, 527 tdvp, tcnp, tde_ret, tvp_ret); 528 529 if (error) 530 return error; 531 532 KASSERT(*fvp_ret != NULL); 533 KASSERT(VOP_ISLOCKED(*fvp_ret) == LK_EXCLUSIVE); 534 KASSERT((*tvp_ret == NULL) || (VOP_ISLOCKED(*tvp_ret) == LK_EXCLUSIVE)); 535 KASSERT(*fvp_ret != fdvp); 536 KASSERT(*fvp_ret != tdvp); 537 KASSERT(*tvp_ret != fdvp); 538 KASSERT(*tvp_ret != tdvp); 539 return 0; 540 } 541 542 /* 543 * genfs_rename_enter_common: Lock and look up with a common 544 * source/target directory. 545 */ 546 static int 547 genfs_rename_enter_common(const struct genfs_rename_ops *ops, 548 struct mount *mp, kauth_cred_t cred, struct vnode *dvp, 549 struct componentname *fcnp, 550 void *fde_ret, struct vnode **fvp_ret, 551 struct componentname *tcnp, 552 void *tde_ret, struct vnode **tvp_ret) 553 { 554 struct vnode *fvp, *tvp; 555 int error; 556 557 KASSERT(ops != NULL); 558 KASSERT(mp != NULL); 559 KASSERT(dvp != NULL); 560 KASSERT(fcnp != NULL); 561 KASSERT(fvp_ret != NULL); 562 KASSERT(tcnp != NULL); 563 KASSERT(tvp_ret != NULL); 564 KASSERT(dvp->v_type == VDIR); 565 KASSERT(dvp->v_mount == mp); 566 567 error = ops->gro_lock_directory(mp, dvp); 568 if (error) 569 goto fail0; 570 571 /* Did we lose a race with mount? */ 572 if (dvp->v_mountedhere != NULL) { 573 error = EBUSY; 574 goto fail1; 575 } 576 577 KASSERT(fcnp->cn_nameiop == DELETE); 578 error = ops->gro_lookup(mp, dvp, fcnp, fde_ret, &fvp); 579 if (error) 580 goto fail1; 581 582 KASSERT(fvp != NULL); 583 584 /* Refuse to rename `.'. */ 585 if (fvp == dvp) { 586 error = EINVAL; 587 goto fail2; 588 } 589 KASSERT(fvp != dvp); 590 591 KASSERT(tcnp->cn_nameiop == RENAME); 592 error = ops->gro_lookup(mp, dvp, tcnp, tde_ret, &tvp); 593 if (error == ENOENT) { 594 tvp = NULL; 595 } else if (error) { 596 goto fail2; 597 } else { 598 KASSERT(tvp != NULL); 599 600 /* Refuse to rename over `.'. */ 601 if (tvp == dvp) { 602 error = EISDIR; /* XXX EINVAL? */ 603 goto fail2; 604 } 605 } 606 KASSERT(tvp != dvp); 607 608 /* 609 * We've looked up both nodes. Now lock them and check them. 610 */ 611 612 vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY); 613 KASSERT(fvp->v_mount == mp); 614 /* Refuse to rename a mount point. */ 615 if ((fvp->v_type == VDIR) && (fvp->v_mountedhere != NULL)) { 616 error = EBUSY; 617 goto fail3; 618 } 619 620 if ((tvp != NULL) && (tvp != fvp)) { 621 vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY); 622 KASSERT(tvp->v_mount == mp); 623 /* Refuse to rename over a mount point. */ 624 if ((tvp->v_type == VDIR) && (tvp->v_mountedhere != NULL)) { 625 error = EBUSY; 626 goto fail4; 627 } 628 } 629 630 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); 631 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 632 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 633 634 *fvp_ret = fvp; 635 *tvp_ret = tvp; 636 return 0; 637 638 fail4: if ((tvp != NULL) && (tvp != fvp)) 639 VOP_UNLOCK(tvp); 640 fail3: VOP_UNLOCK(fvp); 641 if (tvp != NULL) 642 vrele(tvp); 643 fail2: vrele(fvp); 644 fail1: VOP_UNLOCK(dvp); 645 fail0: return error; 646 } 647 648 /* 649 * genfs_rename_enter_separate: Lock and look up with separate source 650 * and target directories. 651 */ 652 static int 653 genfs_rename_enter_separate(const struct genfs_rename_ops *ops, 654 struct mount *mp, kauth_cred_t cred, 655 struct vnode *fdvp, struct componentname *fcnp, 656 void *fde_ret, struct vnode **fvp_ret, 657 struct vnode *tdvp, struct componentname *tcnp, 658 void *tde_ret, struct vnode **tvp_ret) 659 { 660 struct vnode *intermediate_node; 661 struct vnode *fvp, *tvp; 662 int error; 663 664 KASSERT(ops != NULL); 665 KASSERT(mp != NULL); 666 KASSERT(fdvp != NULL); 667 KASSERT(fcnp != NULL); 668 KASSERT(fvp_ret != NULL); 669 KASSERT(tdvp != NULL); 670 KASSERT(tcnp != NULL); 671 KASSERT(tvp_ret != NULL); 672 KASSERT(fdvp != tdvp); 673 KASSERT(fcnp != tcnp); 674 KASSERT(fcnp->cn_nameiop == DELETE); 675 KASSERT(tcnp->cn_nameiop == RENAME); 676 KASSERT(fvp_ret != tvp_ret); 677 KASSERT(fdvp->v_type == VDIR); 678 KASSERT(tdvp->v_type == VDIR); 679 KASSERT(fdvp->v_mount == mp); 680 KASSERT(tdvp->v_mount == mp); 681 682 error = ops->gro_genealogy(mp, cred, fdvp, tdvp, &intermediate_node); 683 if (error) 684 return error; 685 686 /* 687 * intermediate_node == NULL means fdvp is not an ancestor of tdvp. 688 */ 689 if (intermediate_node == NULL) 690 error = genfs_rename_lock(ops, mp, cred, 691 ENOTEMPTY, EISDIR, EINVAL, 692 tdvp, tcnp, true, tde_ret, &tvp, 693 fdvp, fcnp, false, fde_ret, &fvp); 694 else 695 error = genfs_rename_lock(ops, mp, cred, 696 EINVAL, EISDIR, EINVAL, 697 fdvp, fcnp, false, fde_ret, &fvp, 698 tdvp, tcnp, true, tde_ret, &tvp); 699 if (error) 700 goto out; 701 702 KASSERT(fvp != NULL); 703 704 /* 705 * Reject rename("foo/bar", "foo/bar/baz/quux/zot"). 706 */ 707 if (fvp == intermediate_node) { 708 genfs_rename_exit(ops, mp, fdvp, fvp, tdvp, tvp); 709 error = EINVAL; 710 goto out; 711 } 712 713 *fvp_ret = fvp; 714 *tvp_ret = tvp; 715 error = 0; 716 717 out: if (intermediate_node != NULL) 718 vrele(intermediate_node); 719 return error; 720 } 721 722 /* 723 * genfs_rename_lock: Lookup and lock it all. The lock order is: 724 * 725 * a_dvp -> a_vp -> b_dvp -> b_vp, 726 * 727 * except if a_vp is a nondirectory in which case the lock order is: 728 * 729 * a_dvp -> b_dvp -> b_vp -> a_vp, 730 * 731 * which can't violate ancestor->descendant because a_vp has no 732 * descendants in this case. This edge case is necessary because some 733 * file systems can only lookup/lock/unlock, and we can't hold a_vp 734 * locked when we lookup/lock/unlock b_vp if they turn out to be the 735 * same, and we can't find out that they're the same until after the 736 * lookup. 737 * 738 * b_dvp must not be an ancestor of a_dvp, although a_dvp may be an 739 * ancestor of b_dvp. 740 * 741 * Fail with overlap_error if node a is directory b. Neither 742 * componentname may be `.' or `..'. 743 * 744 * a_dvp and b_dvp must be referenced. 745 * 746 * On entry, a_dvp and b_dvp are unlocked. 747 * 748 * On success, 749 * . a_dvp and b_dvp are locked, 750 * . *a_dirent_ret is filled with a directory entry whose node is 751 * locked and referenced, 752 * . *b_vp_ret is filled with the corresponding vnode, 753 * . *b_dirent_ret is filled either with null or with a directory entry 754 * whose node is locked and referenced, 755 * . *b_vp is filled either with null or with the corresponding vnode, 756 * and 757 * . the only pair of vnodes that may be identical is a_vp and b_vp. 758 * 759 * On failure, a_dvp and b_dvp are left unlocked, and *a_dirent_ret, 760 * *a_vp, *b_dirent_ret, and *b_vp are left alone. 761 */ 762 static int 763 genfs_rename_lock(const struct genfs_rename_ops *ops, 764 struct mount *mp, kauth_cred_t cred, 765 int overlap_error, int a_dot_error, int b_dot_error, 766 struct vnode *a_dvp, struct componentname *a_cnp, bool a_missing_ok, 767 void *a_de_ret, struct vnode **a_vp_ret, 768 struct vnode *b_dvp, struct componentname *b_cnp, bool b_missing_ok, 769 void *b_de_ret, struct vnode **b_vp_ret) 770 { 771 struct vnode *a_vp, *b_vp; 772 int error; 773 774 KASSERT(ops != NULL); 775 KASSERT(mp != NULL); 776 KASSERT(a_dvp != NULL); 777 KASSERT(a_cnp != NULL); 778 KASSERT(a_vp_ret != NULL); 779 KASSERT(b_dvp != NULL); 780 KASSERT(b_cnp != NULL); 781 KASSERT(b_vp_ret != NULL); 782 KASSERT(a_dvp != b_dvp); 783 KASSERT(a_vp_ret != b_vp_ret); 784 KASSERT(a_dvp->v_type == VDIR); 785 KASSERT(b_dvp->v_type == VDIR); 786 KASSERT(a_dvp->v_mount == mp); 787 KASSERT(b_dvp->v_mount == mp); 788 KASSERT(a_missing_ok != b_missing_ok); 789 790 /* 791 * 1. Lock a_dvp. 792 */ 793 error = ops->gro_lock_directory(mp, a_dvp); 794 if (error) 795 goto fail0; 796 797 /* Did we lose a race with mount? */ 798 if (a_dvp->v_mountedhere != NULL) { 799 error = EBUSY; 800 goto fail1; 801 } 802 803 /* 804 * 2. Lookup a_vp. May lock/unlock a_vp. 805 */ 806 error = ops->gro_lookup(mp, a_dvp, a_cnp, a_de_ret, &a_vp); 807 if (error) { 808 if (a_missing_ok && (error == ENOENT)) 809 a_vp = NULL; 810 else 811 goto fail1; 812 } else { 813 KASSERT(a_vp != NULL); 814 815 /* Refuse to rename (over) `.'. */ 816 if (a_vp == a_dvp) { 817 error = a_dot_error; 818 goto fail2; 819 } 820 821 /* Reject rename("x", "x/y") or rename("x/y", "x"). */ 822 if (a_vp == b_dvp) { 823 error = overlap_error; 824 goto fail2; 825 } 826 } 827 828 KASSERT(a_vp != a_dvp); 829 KASSERT(a_vp != b_dvp); 830 831 /* 832 * 3. Lock a_vp, if it is a directory. 833 * 834 * We already ruled out a_vp == a_dvp (i.e., a_cnp is `.'), so 835 * this is not locking against self, and we already ruled out 836 * a_vp == b_dvp, so this won't cause subsequent locking of 837 * b_dvp to lock against self. 838 * 839 * If a_vp is a nondirectory, we can't hold it when we lookup 840 * b_vp in case (a) the file system can only lookup/lock/unlock 841 * and (b) b_vp turns out to be the same file as a_vp due to 842 * hard links -- and we can't even detect that case until after 843 * we've looked up b_vp. Fortunately, if a_vp is a 844 * nondirectory, then it is a leaf, so we can safely lock it 845 * last. 846 */ 847 if (a_vp != NULL && a_vp->v_type == VDIR) { 848 vn_lock(a_vp, LK_EXCLUSIVE | LK_RETRY); 849 KASSERT(a_vp->v_mount == mp); 850 /* Refuse to rename (over) a mount point. */ 851 if (a_vp->v_mountedhere != NULL) { 852 error = EBUSY; 853 goto fail3; 854 } 855 } 856 857 /* 858 * 4. Lock b_dvp. 859 */ 860 error = ops->gro_lock_directory(mp, b_dvp); 861 if (error) 862 goto fail3; 863 864 /* Did we lose a race with mount? */ 865 if (b_dvp->v_mountedhere != NULL) { 866 error = EBUSY; 867 goto fail4; 868 } 869 870 /* 871 * 5. Lookup b_vp. May lock/unlock b_vp. 872 */ 873 error = ops->gro_lookup(mp, b_dvp, b_cnp, b_de_ret, &b_vp); 874 if (error) { 875 if (b_missing_ok && (error == ENOENT)) 876 b_vp = NULL; 877 else 878 goto fail4; 879 } else { 880 KASSERT(b_vp != NULL); 881 882 /* Refuse to rename (over) `.'. */ 883 if (b_vp == b_dvp) { 884 error = b_dot_error; 885 goto fail5; 886 } 887 888 /* 889 * b_dvp must not be an ancestor of a_dvp, so if we 890 * find b_dvp/b_vp=a_dvp/a_vp something is wrong. 891 */ 892 if (b_vp == a_dvp) { 893 /* 894 * We have a directory hard link before us. 895 * XXX What error should this return? EDEADLK? 896 * Panic? 897 */ 898 error = EIO; 899 goto fail5; 900 } 901 } 902 KASSERT(b_vp != b_dvp); 903 KASSERT(b_vp != a_dvp); 904 905 /* 906 * 6. Lock a_vp, if it is a nondirectory. 907 * 908 * In this case a_vp is a leaf, so it is either equal to or 909 * incommensurate with b_vp, and so we can safely lock it at 910 * any point now. 911 */ 912 if (a_vp != NULL && a_vp->v_type != VDIR) { 913 vn_lock(a_vp, LK_EXCLUSIVE | LK_RETRY); 914 KASSERT(a_vp->v_mount == mp); 915 /* (not a directory so can't have anything mounted here) */ 916 } 917 918 /* 919 * 7. Lock b_vp, if it is not a_vp. 920 * 921 * b_vp and a_vp may the same inode if they are hard links to 922 * one another. 923 */ 924 if ((b_vp != NULL) && (b_vp != a_vp)) { 925 vn_lock(b_vp, LK_EXCLUSIVE | LK_RETRY); 926 KASSERT(b_vp->v_mount == mp); 927 /* Refuse to rename (over) a mount point. */ 928 if ((b_vp->v_type == VDIR) && (b_vp->v_mountedhere != NULL)) { 929 error = EBUSY; 930 goto fail6; 931 } 932 } 933 934 KASSERT(VOP_ISLOCKED(a_dvp) == LK_EXCLUSIVE); 935 KASSERT(VOP_ISLOCKED(b_dvp) == LK_EXCLUSIVE); 936 KASSERT(a_missing_ok || (a_vp != NULL)); 937 KASSERT(b_missing_ok || (b_vp != NULL)); 938 KASSERT((a_vp == NULL) || (VOP_ISLOCKED(a_vp) == LK_EXCLUSIVE)); 939 KASSERT((b_vp == NULL) || (VOP_ISLOCKED(b_vp) == LK_EXCLUSIVE)); 940 941 *a_vp_ret = a_vp; 942 *b_vp_ret = b_vp; 943 return 0; 944 945 fail6: if ((b_vp != NULL) && (b_vp != a_vp)) 946 VOP_UNLOCK(b_vp); 947 if (a_vp != NULL && a_vp->v_type != VDIR) 948 VOP_UNLOCK(a_vp); 949 fail5: if (b_vp != NULL) 950 vrele(b_vp); 951 fail4: VOP_UNLOCK(b_dvp); 952 fail3: if (a_vp != NULL && a_vp->v_type == VDIR) 953 VOP_UNLOCK(a_vp); 954 fail2: if (a_vp != NULL) 955 vrele(a_vp); 956 fail1: VOP_UNLOCK(a_dvp); 957 fail0: return error; 958 } 959 960 /* 961 * genfs_rename_exit: Unlock everything we locked for rename. 962 * 963 * fdvp and tdvp must be referenced. 964 * 965 * On entry, everything is locked, and fvp and tvp referenced. 966 * 967 * On exit, everything is unlocked, and fvp and tvp are released. 968 */ 969 static void 970 genfs_rename_exit(const struct genfs_rename_ops *ops, 971 struct mount *mp, 972 struct vnode *fdvp, struct vnode *fvp, 973 struct vnode *tdvp, struct vnode *tvp) 974 { 975 976 (void)ops; 977 KASSERT(ops != NULL); 978 KASSERT(mp != NULL); 979 KASSERT(fdvp != NULL); 980 KASSERT(fvp != NULL); 981 KASSERT(fdvp != fvp); 982 KASSERT(fdvp != tvp); 983 KASSERT(tdvp != tvp); 984 KASSERT(tdvp != fvp); 985 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE); 986 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 987 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 988 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 989 990 if ((tvp != NULL) && (tvp != fvp)) 991 VOP_UNLOCK(tvp); 992 VOP_UNLOCK(fvp); 993 if (tvp != NULL) 994 vrele(tvp); 995 if (tdvp != fdvp) 996 VOP_UNLOCK(tdvp); 997 vrele(fvp); 998 VOP_UNLOCK(fdvp); 999 } 1000 1001 /* 1002 * genfs_rename_remove: Remove the entry for the non-directory vp with 1003 * componentname cnp from the directory dvp, using the lookup results 1004 * de. It is the responsibility of gro_remove to purge the name cache. 1005 * 1006 * Everything must be locked and referenced. 1007 */ 1008 static int 1009 genfs_rename_remove(const struct genfs_rename_ops *ops, 1010 struct mount *mp, kauth_cred_t cred, 1011 struct vnode *dvp, struct componentname *cnp, void *de, struct vnode *vp, 1012 nlink_t *tvp_nlinkp) 1013 { 1014 int error; 1015 1016 KASSERT(ops != NULL); 1017 KASSERT(mp != NULL); 1018 KASSERT(dvp != NULL); 1019 KASSERT(cnp != NULL); 1020 KASSERT(vp != NULL); 1021 KASSERT(dvp != vp); 1022 KASSERT(dvp->v_type == VDIR); 1023 KASSERT(vp->v_type != VDIR); 1024 KASSERT(dvp->v_mount == mp); 1025 KASSERT(vp->v_mount == mp); 1026 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); 1027 KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); 1028 1029 error = ops->gro_remove_check_possible(mp, dvp, vp); 1030 if (error) 1031 return error; 1032 1033 error = ops->gro_remove_check_permitted(mp, cred, dvp, vp); 1034 error = kauth_authorize_vnode(cred, KAUTH_VNODE_DELETE, vp, dvp, 1035 error); 1036 if (error) 1037 return error; 1038 1039 error = ops->gro_remove(mp, cred, dvp, cnp, de, vp, tvp_nlinkp); 1040 if (error) 1041 return error; 1042 1043 return 0; 1044 } 1045 1046 static int 1047 genfs_ufslike_check_sticky(kauth_cred_t, mode_t, uid_t, struct vnode *, uid_t); 1048 1049 /* 1050 * genfs_ufslike_rename_check_possible: Check whether a rename is 1051 * possible independent of credentials, assuming UFS-like inode flag 1052 * semantics. clobber_p is true iff the target node already exists. 1053 */ 1054 int 1055 genfs_ufslike_rename_check_possible( 1056 unsigned long fdflags, unsigned long fflags, 1057 unsigned long tdflags, unsigned long tflags, bool clobber_p, 1058 unsigned long immutable, unsigned long append) 1059 { 1060 1061 if ((fdflags | fflags) & (immutable | append)) 1062 return EPERM; 1063 1064 if (tdflags & (immutable | (clobber_p? append : 0))) 1065 return EPERM; 1066 1067 if (clobber_p && (tflags & (immutable | append))) 1068 return EPERM; 1069 1070 return 0; 1071 } 1072 1073 /* 1074 * genfs_ufslike_rename_check_permitted: Check whether a rename is 1075 * permitted given our credentials, assuming UFS-like permission and 1076 * ownership semantics. 1077 * 1078 * The only pair of vnodes that may be identical is {fdvp, tdvp}. 1079 * 1080 * Everything must be locked and referenced. 1081 */ 1082 int 1083 genfs_ufslike_rename_check_permitted(kauth_cred_t cred, 1084 struct vnode *fdvp, mode_t fdmode, uid_t fduid, 1085 struct vnode *fvp, uid_t fuid, 1086 struct vnode *tdvp, mode_t tdmode, uid_t tduid, 1087 struct vnode *tvp, uid_t tuid) 1088 { 1089 int error; 1090 1091 KASSERT(fdvp != NULL); 1092 KASSERT(fvp != NULL); 1093 KASSERT(tdvp != NULL); 1094 KASSERT(fdvp != fvp); 1095 KASSERT(fdvp != tvp); 1096 KASSERT(tdvp != fvp); 1097 KASSERT(tdvp != tvp); 1098 KASSERT(fvp != tvp); 1099 KASSERT(fdvp->v_type == VDIR); 1100 KASSERT(tdvp->v_type == VDIR); 1101 KASSERT(fdvp->v_mount == fvp->v_mount); 1102 KASSERT(fdvp->v_mount == tdvp->v_mount); 1103 KASSERT((tvp == NULL) || (fdvp->v_mount == tvp->v_mount)); 1104 KASSERT(VOP_ISLOCKED(fdvp) == LK_EXCLUSIVE); 1105 KASSERT(VOP_ISLOCKED(fvp) == LK_EXCLUSIVE); 1106 KASSERT(VOP_ISLOCKED(tdvp) == LK_EXCLUSIVE); 1107 KASSERT((tvp == NULL) || (VOP_ISLOCKED(tvp) == LK_EXCLUSIVE)); 1108 1109 /* 1110 * We need to remove or change an entry in the source directory. 1111 */ 1112 error = VOP_ACCESS(fdvp, VWRITE, cred); 1113 if (error) 1114 return error; 1115 1116 /* 1117 * If we are changing directories, then we need to write to the 1118 * target directory to add or change an entry. Also, if fvp is 1119 * a directory, we need to write to it to change its `..' 1120 * entry. 1121 */ 1122 if (fdvp != tdvp) { 1123 error = VOP_ACCESS(tdvp, VWRITE, cred); 1124 if (error) 1125 return error; 1126 if (fvp->v_type == VDIR) { 1127 error = VOP_ACCESS(fvp, VWRITE, cred); 1128 if (error) 1129 return error; 1130 } 1131 } 1132 1133 error = genfs_ufslike_check_sticky(cred, fdmode, fduid, fvp, fuid); 1134 if (error) 1135 return error; 1136 1137 error = genfs_ufslike_check_sticky(cred, tdmode, tduid, tvp, tuid); 1138 if (error) 1139 return error; 1140 1141 return 0; 1142 } 1143 1144 /* 1145 * genfs_ufslike_remove_check_possible: Check whether a remove is 1146 * possible independent of credentials, assuming UFS-like inode flag 1147 * semantics. 1148 */ 1149 int 1150 genfs_ufslike_remove_check_possible(unsigned long dflags, unsigned long flags, 1151 unsigned long immutable, unsigned long append) 1152 { 1153 1154 /* 1155 * We want to delete the entry. If the directory is immutable, 1156 * we can't write to it to delete the entry. If the directory 1157 * is append-only, the only change we can make is to add 1158 * entries, so we can't delete entries. If the node is 1159 * immutable, we can't change the links to it, so we can't 1160 * delete the entry. If the node is append-only...well, this 1161 * is what UFS does. 1162 */ 1163 if ((dflags | flags) & (immutable | append)) 1164 return EPERM; 1165 1166 return 0; 1167 } 1168 1169 /* 1170 * genfs_ufslike_remove_check_permitted: Check whether a remove is 1171 * permitted given our credentials, assuming UFS-like permission and 1172 * ownership semantics. 1173 * 1174 * Everything must be locked and referenced. 1175 */ 1176 int 1177 genfs_ufslike_remove_check_permitted(kauth_cred_t cred, 1178 struct vnode *dvp, mode_t dmode, uid_t duid, 1179 struct vnode *vp, uid_t uid) 1180 { 1181 int error; 1182 1183 KASSERT(dvp != NULL); 1184 KASSERT(vp != NULL); 1185 KASSERT(dvp != vp); 1186 KASSERT(dvp->v_type == VDIR); 1187 KASSERT(vp->v_type != VDIR); 1188 KASSERT(dvp->v_mount == vp->v_mount); 1189 KASSERT(VOP_ISLOCKED(dvp) == LK_EXCLUSIVE); 1190 KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE); 1191 1192 /* 1193 * We need to write to the directory to remove from it. 1194 */ 1195 error = VOP_ACCESS(dvp, VWRITE, cred); 1196 if (error) 1197 return error; 1198 1199 error = genfs_ufslike_check_sticky(cred, dmode, duid, vp, uid); 1200 if (error) 1201 return error; 1202 1203 return 0; 1204 } 1205 1206 /* 1207 * genfs_ufslike_check_sticky: Check whether a party with credentials 1208 * cred may change an entry in a sticky directory, assuming UFS-like 1209 * permission, ownership, and stickiness semantics: If the directory is 1210 * sticky and the entry exists, the user must own either the directory 1211 * or the entry's node in order to change the entry. 1212 * 1213 * Everything must be locked and referenced. 1214 */ 1215 int 1216 genfs_ufslike_check_sticky(kauth_cred_t cred, mode_t dmode, uid_t duid, 1217 struct vnode *vp, uid_t uid) 1218 { 1219 1220 if ((dmode & S_ISTXT) && (vp != NULL)) 1221 return genfs_can_sticky(vp, cred, duid, uid); 1222 1223 return 0; 1224 } 1225