hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/namei.c
....@@ -2724,7 +2724,7 @@
27242724 dput(path->dentry);
27252725 path->dentry = parent;
27262726 child = d_hash_and_lookup(parent, &this);
2727
- if (!child)
2727
+ if (IS_ERR_OR_NULL(child))
27282728 return -ENOENT;
27292729
27302730 path->dentry = child;
....@@ -2866,8 +2866,8 @@
28662866 return p;
28672867 }
28682868
2869
- inode_lock_nested(p1->d_inode, I_MUTEX_PARENT);
2870
- inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2);
2869
+ lock_two_inodes(p1->d_inode, p2->d_inode,
2870
+ I_MUTEX_PARENT, I_MUTEX_PARENT2);
28712871 return NULL;
28722872 }
28732873 EXPORT_SYMBOL(lock_rename);
....@@ -2882,6 +2882,63 @@
28822882 }
28832883 EXPORT_SYMBOL(unlock_rename);
28842884
2885
+/**
2886
+ * mode_strip_umask - handle vfs umask stripping
2887
+ * @dir: parent directory of the new inode
2888
+ * @mode: mode of the new inode to be created in @dir
2889
+ *
2890
+ * Umask stripping depends on whether or not the filesystem supports POSIX
2891
+ * ACLs. If the filesystem doesn't support it umask stripping is done directly
2892
+ * in here. If the filesystem does support POSIX ACLs umask stripping is
2893
+ * deferred until the filesystem calls posix_acl_create().
2894
+ *
2895
+ * Returns: mode
2896
+ */
2897
+static inline umode_t mode_strip_umask(const struct inode *dir, umode_t mode)
2898
+{
2899
+ if (!IS_POSIXACL(dir))
2900
+ mode &= ~current_umask();
2901
+ return mode;
2902
+}
2903
+
2904
+/**
2905
+ * vfs_prepare_mode - prepare the mode to be used for a new inode
2906
+ * @dir: parent directory of the new inode
2907
+ * @mode: mode of the new inode
2908
+ * @mask_perms: allowed permission by the vfs
2909
+ * @type: type of file to be created
2910
+ *
2911
+ * This helper consolidates and enforces vfs restrictions on the @mode of a new
2912
+ * object to be created.
2913
+ *
2914
+ * Umask stripping depends on whether the filesystem supports POSIX ACLs (see
2915
+ * the kernel documentation for mode_strip_umask()). Moving umask stripping
2916
+ * after setgid stripping allows the same ordering for both non-POSIX ACL and
2917
+ * POSIX ACL supporting filesystems.
2918
+ *
2919
+ * Note that it's currently valid for @type to be 0 if a directory is created.
2920
+ * Filesystems raise that flag individually and we need to check whether each
2921
+ * filesystem can deal with receiving S_IFDIR from the vfs before we enforce a
2922
+ * non-zero type.
2923
+ *
2924
+ * Returns: mode to be passed to the filesystem
2925
+ */
2926
+static inline umode_t vfs_prepare_mode(const struct inode *dir, umode_t mode,
2927
+ umode_t mask_perms, umode_t type)
2928
+{
2929
+ mode = mode_strip_sgid(dir, mode);
2930
+ mode = mode_strip_umask(dir, mode);
2931
+
2932
+ /*
2933
+ * Apply the vfs mandated allowed permission mask and set the type of
2934
+ * file to be created before we call into the filesystem.
2935
+ */
2936
+ mode &= (mask_perms & ~S_IFMT);
2937
+ mode |= (type & S_IFMT);
2938
+
2939
+ return mode;
2940
+}
2941
+
28852942 int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
28862943 bool want_excl)
28872944 {
....@@ -2891,8 +2948,8 @@
28912948
28922949 if (!dir->i_op->create)
28932950 return -EACCES; /* shouldn't it be ENOSYS? */
2894
- mode &= S_IALLUGO;
2895
- mode |= S_IFREG;
2951
+
2952
+ mode = vfs_prepare_mode(dir, mode, S_IALLUGO, S_IFREG);
28962953 error = security_inode_create(dir, dentry, mode);
28972954 if (error)
28982955 return error;
....@@ -3156,8 +3213,7 @@
31563213 if (open_flag & O_CREAT) {
31573214 if (open_flag & O_EXCL)
31583215 open_flag &= ~O_TRUNC;
3159
- if (!IS_POSIXACL(dir->d_inode))
3160
- mode &= ~current_umask();
3216
+ mode = vfs_prepare_mode(dir->d_inode, mode, mode, mode);
31613217 if (likely(got_write))
31623218 create_error = may_o_create(&nd->path, dentry, mode);
31633219 else
....@@ -3370,8 +3426,7 @@
33703426 child = d_alloc(dentry, &slash_name);
33713427 if (unlikely(!child))
33723428 goto out_err;
3373
- if (!IS_POSIXACL(dir))
3374
- mode &= ~current_umask();
3429
+ mode = vfs_prepare_mode(dir, mode, mode, mode);
33753430 error = dir->i_op->tmpfile(dir, child, mode);
33763431 if (error)
33773432 goto out_err;
....@@ -3632,6 +3687,7 @@
36323687 if (!dir->i_op->mknod)
36333688 return -EPERM;
36343689
3690
+ mode = vfs_prepare_mode(dir, mode, mode, mode);
36353691 error = devcgroup_inode_mknod(mode, dev);
36363692 if (error)
36373693 return error;
....@@ -3680,9 +3736,8 @@
36803736 if (IS_ERR(dentry))
36813737 return PTR_ERR(dentry);
36823738
3683
- if (!IS_POSIXACL(path.dentry->d_inode))
3684
- mode &= ~current_umask();
3685
- error = security_path_mknod(&path, dentry, mode, dev);
3739
+ error = security_path_mknod(&path, dentry,
3740
+ mode_strip_umask(path.dentry->d_inode, mode), dev);
36863741 if (error)
36873742 goto out;
36883743 switch (mode & S_IFMT) {
....@@ -3730,7 +3785,7 @@
37303785 if (!dir->i_op->mkdir)
37313786 return -EPERM;
37323787
3733
- mode &= (S_IRWXUGO|S_ISVTX);
3788
+ mode = vfs_prepare_mode(dir, mode, S_IRWXUGO | S_ISVTX, 0);
37343789 error = security_inode_mkdir(dir, dentry, mode);
37353790 if (error)
37363791 return error;
....@@ -3757,9 +3812,8 @@
37573812 if (IS_ERR(dentry))
37583813 return PTR_ERR(dentry);
37593814
3760
- if (!IS_POSIXACL(path.dentry->d_inode))
3761
- mode &= ~current_umask();
3762
- error = security_path_mkdir(&path, dentry, mode);
3815
+ error = security_path_mkdir(&path, dentry,
3816
+ mode_strip_umask(path.dentry->d_inode, mode));
37633817 if (!error)
37643818 error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
37653819 done_path_create(&path, dentry);
....@@ -4294,7 +4348,7 @@
42944348 * sb->s_vfs_rename_mutex. We might be more accurate, but that's another
42954349 * story.
42964350 * c) we have to lock _four_ objects - parents and victim (if it exists),
4297
- * and source (if it is not a directory).
4351
+ * and source.
42984352 * And that - after we got ->i_mutex on parents (until then we don't know
42994353 * whether the target exists). Solution: try to be smart with locking
43004354 * order for inodes. We rely on the fact that tree topology may change
....@@ -4371,10 +4425,16 @@
43714425
43724426 take_dentry_name_snapshot(&old_name, old_dentry);
43734427 dget(new_dentry);
4374
- if (!is_dir || (flags & RENAME_EXCHANGE))
4375
- lock_two_nondirectories(source, target);
4376
- else if (target)
4377
- inode_lock(target);
4428
+ /*
4429
+ * Lock all moved children. Moved directories may need to change parent
4430
+ * pointer so they need the lock to prevent against concurrent
4431
+ * directory changes moving parent pointer. For regular files we've
4432
+ * historically always done this. The lockdep locking subclasses are
4433
+ * somewhat arbitrary but RENAME_EXCHANGE in particular can swap
4434
+ * regular files and directories so it's difficult to tell which
4435
+ * subclasses to use.
4436
+ */
4437
+ lock_two_inodes(source, target, I_MUTEX_NORMAL, I_MUTEX_NONDIR2);
43784438
43794439 error = -EBUSY;
43804440 if (is_local_mountpoint(old_dentry) || is_local_mountpoint(new_dentry))
....@@ -4418,9 +4478,8 @@
44184478 d_exchange(old_dentry, new_dentry);
44194479 }
44204480 out:
4421
- if (!is_dir || (flags & RENAME_EXCHANGE))
4422
- unlock_two_nondirectories(source, target);
4423
- else if (target)
4481
+ inode_unlock(source);
4482
+ if (target)
44244483 inode_unlock(target);
44254484 dput(new_dentry);
44264485 if (!error) {