Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull misc vfs fixes from Al Viro:
"Assorted fixes all over the place; some of that is -stable fodder,
some regressions from the last window"

* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
ecryptfs_lookup_interpose(): lower_dentry->d_parent is not stable either
ecryptfs_lookup_interpose(): lower_dentry->d_inode is not stable
ecryptfs: fix unlink and rmdir in face of underlying fs modifications
audit_get_nd(): don't unlock parent too early
exportfs_decode_fh(): negative pinned may become positive without the parent locked
cgroup: don't put ERR_PTR() into fc->root
autofs: fix a leak in autofs_expire_indirect()
aio: Fix io_pgetevents() struct __compat_aio_sigset layout
fs/namespace.c: fix use-after-free of mount in mnt_warn_timestamp_expiry()

+91 -61
+5 -5
fs/aio.c
··· 2179 2179 #ifdef CONFIG_COMPAT 2180 2180 2181 2181 struct __compat_aio_sigset { 2182 - compat_sigset_t __user *sigmask; 2182 + compat_uptr_t sigmask; 2183 2183 compat_size_t sigsetsize; 2184 2184 }; 2185 2185 ··· 2193 2193 struct old_timespec32 __user *, timeout, 2194 2194 const struct __compat_aio_sigset __user *, usig) 2195 2195 { 2196 - struct __compat_aio_sigset ksig = { NULL, }; 2196 + struct __compat_aio_sigset ksig = { 0, }; 2197 2197 struct timespec64 t; 2198 2198 bool interrupted; 2199 2199 int ret; ··· 2204 2204 if (usig && copy_from_user(&ksig, usig, sizeof(ksig))) 2205 2205 return -EFAULT; 2206 2206 2207 - ret = set_compat_user_sigmask(ksig.sigmask, ksig.sigsetsize); 2207 + ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), ksig.sigsetsize); 2208 2208 if (ret) 2209 2209 return ret; 2210 2210 ··· 2228 2228 struct __kernel_timespec __user *, timeout, 2229 2229 const struct __compat_aio_sigset __user *, usig) 2230 2230 { 2231 - struct __compat_aio_sigset ksig = { NULL, }; 2231 + struct __compat_aio_sigset ksig = { 0, }; 2232 2232 struct timespec64 t; 2233 2233 bool interrupted; 2234 2234 int ret; ··· 2239 2239 if (usig && copy_from_user(&ksig, usig, sizeof(ksig))) 2240 2240 return -EFAULT; 2241 2241 2242 - ret = set_compat_user_sigmask(ksig.sigmask, ksig.sigsetsize); 2242 + ret = set_compat_user_sigmask(compat_ptr(ksig.sigmask), ksig.sigsetsize); 2243 2243 if (ret) 2244 2244 return ret; 2245 2245
+3 -2
fs/autofs/expire.c
··· 459 459 */ 460 460 how &= ~AUTOFS_EXP_LEAVES; 461 461 found = should_expire(expired, mnt, timeout, how); 462 - if (!found || found != expired) 463 - /* Something has changed, continue */ 462 + if (found != expired) { // something has changed, continue 463 + dput(found); 464 464 goto next; 465 + } 465 466 466 467 if (expired != dentry) 467 468 dput(dentry);
+53 -31
fs/ecryptfs/inode.c
··· 128 128 struct inode *inode) 129 129 { 130 130 struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); 131 - struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); 132 131 struct dentry *lower_dir_dentry; 132 + struct inode *lower_dir_inode; 133 133 int rc; 134 134 135 - dget(lower_dentry); 136 - lower_dir_dentry = lock_parent(lower_dentry); 137 - rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL); 135 + lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); 136 + lower_dir_inode = d_inode(lower_dir_dentry); 137 + inode_lock_nested(lower_dir_inode, I_MUTEX_PARENT); 138 + dget(lower_dentry); // don't even try to make the lower negative 139 + if (lower_dentry->d_parent != lower_dir_dentry) 140 + rc = -EINVAL; 141 + else if (d_unhashed(lower_dentry)) 142 + rc = -EINVAL; 143 + else 144 + rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL); 138 145 if (rc) { 139 146 printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); 140 147 goto out_unlock; ··· 149 142 fsstack_copy_attr_times(dir, lower_dir_inode); 150 143 set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink); 151 144 inode->i_ctime = dir->i_ctime; 152 - d_drop(dentry); 153 145 out_unlock: 154 - unlock_dir(lower_dir_dentry); 155 146 dput(lower_dentry); 147 + inode_unlock(lower_dir_inode); 148 + if (!rc) 149 + d_drop(dentry); 156 150 return rc; 157 151 } 158 152 ··· 319 311 static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry, 320 312 struct dentry *lower_dentry) 321 313 { 322 - struct inode *inode, *lower_inode = d_inode(lower_dentry); 314 + struct path *path = ecryptfs_dentry_to_lower_path(dentry->d_parent); 315 + struct inode *inode, *lower_inode; 323 316 struct ecryptfs_dentry_info *dentry_info; 324 - struct vfsmount *lower_mnt; 325 317 int rc = 0; 326 318 327 319 dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL); ··· 330 322 return ERR_PTR(-ENOMEM); 331 323 } 332 324 333 - lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); 334 325 fsstack_copy_attr_atime(d_inode(dentry->d_parent), 335 - d_inode(lower_dentry->d_parent)); 326 + d_inode(path->dentry)); 336 327 BUG_ON(!d_count(lower_dentry)); 337 328 338 329 ecryptfs_set_dentry_private(dentry, dentry_info); 339 - dentry_info->lower_path.mnt = lower_mnt; 330 + dentry_info->lower_path.mnt = mntget(path->mnt); 340 331 dentry_info->lower_path.dentry = lower_dentry; 341 332 342 - if (d_really_is_negative(lower_dentry)) { 333 + /* 334 + * negative dentry can go positive under us here - its parent is not 335 + * locked. That's OK and that could happen just as we return from 336 + * ecryptfs_lookup() anyway. Just need to be careful and fetch 337 + * ->d_inode only once - it's not stable here. 338 + */ 339 + lower_inode = READ_ONCE(lower_dentry->d_inode); 340 + 341 + if (!lower_inode) { 343 342 /* We want to add because we couldn't find in lower */ 344 343 d_add(dentry, NULL); 345 344 return NULL; ··· 527 512 { 528 513 struct dentry *lower_dentry; 529 514 struct dentry *lower_dir_dentry; 515 + struct inode *lower_dir_inode; 530 516 int rc; 531 517 532 518 lower_dentry = ecryptfs_dentry_to_lower(dentry); 533 - dget(dentry); 534 - lower_dir_dentry = lock_parent(lower_dentry); 535 - dget(lower_dentry); 536 - rc = vfs_rmdir(d_inode(lower_dir_dentry), lower_dentry); 537 - dput(lower_dentry); 538 - if (!rc && d_really_is_positive(dentry)) 519 + lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); 520 + lower_dir_inode = d_inode(lower_dir_dentry); 521 + 522 + inode_lock_nested(lower_dir_inode, I_MUTEX_PARENT); 523 + dget(lower_dentry); // don't even try to make the lower negative 524 + if (lower_dentry->d_parent != lower_dir_dentry) 525 + rc = -EINVAL; 526 + else if (d_unhashed(lower_dentry)) 527 + rc = -EINVAL; 528 + else 529 + rc = vfs_rmdir(lower_dir_inode, lower_dentry); 530 + if (!rc) { 539 531 clear_nlink(d_inode(dentry)); 540 - fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); 541 - set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink); 542 - unlock_dir(lower_dir_dentry); 532 + fsstack_copy_attr_times(dir, lower_dir_inode); 533 + set_nlink(dir, lower_dir_inode->i_nlink); 534 + } 535 + dput(lower_dentry); 536 + inode_unlock(lower_dir_inode); 543 537 if (!rc) 544 538 d_drop(dentry); 545 - dput(dentry); 546 539 return rc; 547 540 } 548 541 ··· 588 565 struct dentry *lower_new_dentry; 589 566 struct dentry *lower_old_dir_dentry; 590 567 struct dentry *lower_new_dir_dentry; 591 - struct dentry *trap = NULL; 568 + struct dentry *trap; 592 569 struct inode *target_inode; 593 570 594 571 if (flags) 595 572 return -EINVAL; 596 573 574 + lower_old_dir_dentry = ecryptfs_dentry_to_lower(old_dentry->d_parent); 575 + lower_new_dir_dentry = ecryptfs_dentry_to_lower(new_dentry->d_parent); 576 + 597 577 lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); 598 578 lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); 599 - dget(lower_old_dentry); 600 - dget(lower_new_dentry); 601 - lower_old_dir_dentry = dget_parent(lower_old_dentry); 602 - lower_new_dir_dentry = dget_parent(lower_new_dentry); 579 + 603 580 target_inode = d_inode(new_dentry); 581 + 604 582 trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); 583 + dget(lower_new_dentry); 605 584 rc = -EINVAL; 606 585 if (lower_old_dentry->d_parent != lower_old_dir_dentry) 607 586 goto out_lock; ··· 631 606 if (new_dir != old_dir) 632 607 fsstack_copy_attr_all(old_dir, d_inode(lower_old_dir_dentry)); 633 608 out_lock: 634 - unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); 635 - dput(lower_new_dir_dentry); 636 - dput(lower_old_dir_dentry); 637 609 dput(lower_new_dentry); 638 - dput(lower_old_dentry); 610 + unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); 639 611 return rc; 640 612 } 641 613
+19 -12
fs/exportfs/expfs.c
··· 519 519 * inode is actually connected to the parent. 520 520 */ 521 521 err = exportfs_get_name(mnt, target_dir, nbuf, result); 522 - if (!err) { 523 - inode_lock(target_dir->d_inode); 524 - nresult = lookup_one_len(nbuf, target_dir, 525 - strlen(nbuf)); 526 - inode_unlock(target_dir->d_inode); 527 - if (!IS_ERR(nresult)) { 528 - if (nresult->d_inode) { 529 - dput(result); 530 - result = nresult; 531 - } else 532 - dput(nresult); 533 - } 522 + if (err) { 523 + dput(target_dir); 524 + goto err_result; 534 525 } 535 526 527 + inode_lock(target_dir->d_inode); 528 + nresult = lookup_one_len(nbuf, target_dir, strlen(nbuf)); 529 + if (!IS_ERR(nresult)) { 530 + if (unlikely(nresult->d_inode != result->d_inode)) { 531 + dput(nresult); 532 + nresult = ERR_PTR(-ESTALE); 533 + } 534 + } 535 + inode_unlock(target_dir->d_inode); 536 536 /* 537 537 * At this point we are done with the parent, but it's pinned 538 538 * by the child dentry anyway. 539 539 */ 540 540 dput(target_dir); 541 + 542 + if (IS_ERR(nresult)) { 543 + err = PTR_ERR(nresult); 544 + goto err_result; 545 + } 546 + dput(result); 547 + result = nresult; 541 548 542 549 /* 543 550 * And finally make sure the dentry is actually acceptable
+7 -8
fs/namespace.c
··· 2478 2478 2479 2479 time64_to_tm(sb->s_time_max, 0, &tm); 2480 2480 2481 - pr_warn("Mounted %s file system at %s supports timestamps until %04ld (0x%llx)\n", 2482 - sb->s_type->name, mntpath, 2481 + pr_warn("%s filesystem being %s at %s supports timestamps until %04ld (0x%llx)\n", 2482 + sb->s_type->name, 2483 + is_mounted(mnt) ? "remounted" : "mounted", 2484 + mntpath, 2483 2485 tm.tm_year+1900, (unsigned long long)sb->s_time_max); 2484 2486 2485 2487 free_page((unsigned long)buf); ··· 2766 2764 if (IS_ERR(mnt)) 2767 2765 return PTR_ERR(mnt); 2768 2766 2769 - error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags); 2770 - if (error < 0) { 2771 - mntput(mnt); 2772 - return error; 2773 - } 2774 - 2775 2767 mnt_warn_timestamp_expiry(mountpoint, mnt); 2776 2768 2769 + error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags); 2770 + if (error < 0) 2771 + mntput(mnt); 2777 2772 return error; 2778 2773 } 2779 2774
+1 -1
kernel/audit_watch.c
··· 351 351 struct dentry *d = kern_path_locked(watch->path, parent); 352 352 if (IS_ERR(d)) 353 353 return PTR_ERR(d); 354 - inode_unlock(d_backing_inode(parent->dentry)); 355 354 if (d_is_positive(d)) { 356 355 /* update watch filter fields */ 357 356 watch->dev = d->d_sb->s_dev; 358 357 watch->ino = d_backing_inode(d)->i_ino; 359 358 } 359 + inode_unlock(d_backing_inode(parent->dentry)); 360 360 dput(d); 361 361 return 0; 362 362 }
+3 -2
kernel/cgroup/cgroup.c
··· 2119 2119 2120 2120 nsdentry = kernfs_node_dentry(cgrp->kn, sb); 2121 2121 dput(fc->root); 2122 - fc->root = nsdentry; 2123 2122 if (IS_ERR(nsdentry)) { 2124 - ret = PTR_ERR(nsdentry); 2125 2123 deactivate_locked_super(sb); 2124 + ret = PTR_ERR(nsdentry); 2125 + nsdentry = NULL; 2126 2126 } 2127 + fc->root = nsdentry; 2127 2128 } 2128 2129 2129 2130 if (!ctx->kfc.new_sb_created)