@@ -3583,44 +3583,44 @@ static int do_open(struct nameidata *nd,
35833583 * On non-idmapped mounts or if permission checking is to be performed on the
35843584 * raw inode simply passs init_user_ns.
35853585 */
3586- static struct dentry * vfs_tmpfile (struct user_namespace * mnt_userns ,
3587- struct dentry * dentry , umode_t mode , int open_flag )
3586+ static int vfs_tmpfile (struct user_namespace * mnt_userns ,
3587+ const struct path * parentpath ,
3588+ struct file * file , umode_t mode )
35883589{
3589- struct dentry * child = NULL ;
3590- struct inode * dir = dentry -> d_inode ;
3590+ struct dentry * child ;
3591+ struct inode * dir = d_inode ( parentpath -> dentry ) ;
35913592 struct inode * inode ;
35923593 int error ;
35933594
35943595 /* we want directory to be writable */
35953596 error = inode_permission (mnt_userns , dir , MAY_WRITE | MAY_EXEC );
35963597 if (error )
3597- goto out_err ;
3598- error = - EOPNOTSUPP ;
3598+ return error ;
35993599 if (!dir -> i_op -> tmpfile )
3600- goto out_err ;
3601- error = - ENOMEM ;
3602- child = d_alloc (dentry , & slash_name );
3600+ return - EOPNOTSUPP ;
3601+ child = d_alloc (parentpath -> dentry , & slash_name );
36033602 if (unlikely (!child ))
3604- goto out_err ;
3603+ return - ENOMEM ;
3604+ file -> f_path .mnt = parentpath -> mnt ;
3605+ file -> f_path .dentry = child ;
36053606 mode = vfs_prepare_mode (mnt_userns , dir , mode , mode , mode );
36063607 error = dir -> i_op -> tmpfile (mnt_userns , dir , child , mode );
3608+ error = finish_open_simple (file , error );
3609+ dput (child );
36073610 if (error )
3608- goto out_err ;
3609- error = - ENOENT ;
3610- inode = child -> d_inode ;
3611- if (unlikely (!inode ))
3612- goto out_err ;
3613- if (!(open_flag & O_EXCL )) {
3611+ return error ;
3612+ /* Don't check for other permissions, the inode was just created */
3613+ error = may_open (mnt_userns , & file -> f_path , 0 , file -> f_flags );
3614+ if (error )
3615+ return error ;
3616+ inode = file_inode (file );
3617+ if (!(file -> f_flags & O_EXCL )) {
36143618 spin_lock (& inode -> i_lock );
36153619 inode -> i_state |= I_LINKABLE ;
36163620 spin_unlock (& inode -> i_lock );
36173621 }
36183622 ima_post_create_tmpfile (mnt_userns , inode );
3619- return child ;
3620-
3621- out_err :
3622- dput (child );
3623- return ERR_PTR (error );
3623+ return 0 ;
36243624}
36253625
36263626/**
@@ -3641,25 +3641,15 @@ struct file *vfs_tmpfile_open(struct user_namespace *mnt_userns,
36413641{
36423642 struct file * file ;
36433643 int error ;
3644- struct path path = { .mnt = parentpath -> mnt };
3645-
3646- path .dentry = vfs_tmpfile (mnt_userns , parentpath -> dentry , mode , open_flag );
3647- if (IS_ERR (path .dentry ))
3648- return ERR_CAST (path .dentry );
3649-
3650- error = may_open (mnt_userns , & path , 0 , open_flag );
3651- file = ERR_PTR (error );
3652- if (error )
3653- goto out_dput ;
3654-
3655- /*
3656- * This relies on the "noaccount" property of fake open, otherwise
3657- * equivalent to dentry_open().
3658- */
3659- file = open_with_fake_path (& path , open_flag , d_inode (path .dentry ), cred );
3660- out_dput :
3661- dput (path .dentry );
36623644
3645+ file = alloc_empty_file_noaccount (open_flag , cred );
3646+ if (!IS_ERR (file )) {
3647+ error = vfs_tmpfile (mnt_userns , parentpath , file , mode );
3648+ if (error ) {
3649+ fput (file );
3650+ file = ERR_PTR (error );
3651+ }
3652+ }
36633653 return file ;
36643654}
36653655EXPORT_SYMBOL (vfs_tmpfile_open );
@@ -3669,26 +3659,19 @@ static int do_tmpfile(struct nameidata *nd, unsigned flags,
36693659 struct file * file )
36703660{
36713661 struct user_namespace * mnt_userns ;
3672- struct dentry * child ;
36733662 struct path path ;
36743663 int error = path_lookupat (nd , flags | LOOKUP_DIRECTORY , & path );
3664+
36753665 if (unlikely (error ))
36763666 return error ;
36773667 error = mnt_want_write (path .mnt );
36783668 if (unlikely (error ))
36793669 goto out ;
36803670 mnt_userns = mnt_user_ns (path .mnt );
3681- child = vfs_tmpfile (mnt_userns , path .dentry , op -> mode , op -> open_flag );
3682- error = PTR_ERR (child );
3683- if (IS_ERR (child ))
3671+ error = vfs_tmpfile (mnt_userns , & path , file , op -> mode );
3672+ if (error )
36843673 goto out2 ;
3685- dput (path .dentry );
3686- path .dentry = child ;
3687- audit_inode (nd -> name , child , 0 );
3688- /* Don't check for other permissions, the inode was just created */
3689- error = may_open (mnt_userns , & path , 0 , op -> open_flag );
3690- if (!error )
3691- error = vfs_open (& path , file );
3674+ audit_inode (nd -> name , file -> f_path .dentry , 0 );
36923675out2 :
36933676 mnt_drop_write (path .mnt );
36943677out :
0 commit comments