All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Mickaël Salaün" <mic@digikod.net>
To: "Arnd Bergmann" <arnd@arndb.de>,
	"Christian Brauner" <brauner@kernel.org>,
	"Günther Noack" <gnoack@google.com>
Cc: Allen Webb <allenwebb@google.com>,
	Dmitry Torokhov <dtor@google.com>,  Jeff Xu <jeffxu@google.com>,
	Jorge Lucangeli Obes <jorgelo@chromium.org>,
	 Konstantin Meskhidze <konstantin.meskhidze@huawei.com>,
	Matt Bobrowski <repnop@google.com>,
	 Paul Moore <paul@paul-moore.com>,
	linux-fsdevel@vger.kernel.org,
	 linux-security-module@vger.kernel.org
Subject: Re: [RFC PATCH] fs: Add vfs_masks_device_ioctl*() helpers
Date: Fri, 1 Mar 2024 14:42:00 +0100	[thread overview]
Message-ID: <20240301.deax4thooPhu@digikod.net> (raw)
In-Reply-To: <20240219183539.2926165-1-mic@digikod.net>

Arnd, Christian, are you OK with this approach to identify VFS IOCTLs?

If yes, Günther should include it in his next patch series.

On Mon, Feb 19, 2024 at 07:35:39PM +0100, Mickaël Salaün wrote:
> vfs_masks_device_ioctl() and vfs_masks_device_ioctl_compat() are useful
> to differenciate between device driver IOCTL implementations and
> filesystem ones.  The goal is to be able to filter well-defined IOCTLs
> from per-device (i.e. namespaced) IOCTLs and control such access.
> 
> Add a new ioctl_compat() helper, similar to vfs_ioctl(), to wrap
> compat_ioctl() calls and handle error conversions.
> 
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Günther Noack <gnoack@google.com>
> ---
>  fs/ioctl.c         | 101 +++++++++++++++++++++++++++++++++++++++++----
>  include/linux/fs.h |  12 ++++++
>  2 files changed, 105 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/ioctl.c b/fs/ioctl.c
> index 76cf22ac97d7..f72c8da47d21 100644
> --- a/fs/ioctl.c
> +++ b/fs/ioctl.c
> @@ -763,6 +763,38 @@ static int ioctl_fssetxattr(struct file *file, void __user *argp)
>  	return err;
>  }
>  
> +/*
> + * Safeguard to maintain a list of valid IOCTLs handled by do_vfs_ioctl()
> + * instead of def_blk_fops or def_chr_fops (see init_special_inode).
> + */
> +__attribute_const__ bool vfs_masked_device_ioctl(const unsigned int cmd)
> +{
> +	switch (cmd) {
> +	case FIOCLEX:
> +	case FIONCLEX:
> +	case FIONBIO:
> +	case FIOASYNC:
> +	case FIOQSIZE:
> +	case FIFREEZE:
> +	case FITHAW:
> +	case FS_IOC_FIEMAP:
> +	case FIGETBSZ:
> +	case FICLONE:
> +	case FICLONERANGE:
> +	case FIDEDUPERANGE:
> +	/* FIONREAD is forwarded to device implementations. */
> +	case FS_IOC_GETFLAGS:
> +	case FS_IOC_SETFLAGS:
> +	case FS_IOC_FSGETXATTR:
> +	case FS_IOC_FSSETXATTR:
> +	/* file_ioctl()'s IOCTLs are forwarded to device implementations. */
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +EXPORT_SYMBOL(vfs_masked_device_ioctl);
> +
>  /*
>   * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d.
>   * It's just a simple helper for sys_ioctl and compat_sys_ioctl.
> @@ -858,6 +890,8 @@ SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
>  {
>  	struct fd f = fdget(fd);
>  	int error;
> +	const struct inode *inode;
> +	bool is_device;
>  
>  	if (!f.file)
>  		return -EBADF;
> @@ -866,9 +900,18 @@ SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
>  	if (error)
>  		goto out;
>  
> +	inode = file_inode(f.file);
> +	is_device = S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode);
> +	if (is_device && !vfs_masked_device_ioctl(cmd)) {
> +		error = vfs_ioctl(f.file, cmd, arg);
> +		goto out;
> +	}
> +
>  	error = do_vfs_ioctl(f.file, fd, cmd, arg);
> -	if (error == -ENOIOCTLCMD)
> +	if (error == -ENOIOCTLCMD) {
> +		WARN_ON_ONCE(is_device);
>  		error = vfs_ioctl(f.file, cmd, arg);
> +	}
>  
>  out:
>  	fdput(f);
> @@ -911,11 +954,49 @@ long compat_ptr_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>  }
>  EXPORT_SYMBOL(compat_ptr_ioctl);
>  
> +static long ioctl_compat(struct file *filp, unsigned int cmd,
> +			 compat_ulong_t arg)
> +{
> +	int error = -ENOTTY;
> +
> +	if (!filp->f_op->compat_ioctl)
> +		goto out;
> +
> +	error = filp->f_op->compat_ioctl(filp, cmd, arg);
> +	if (error == -ENOIOCTLCMD)
> +		error = -ENOTTY;
> +
> +out:
> +	return error;
> +}
> +
> +__attribute_const__ bool vfs_masked_device_ioctl_compat(const unsigned int cmd)
> +{
> +	switch (cmd) {
> +	case FICLONE:
> +#if defined(CONFIG_X86_64)
> +	case FS_IOC_RESVSP_32:
> +	case FS_IOC_RESVSP64_32:
> +	case FS_IOC_UNRESVSP_32:
> +	case FS_IOC_UNRESVSP64_32:
> +	case FS_IOC_ZERO_RANGE_32:
> +#endif
> +	case FS_IOC32_GETFLAGS:
> +	case FS_IOC32_SETFLAGS:
> +		return true;
> +	default:
> +		return vfs_masked_device_ioctl(cmd);
> +	}
> +}
> +EXPORT_SYMBOL(vfs_masked_device_ioctl_compat);
> +
>  COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
>  		       compat_ulong_t, arg)
>  {
>  	struct fd f = fdget(fd);
>  	int error;
> +	const struct inode *inode;
> +	bool is_device;
>  
>  	if (!f.file)
>  		return -EBADF;
> @@ -924,6 +1005,13 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
>  	if (error)
>  		goto out;
>  
> +	inode = file_inode(f.file);
> +	is_device = S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode);
> +	if (is_device && !vfs_masked_device_ioctl_compat(cmd)) {
> +		error = ioctl_compat(f.file, cmd, arg);
> +		goto out;
> +	}
> +
>  	switch (cmd) {
>  	/* FICLONE takes an int argument, so don't use compat_ptr() */
>  	case FICLONE:
> @@ -964,13 +1052,10 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
>  	default:
>  		error = do_vfs_ioctl(f.file, fd, cmd,
>  				     (unsigned long)compat_ptr(arg));
> -		if (error != -ENOIOCTLCMD)
> -			break;
> -
> -		if (f.file->f_op->compat_ioctl)
> -			error = f.file->f_op->compat_ioctl(f.file, cmd, arg);
> -		if (error == -ENOIOCTLCMD)
> -			error = -ENOTTY;
> +		if (error == -ENOIOCTLCMD) {
> +			WARN_ON_ONCE(is_device);
> +			error = ioctl_compat(f.file, cmd, arg);
> +		}
>  		break;
>  	}
>  
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index ed5966a70495..b620d0c00e16 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1902,6 +1902,18 @@ extern long compat_ptr_ioctl(struct file *file, unsigned int cmd,
>  #define compat_ptr_ioctl NULL
>  #endif
>  
> +extern __attribute_const__ bool vfs_masked_device_ioctl(const unsigned int cmd);
> +#ifdef CONFIG_COMPAT
> +extern __attribute_const__ bool
> +vfs_masked_device_ioctl_compat(const unsigned int cmd);
> +#else /* CONFIG_COMPAT */
> +static inline __attribute_const__ bool
> +vfs_masked_device_ioctl_compat(const unsigned int cmd)
> +{
> +	return vfs_masked_device_ioctl(cmd);
> +}
> +#endif /* CONFIG_COMPAT */
> +
>  /*
>   * VFS file helper functions.
>   */
> -- 
> 2.43.0
> 
> 

  reply	other threads:[~2024-03-01 13:42 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-09 17:06 [PATCH v9 0/8] Landlock: IOCTL support Günther Noack
2024-02-09 17:06 ` [PATCH v9 1/8] landlock: Add IOCTL access right Günther Noack
2024-02-10 11:06   ` Günther Noack
2024-02-10 11:49     ` Arnd Bergmann
2024-02-12 11:09       ` Christian Brauner
2024-02-12 22:10         ` Günther Noack
2024-02-10 11:18   ` Günther Noack
2024-02-16 14:11     ` Mickaël Salaün
2024-02-16 15:51       ` Mickaël Salaün
2024-02-18  8:34         ` Günther Noack
2024-02-19 21:44           ` Günther Noack
2024-02-16 17:19   ` Mickaël Salaün
2024-02-19 18:34   ` Mickaël Salaün
2024-02-19 18:35     ` [RFC PATCH] fs: Add vfs_masks_device_ioctl*() helpers Mickaël Salaün
2024-03-01 13:42       ` Mickaël Salaün [this message]
2024-03-01 16:24       ` Arnd Bergmann
2024-03-01 18:35         ` Mickaël Salaün
2024-03-05 18:13       ` Günther Noack
2024-03-06 13:47         ` Mickaël Salaün
2024-03-06 15:18           ` Arnd Bergmann
2024-03-07 12:15             ` Christian Brauner
2024-03-07 12:21               ` Arnd Bergmann
2024-03-07 12:57                 ` Günther Noack
2024-03-07 20:40                   ` Paul Moore
2024-03-07 23:09                     ` Dave Chinner
2024-03-07 23:35                       ` Paul Moore
2024-03-08  7:02                       ` Arnd Bergmann
2024-03-08  9:29                         ` Mickaël Salaün
2024-03-08 19:22                           ` Paul Moore
2024-03-08 20:12                             ` Mickaël Salaün
2024-03-08 22:04                               ` Casey Schaufler
2024-03-08 22:25                               ` Paul Moore
2024-03-09  8:14                                 ` Günther Noack
2024-03-09 17:41                                   ` Casey Schaufler
2024-03-11 19:04                                   ` Paul Moore
2024-03-08 11:03                         ` Günther Noack
2024-03-11  1:03                           ` Dave Chinner
2024-03-11  9:01                             ` Günther Noack
2024-03-11 22:12                               ` Dave Chinner
2024-03-12 10:58                                 ` Mickaël Salaün
2024-02-28 12:57     ` [PATCH v9 1/8] landlock: Add IOCTL access right Günther Noack
2024-03-01 12:59       ` Mickaël Salaün
2024-03-01 13:38         ` Mickaël Salaün
2024-02-09 17:06 ` [PATCH v9 2/8] selftests/landlock: Test IOCTL support Günther Noack
2024-02-09 17:06 ` [PATCH v9 3/8] selftests/landlock: Test IOCTL with memfds Günther Noack
2024-02-09 17:06 ` [PATCH v9 4/8] selftests/landlock: Test ioctl(2) and ftruncate(2) with open(O_PATH) Günther Noack
2024-02-09 17:06 ` [PATCH v9 5/8] selftests/landlock: Test IOCTLs on named pipes Günther Noack
2024-02-09 17:06 ` [PATCH v9 6/8] selftests/landlock: Check IOCTL restrictions for named UNIX domain sockets Günther Noack
2024-02-09 17:06 ` [PATCH v9 7/8] samples/landlock: Add support for LANDLOCK_ACCESS_FS_IOCTL Günther Noack
2024-02-09 17:06 ` [PATCH v9 8/8] landlock: Document IOCTL support Günther Noack

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240301.deax4thooPhu@digikod.net \
    --to=mic@digikod.net \
    --cc=allenwebb@google.com \
    --cc=arnd@arndb.de \
    --cc=brauner@kernel.org \
    --cc=dtor@google.com \
    --cc=gnoack@google.com \
    --cc=jeffxu@google.com \
    --cc=jorgelo@chromium.org \
    --cc=konstantin.meskhidze@huawei.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=paul@paul-moore.com \
    --cc=repnop@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.