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 vfs fix from Al Viro:
"Fix a use-after-free in do_last() handling of sysctl_protected_...
checks.

The use-after-free normally doesn't happen there, but race with
rename() and it becomes possible"

* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
do_last(): fetch directory ->i_mode and ->i_uid before it's too late

+10 -7
+10 -7
fs/namei.c
··· 1001 1001 * may_create_in_sticky - Check whether an O_CREAT open in a sticky directory 1002 1002 * should be allowed, or not, on files that already 1003 1003 * exist. 1004 - * @dir: the sticky parent directory 1004 + * @dir_mode: mode bits of directory 1005 + * @dir_uid: owner of directory 1005 1006 * @inode: the inode of the file to open 1006 1007 * 1007 1008 * Block an O_CREAT open of a FIFO (or a regular file) when: ··· 1018 1017 * 1019 1018 * Returns 0 if the open is allowed, -ve on error. 1020 1019 */ 1021 - static int may_create_in_sticky(struct dentry * const dir, 1020 + static int may_create_in_sticky(umode_t dir_mode, kuid_t dir_uid, 1022 1021 struct inode * const inode) 1023 1022 { 1024 1023 if ((!sysctl_protected_fifos && S_ISFIFO(inode->i_mode)) || 1025 1024 (!sysctl_protected_regular && S_ISREG(inode->i_mode)) || 1026 - likely(!(dir->d_inode->i_mode & S_ISVTX)) || 1027 - uid_eq(inode->i_uid, dir->d_inode->i_uid) || 1025 + likely(!(dir_mode & S_ISVTX)) || 1026 + uid_eq(inode->i_uid, dir_uid) || 1028 1027 uid_eq(current_fsuid(), inode->i_uid)) 1029 1028 return 0; 1030 1029 1031 - if (likely(dir->d_inode->i_mode & 0002) || 1032 - (dir->d_inode->i_mode & 0020 && 1030 + if (likely(dir_mode & 0002) || 1031 + (dir_mode & 0020 && 1033 1032 ((sysctl_protected_fifos >= 2 && S_ISFIFO(inode->i_mode)) || 1034 1033 (sysctl_protected_regular >= 2 && S_ISREG(inode->i_mode))))) { 1035 1034 const char *operation = S_ISFIFO(inode->i_mode) ? ··· 3202 3201 struct file *file, const struct open_flags *op) 3203 3202 { 3204 3203 struct dentry *dir = nd->path.dentry; 3204 + kuid_t dir_uid = dir->d_inode->i_uid; 3205 + umode_t dir_mode = dir->d_inode->i_mode; 3205 3206 int open_flag = op->open_flag; 3206 3207 bool will_truncate = (open_flag & O_TRUNC) != 0; 3207 3208 bool got_write = false; ··· 3334 3331 error = -EISDIR; 3335 3332 if (d_is_dir(nd->path.dentry)) 3336 3333 goto out; 3337 - error = may_create_in_sticky(dir, 3334 + error = may_create_in_sticky(dir_mode, dir_uid, 3338 3335 d_backing_inode(nd->path.dentry)); 3339 3336 if (unlikely(error)) 3340 3337 goto out;