Skip to content

Commit b308570

Browse files
committed
Merge tag 'pull-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "A couple of fixes, one of them for this cycle regression..." * tag 'pull-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: vfs: vfs_tmpfile: ensure O_EXCL flag is enforced fs: use acquire ordering in __fget_light()
2 parents ca66e58 + 406c706 commit b308570

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

fs/file.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,16 @@ static unsigned long __fget_light(unsigned int fd, fmode_t mask)
10031003
struct files_struct *files = current->files;
10041004
struct file *file;
10051005

1006-
if (atomic_read(&files->count) == 1) {
1006+
/*
1007+
* If another thread is concurrently calling close_fd() followed
1008+
* by put_files_struct(), we must not observe the old table
1009+
* entry combined with the new refcount - otherwise we could
1010+
* return a file that is concurrently being freed.
1011+
*
1012+
* atomic_read_acquire() pairs with atomic_dec_and_test() in
1013+
* put_files_struct().
1014+
*/
1015+
if (atomic_read_acquire(&files->count) == 1) {
10071016
file = files_lookup_fd_raw(files, fd);
10081017
if (!file || unlikely(file->f_mode & mask))
10091018
return 0;

fs/namei.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3591,6 +3591,7 @@ static int vfs_tmpfile(struct user_namespace *mnt_userns,
35913591
struct inode *dir = d_inode(parentpath->dentry);
35923592
struct inode *inode;
35933593
int error;
3594+
int open_flag = file->f_flags;
35943595

35953596
/* we want directory to be writable */
35963597
error = inode_permission(mnt_userns, dir, MAY_WRITE | MAY_EXEC);
@@ -3613,7 +3614,7 @@ static int vfs_tmpfile(struct user_namespace *mnt_userns,
36133614
if (error)
36143615
return error;
36153616
inode = file_inode(file);
3616-
if (!(file->f_flags & O_EXCL)) {
3617+
if (!(open_flag & O_EXCL)) {
36173618
spin_lock(&inode->i_lock);
36183619
inode->i_state |= I_LINKABLE;
36193620
spin_unlock(&inode->i_lock);

0 commit comments

Comments
 (0)