diff options
| -rw-r--r-- | drivers/media/video/v4l2-compat-ioctl32.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c index 073f01390cdd..86294ed35c9b 100644 --- a/drivers/media/video/v4l2-compat-ioctl32.c +++ b/drivers/media/video/v4l2-compat-ioctl32.c | |||
| @@ -193,17 +193,24 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u | |||
| 193 | struct video_code32 { | 193 | struct video_code32 { |
| 194 | char loadwhat[16]; /* name or tag of file being passed */ | 194 | char loadwhat[16]; /* name or tag of file being passed */ |
| 195 | compat_int_t datasize; | 195 | compat_int_t datasize; |
| 196 | unsigned char *data; | 196 | compat_uptr_t data; |
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| 199 | static int get_microcode32(struct video_code *kp, struct video_code32 __user *up) | 199 | static struct video_code __user *get_microcode32(struct video_code32 *kp) |
| 200 | { | 200 | { |
| 201 | if (!access_ok(VERIFY_READ, up, sizeof(struct video_code32)) || | 201 | struct video_code __user *up; |
| 202 | copy_from_user(kp->loadwhat, up->loadwhat, sizeof(up->loadwhat)) || | 202 | |
| 203 | get_user(kp->datasize, &up->datasize) || | 203 | up = compat_alloc_user_space(sizeof(*up)); |
| 204 | copy_from_user(kp->data, up->data, up->datasize)) | 204 | |
| 205 | return -EFAULT; | 205 | /* |
| 206 | return 0; | 206 | * NOTE! We don't actually care if these fail. If the |
| 207 | * user address is invalid, the native ioctl will do | ||
| 208 | * the error handling for us | ||
| 209 | */ | ||
| 210 | (void) copy_to_user(up->loadwhat, kp->loadwhat, sizeof(up->loadwhat)); | ||
| 211 | (void) put_user(kp->datasize, &up->datasize); | ||
| 212 | (void) put_user(compat_ptr(kp->data), &up->data); | ||
| 213 | return up; | ||
| 207 | } | 214 | } |
| 208 | 215 | ||
| 209 | #define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32) | 216 | #define VIDIOCGTUNER32 _IOWR('v', 4, struct video_tuner32) |
| @@ -739,7 +746,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar | |||
| 739 | struct video_tuner vt; | 746 | struct video_tuner vt; |
| 740 | struct video_buffer vb; | 747 | struct video_buffer vb; |
| 741 | struct video_window vw; | 748 | struct video_window vw; |
| 742 | struct video_code vc; | 749 | struct video_code32 vc; |
| 743 | struct video_audio va; | 750 | struct video_audio va; |
| 744 | #endif | 751 | #endif |
| 745 | struct v4l2_format v2f; | 752 | struct v4l2_format v2f; |
| @@ -818,8 +825,11 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar | |||
| 818 | break; | 825 | break; |
| 819 | 826 | ||
| 820 | case VIDIOCSMICROCODE: | 827 | case VIDIOCSMICROCODE: |
| 821 | err = get_microcode32(&karg.vc, up); | 828 | /* Copy the 32-bit "video_code32" to kernel space */ |
| 822 | compatible_arg = 0; | 829 | if (copy_from_user(&karg.vc, up, sizeof(karg.vc))) |
| 830 | return -EFAULT; | ||
| 831 | /* Convert the 32-bit version to a 64-bit version in user space */ | ||
| 832 | up = get_microcode32(&karg.vc); | ||
| 823 | break; | 833 | break; |
| 824 | 834 | ||
| 825 | case VIDIOCSFREQ: | 835 | case VIDIOCSFREQ: |
