Skip to content

Commit 406c706

Browse files
petegriffinAl Viro
authored andcommitted
vfs: vfs_tmpfile: ensure O_EXCL flag is enforced
If O_EXCL is *not* specified, then linkat() can be used to link the temporary file into the filesystem. If O_EXCL is specified then linkat() should fail (-1). After commit 863f144 ("vfs: open inside ->tmpfile()") the O_EXCL flag is no longer honored by the vfs layer for tmpfile, which means the file can be linked even if O_EXCL flag is specified, which is a change in behaviour for userspace! The open flags was previously passed as a parameter, so it was uneffected by the changes to file->f_flags caused by finish_open(). This patch fixes the issue by storing file->f_flags in a local variable so the O_EXCL test logic is restored. This regression was detected by Android CTS Bionic fcntl() tests running on android-mainline [1]. [1] https://android.googlesource.com/platform/bionic/+/ refs/heads/master/tests/fcntl_test.cpp#352 Fixes: 863f144 ("vfs: open inside ->tmpfile()") Acked-by: Miklos Szeredi <[email protected]> Tested-by: Will McVicker <[email protected]> Signed-off-by: Peter Griffin <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent 7ee47dc commit 406c706

File tree

1 file changed

+2
-1
lines changed

1 file changed

+2
-1
lines changed

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)