From: Stephen Kitt <steve@sk2.org>
To: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: linux-input@vger.kernel.org
Subject: Re: Restoring joydev BTNMAP ioctl compatibility
Date: Mon, 17 Aug 2009 21:24:16 +0200 [thread overview]
Message-ID: <20090817212416.5c5b0a8b@sk2.org> (raw)
In-Reply-To: <20090811075734.A12DE526EC9@mailhub.coreip.homeip.net>
Hi Dmitry,
On Tue, 11 Aug 2009 00:26:53 -0700, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> Yep, exactly, except that don't bother with vmalloc, kmalloc will do
> nicely since the amout of memory needed is relatively small.
Did you have a chance to look at the previous patch I sent? In case it's
easier to review in one go, here's a single patch grouping the changes to the
ioctls themselves as well as the map validation code!
Regards,
Stephen
Input: handle map ioctls regardless of declared length, and validate maps
The KEY_MAX change in 2.6.28 changed the values of the JSIOCSBTNMAP and
JSIOCGBTNMAP constants; software compiled with the old values no longer
works with kernels following 2.6.28, because the ioctl switch statement
no longer matches the values given by the software. This patch handles
these ioctls independently of the length of data specified, and applies the
same treatment to JSIOCSAXMAP and JSIOCGAXMAP which currently depend on
ABS_MAX.
Furthermore the user-supplied maps are validated before being copied over
the driver's stored values; previously an invalid map could result in the
driver's copy being partially updated.
Signed-off-by: Stephen Kitt <steve@sk2.org>
---
drivers/input/joydev.c | 100 +++++++++++++++++++++++++++++++++---------------
1 files changed, 69 insertions(+), 31 deletions(-)
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 4cfd084..ceaeb7b 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -456,8 +456,13 @@ static int joydev_ioctl_common(struct joydev *joydev,
unsigned int cmd, void __user *argp)
{
struct input_dev *dev = joydev->handle.dev;
+ size_t len;
int i, j;
+ const char *name;
+ __u8 *tmpabspam;
+ __u16 *tmpkeypam;
+ /* Process fixed-sized commands. */
switch (cmd) {
case JS_SET_CAL:
@@ -499,55 +504,88 @@ static int joydev_ioctl_common(struct joydev *joydev,
return copy_to_user(argp, joydev->corr,
sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
- case JSIOCSAXMAP:
- if (copy_from_user(joydev->abspam, argp,
- sizeof(__u8) * (ABS_MAX + 1)))
- return -EFAULT;
+ }
+
+ /* Process variable-sized commands (the axis and button map commands
+ are considered variable-sized to decouple them from the values of
+ ABS_MAX and KEY_MAX). */
+ switch (cmd & ~IOCSIZE_MASK) {
+ case (JSIOCSAXMAP & ~IOCSIZE_MASK):
+ len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
+
+ /* Validate the map. */
+ tmpabspam = kmalloc(len, GFP_KERNEL);
+ if (!tmpabspam)
+ return -ENOMEM;
+ if (copy_from_user(tmpabspam, argp, len)) {
+ kfree(tmpabspam);
+ return -EFAULT;
+ }
for (i = 0; i < joydev->nabs; i++) {
- if (joydev->abspam[i] > ABS_MAX)
+ if (tmpabspam[i] > ABS_MAX) {
+ kfree(tmpabspam);
return -EINVAL;
+ }
+ }
+
+ memcpy(joydev->abspam, tmpabspam, len);
+ kfree(tmpabspam);
+
+ for (i = 0; i < joydev->nabs; i++) {
joydev->absmap[joydev->abspam[i]] = i;
}
return 0;
- case JSIOCGAXMAP:
- return copy_to_user(argp, joydev->abspam,
- sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0;
+ case (JSIOCGAXMAP & ~IOCSIZE_MASK):
+ len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
+ return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : len;
- case JSIOCSBTNMAP:
- if (copy_from_user(joydev->keypam, argp,
- sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)))
- return -EFAULT;
+ case (JSIOCSBTNMAP & ~IOCSIZE_MASK):
+ len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
+ /* Validate the map. */
+ tmpkeypam = kmalloc(len, GFP_KERNEL);
+ if (!tmpkeypam)
+ return -ENOMEM;
+ if (copy_from_user(tmpkeypam, argp, len)) {
+ kfree(tmpkeypam);
+ return -EFAULT;
+ }
for (i = 0; i < joydev->nkey; i++) {
- if (joydev->keypam[i] > KEY_MAX ||
- joydev->keypam[i] < BTN_MISC)
+ if (tmpkeypam[i] > KEY_MAX ||
+ tmpkeypam[i] < BTN_MISC) {
+ kfree(tmpkeypam);
return -EINVAL;
+ }
+ }
+
+ memcpy(joydev->keypam, tmpkeypam, len);
+ kfree(tmpkeypam);
+
+ for (i = 0; i < joydev->nkey; i++) {
joydev->keymap[joydev->keypam[i] - BTN_MISC] = i;
}
return 0;
- case JSIOCGBTNMAP:
- return copy_to_user(argp, joydev->keypam,
- sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0;
+ case (JSIOCGBTNMAP & ~IOCSIZE_MASK):
+ len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
+ return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : len;
- default:
- if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) {
- int len;
- const char *name = dev->name;
-
- if (!name)
- return 0;
- len = strlen(name) + 1;
- if (len > _IOC_SIZE(cmd))
- len = _IOC_SIZE(cmd);
- if (copy_to_user(argp, name, len))
- return -EFAULT;
- return len;
- }
+ case JSIOCGNAME(0):
+ name = dev->name;
+
+ if (!name)
+ return 0;
+ len = strlen(name) + 1;
+ if (len > _IOC_SIZE(cmd))
+ len = _IOC_SIZE(cmd);
+ if (copy_to_user(argp, name, len))
+ return -EFAULT;
+ return len;
}
+
return -EINVAL;
}
next prev parent reply other threads:[~2009-08-17 19:24 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-10 6:52 Restoring joydev BTNMAP ioctl compatibility Stephen Kitt
2009-08-10 8:14 ` Dmitry Torokhov
2009-08-10 11:29 ` Stephen Kitt
2009-08-10 19:12 ` Stephen Kitt
2009-08-10 20:27 ` Dmitry Torokhov
2009-08-11 6:20 ` Stephen Kitt
2009-08-11 7:26 ` Dmitry Torokhov
2009-08-11 22:00 ` Stephen Kitt
2009-08-17 19:24 ` Stephen Kitt [this message]
2009-08-18 5:25 ` Dmitry Torokhov
2009-08-19 6:24 ` Stephen Kitt
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=20090817212416.5c5b0a8b@sk2.org \
--to=steve@sk2.org \
--cc=dmitry.torokhov@gmail.com \
--cc=linux-input@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 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.