From: Sakari Ailus <sakari.ailus@linux.intel.com>
To: linux-media@vger.kernel.org
Cc: hverkuil@xs4all.nl, acourbot@chromium.org
Subject: [RFC v2 01/10] media: Support variable size IOCTL arguments
Date: Fri, 23 Mar 2018 23:17:35 +0200 [thread overview]
Message-ID: <1521839864-10146-2-git-send-email-sakari.ailus@linux.intel.com> (raw)
In-Reply-To: <1521839864-10146-1-git-send-email-sakari.ailus@linux.intel.com>
Maintain a list of supported IOCTL argument sizes and allow only those in
the list.
As an additional bonus, IOCTL handlers will be able to check whether the
caller actually set (using the argument size) the field vs. assigning it
to zero. Separate macro can be provided for that.
This will be easier for applications as well since there is no longer the
problem of setting the reserved fields zero, or at least it is a lesser
problem.
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
---
drivers/media/media-device.c | 65 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 59 insertions(+), 6 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 35e81f7..da63da1 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -387,22 +387,36 @@ static long copy_arg_to_user(void __user *uarg, void *karg, unsigned int cmd)
/* Do acquire the graph mutex */
#define MEDIA_IOC_FL_GRAPH_MUTEX BIT(0)
-#define MEDIA_IOC_ARG(__cmd, func, fl, from_user, to_user) \
+#define MEDIA_IOC_SZ_ARG(__cmd, func, fl, alt_sz, from_user, to_user) \
[_IOC_NR(MEDIA_IOC_##__cmd)] = { \
.cmd = MEDIA_IOC_##__cmd, \
.fn = (long (*)(struct media_device *, void *))func, \
.flags = fl, \
+ .alt_arg_sizes = alt_sz, \
.arg_from_user = from_user, \
.arg_to_user = to_user, \
}
-#define MEDIA_IOC(__cmd, func, fl) \
- MEDIA_IOC_ARG(__cmd, func, fl, copy_arg_from_user, copy_arg_to_user)
+#define MEDIA_IOC_ARG(__cmd, func, fl, from_user, to_user) \
+ MEDIA_IOC_SZ_ARG(__cmd, func, fl, NULL, from_user, to_user)
+
+#define MEDIA_IOC_SZ(__cmd, func, fl, alt_sz) \
+ MEDIA_IOC_SZ_ARG(__cmd, func, fl, alt_sz, \
+ copy_arg_from_user, copy_arg_to_user)
+
+#define MEDIA_IOC(__cmd, func, fl) \
+ MEDIA_IOC_ARG(__cmd, func, fl, \
+ copy_arg_from_user, copy_arg_to_user)
/* the table is indexed by _IOC_NR(cmd) */
struct media_ioctl_info {
unsigned int cmd;
unsigned short flags;
+ /*
+ * Sizes of the alternative arguments. If there are none, this
+ * pointer is NULL.
+ */
+ const unsigned short *alt_arg_sizes;
long (*fn)(struct media_device *dev, void *arg);
long (*arg_from_user)(void *karg, void __user *uarg, unsigned int cmd);
long (*arg_to_user)(void __user *uarg, void *karg, unsigned int cmd);
@@ -416,6 +430,42 @@ static const struct media_ioctl_info ioctl_info[] = {
MEDIA_IOC(G_TOPOLOGY, media_device_get_topology, MEDIA_IOC_FL_GRAPH_MUTEX),
};
+#define MASK_IOC_SIZE(cmd) \
+ ((cmd) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
+
+static inline long is_valid_ioctl(unsigned int cmd)
+{
+ const struct media_ioctl_info *info = ioctl_info;
+ const unsigned short *alt_arg_sizes;
+
+ if (_IOC_NR(cmd) >= ARRAY_SIZE(ioctl_info))
+ return -ENOIOCTLCMD;
+
+ info += _IOC_NR(cmd);
+
+ if (info->cmd == cmd)
+ return 0;
+
+ /*
+ * Verify that the size-dependent patch of the IOCTL command
+ * matches and that the size does not exceed the principal
+ * argument size.
+ */
+ if (MASK_IOC_SIZE(info->cmd) != MASK_IOC_SIZE(cmd)
+ || _IOC_SIZE(info->cmd) < _IOC_SIZE(cmd))
+ return -ENOIOCTLCMD;
+
+ alt_arg_sizes = info->alt_arg_sizes;
+ if (!alt_arg_sizes)
+ return -ENOIOCTLCMD;
+
+ for (; *alt_arg_sizes; alt_arg_sizes++)
+ if (_IOC_SIZE(cmd) == *alt_arg_sizes)
+ return 0;
+
+ return -ENOIOCTLCMD;
+}
+
static long media_device_ioctl(struct file *filp, unsigned int cmd,
unsigned long __arg)
{
@@ -426,9 +476,9 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
char __karg[256], *karg = __karg;
long ret;
- if (_IOC_NR(cmd) >= ARRAY_SIZE(ioctl_info)
- || ioctl_info[_IOC_NR(cmd)].cmd != cmd)
- return -ENOIOCTLCMD;
+ ret = is_valid_ioctl(cmd);
+ if (ret)
+ return ret;
info = &ioctl_info[_IOC_NR(cmd)];
@@ -444,6 +494,9 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
goto out_free;
}
+ /* Set the rest of the argument struct to zero */
+ memset(karg + _IOC_SIZE(cmd), 0, _IOC_SIZE(info->cmd) - _IOC_SIZE(cmd));
+
if (info->flags & MEDIA_IOC_FL_GRAPH_MUTEX)
mutex_lock(&dev->graph_mutex);
--
2.7.4
next prev parent reply other threads:[~2018-03-23 21:18 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-23 21:17 [RFC v2 00/10] Preparing the request API Sakari Ailus
2018-03-23 21:17 ` Sakari Ailus [this message]
2018-03-26 10:47 ` [RFC v2 01/10] media: Support variable size IOCTL arguments Mauro Carvalho Chehab
2018-03-26 11:34 ` Sakari Ailus
2018-03-26 13:23 ` [RFC v2.1 1/1] " Sakari Ailus
2018-03-26 17:28 ` Mauro Carvalho Chehab
2018-03-26 20:00 ` Sakari Ailus
2018-03-26 20:37 ` Mauro Carvalho Chehab
2018-03-23 21:17 ` [RFC v2 02/10] media: Add request API Sakari Ailus
2018-03-23 21:17 ` [RFC v2 03/10] videodev2.h: Add request_fd field to v4l2_buffer Sakari Ailus
2018-03-23 21:17 ` [RFC v2 04/10] videodev2.h: add request_fd field to v4l2_ext_controls Sakari Ailus
2018-03-23 21:17 ` [RFC v2 05/10] staging: media: atomisp: Remove v4l2_buffer.reserved2 field hack Sakari Ailus
2018-03-23 21:17 ` [RFC v2 06/10] vb2: Add support for requests Sakari Ailus
2018-03-26 6:02 ` Tomasz Figa
2018-03-26 9:31 ` Sakari Ailus
2018-03-23 21:17 ` [RFC v2 07/10] v4l: m2m: Simplify exiting the function in v4l2_m2m_try_schedule Sakari Ailus
2018-03-23 21:17 ` [RFC v2 08/10] v4l: m2m: Support requests with video buffers Sakari Ailus
2018-03-23 21:17 ` [RFC v2 09/10] vim2m: Register V4L2 video device after V4L2 mem2mem init Sakari Ailus
2018-03-23 21:17 ` [RFC v2 10/10] vim2m: Request support Sakari Ailus
2018-03-25 15:12 ` [RFC v2 00/10] Preparing the request API Hans Verkuil
2018-03-25 16:17 ` Hans Verkuil
2018-03-26 7:58 ` Sakari Ailus
2018-03-26 8:31 ` Hans Verkuil
2018-03-26 9:17 ` Sakari Ailus
2018-03-26 15:35 ` Hans Verkuil
2018-03-27 15:00 ` Hans Verkuil
2018-03-26 3:30 ` Alexandre Courbot
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=1521839864-10146-2-git-send-email-sakari.ailus@linux.intel.com \
--to=sakari.ailus@linux.intel.com \
--cc=acourbot@chromium.org \
--cc=hverkuil@xs4all.nl \
--cc=linux-media@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox