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