Re: [PATCH v3 3/9] vfs: add tmpfile_open() helper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Sep 20, 2022 at 09:36:26PM +0200, Miklos Szeredi wrote:
> This helper unifies tmpfile creation with opening.
> 
> Existing vfs_tmpfile() callers outside of fs/namei.c will be converted to
> using this helper.  There are two such callers: cachefile and overlayfs.
> 
> The cachefiles code currently uses the open_with_fake_path() helper to open
> the tmpfile, presumably to disable accounting of the open file.  Overlayfs
> uses tmpfile for copy_up, which means these struct file instances will be
> short lived, hence it doesn't really matter if they are accounted or not.
> Disable accounting in this helper to, which should be okay for both caller.
> 
> Add MAY_OPEN permission checking for consistency.  Like for create(2)
> read/write permissions are not checked.
> 
> Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxxxxx>
> ---
>  fs/namei.c         | 41 +++++++++++++++++++++++++++++++++++++++++
>  include/linux/fs.h |  4 ++++
>  2 files changed, 45 insertions(+)
> 
> diff --git a/fs/namei.c b/fs/namei.c
> index 53b4bc094db2..5e4a0c59eef6 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -3624,6 +3624,47 @@ struct dentry *vfs_tmpfile(struct user_namespace *mnt_userns,
>  }
>  EXPORT_SYMBOL(vfs_tmpfile);
>  
> +/**
> + * tmpfile_open - open a tmpfile for kernel internal use
> + * @mnt_userns:	user namespace of the mount the inode was found from
> + * @parentpath:	path of the base directory
> + * @mode:	mode of the new tmpfile
> + * @open_flag:	flags
> + * @cred:	credentials for open
> + *
> + * Create and open a temporary file.  The file is not accounted in nr_files,
> + * hence this is only for kernel internal use, and must not be installed into
> + * file tables or such.
> + */
> +struct file *tmpfile_open(struct user_namespace *mnt_userns,
> +			  const struct path *parentpath,
> +			  umode_t mode, int open_flag, const struct cred *cred)
> +{
> +	struct file *file;
> +	int error;
> +	struct path path = { .mnt = parentpath->mnt };
> +
> +	path.dentry = vfs_tmpfile(mnt_userns, parentpath->dentry, mode, open_flag);
> +	if (IS_ERR(path.dentry))
> +		return ERR_CAST(path.dentry);
> +
> +	error = may_open(mnt_userns, &path, 0, open_flag);
> +	file = ERR_PTR(error);
> +	if (error)
> +		goto out_dput;
> +
> +	/*
> +	 * This relies on the "noaccount" property of fake open, otherwise
> +	 * equivalent to dentry_open().
> +	 */
> +	file = open_with_fake_path(&path, open_flag, d_inode(path.dentry), cred);
> +out_dput:
> +	dput(path.dentry);
> +
> +	return file;
> +}
> +EXPORT_SYMBOL(tmpfile_open);

Feels like this could be simplified while being equally legible to
something like:

/**
 * tmpfile_open - open a tmpfile for kernel internal use
 * @mnt_userns:	user namespace of the mount the inode was found from
 * @parentpath:	path of the base directory
 * @mode:	mode of the new tmpfile
 * @open_flag:	flags
 * @cred:	credentials for open
 *
 * Create and open a temporary file.  The file is not accounted in nr_files,
 * hence this is only for kernel internal use, and must not be installed into
 * file tables or such.
 *
 * The helper relies on the "noaccount" property of open_with_fake_path().
 * Otherwise it is equivalent to dentry_open().
 *
 * Return: Opened tmpfile on success, error pointer on failure.
 */
struct file *tmpfile_open(struct user_namespace *mnt_userns,
			  const struct path *parentpath,
			  umode_t mode, int open_flag, const struct cred *cred)
{
	struct file *file;
	int error;
	struct path path = { .mnt = parentpath->mnt };

	path.dentry = vfs_tmpfile(mnt_userns, parentpath->dentry, mode, open_flag);
	if (IS_ERR(path.dentry))
		return ERR_CAST(path.dentry);

	error = may_open(mnt_userns, &path, 0, open_flag);
	if (!error)
		file = open_with_fake_path(&path, open_flag, d_inode(path.dentry), cred);
	else
		file = ERR_PTR(error);
	dput(path.dentry);
	return file;
}
EXPORT_SYMBOL(tmpfile_open);



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux