V4L/DVB (10920): v4l2-ioctl: fix partial-copy code.
authorHans Verkuil <hverkuil@xs4all.nl>
Sun, 8 Mar 2009 13:35:23 +0000 (10:35 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 30 Mar 2009 15:43:16 +0000 (12:43 -0300)
The code to optimize the usercopy only checked the ioctl NR field. However,
this code is also called for non-V4L2 ioctls (either private or ioctls from
linux/dvb/audio.h and linux/dvb/video.h for decoder drivers like ivtv).

If such an ioctl has the same NR as a V4L2 ioctl, then disaster strikes.

Modified the code to check on the full command ID.

Thanks to Martin Dauskardt for tracing the ivtv breakage to this particular
change.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/v4l2-ioctl.c

index df8d1ff..54ba6b0 100644 (file)
@@ -1796,11 +1796,12 @@ static long __video_do_ioctl(struct file *file,
 static unsigned long cmd_input_size(unsigned int cmd)
 {
        /* Size of structure up to and including 'field' */
-#define CMDINSIZE(cmd, type, field) case _IOC_NR(VIDIOC_##cmd): return \
-               offsetof(struct v4l2_##type, field) + \
-               sizeof(((struct v4l2_##type *)0)->field);
+#define CMDINSIZE(cmd, type, field)                            \
+       case VIDIOC_##cmd:                                      \
+               return offsetof(struct v4l2_##type, field) +    \
+                       sizeof(((struct v4l2_##type *)0)->field);
 
-       switch (_IOC_NR(cmd)) {
+       switch (cmd) {
                CMDINSIZE(ENUM_FMT,             fmtdesc,        type);
                CMDINSIZE(G_FMT,                format,         type);
                CMDINSIZE(QUERYBUF,             buffer,         type);