diff options
| -rw-r--r-- | drivers/media/video/v4l2-compat-ioctl32.c | 32 | ||||
| -rw-r--r-- | net/rds/page.c | 27 |
2 files changed, 28 insertions, 31 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: |
diff --git a/net/rds/page.c b/net/rds/page.c index 595a952d4b17..1dfbfea12e9b 100644 --- a/net/rds/page.c +++ b/net/rds/page.c | |||
| @@ -57,30 +57,17 @@ int rds_page_copy_user(struct page *page, unsigned long offset, | |||
| 57 | unsigned long ret; | 57 | unsigned long ret; |
| 58 | void *addr; | 58 | void *addr; |
| 59 | 59 | ||
| 60 | if (to_user) | 60 | addr = kmap(page); |
| 61 | if (to_user) { | ||
| 61 | rds_stats_add(s_copy_to_user, bytes); | 62 | rds_stats_add(s_copy_to_user, bytes); |
| 62 | else | 63 | ret = copy_to_user(ptr, addr + offset, bytes); |
| 64 | } else { | ||
| 63 | rds_stats_add(s_copy_from_user, bytes); | 65 | rds_stats_add(s_copy_from_user, bytes); |
| 64 | 66 | ret = copy_from_user(addr + offset, ptr, bytes); | |
| 65 | addr = kmap_atomic(page, KM_USER0); | ||
| 66 | if (to_user) | ||
| 67 | ret = __copy_to_user_inatomic(ptr, addr + offset, bytes); | ||
| 68 | else | ||
| 69 | ret = __copy_from_user_inatomic(addr + offset, ptr, bytes); | ||
| 70 | kunmap_atomic(addr, KM_USER0); | ||
| 71 | |||
| 72 | if (ret) { | ||
| 73 | addr = kmap(page); | ||
| 74 | if (to_user) | ||
| 75 | ret = copy_to_user(ptr, addr + offset, bytes); | ||
| 76 | else | ||
| 77 | ret = copy_from_user(addr + offset, ptr, bytes); | ||
| 78 | kunmap(page); | ||
| 79 | if (ret) | ||
| 80 | return -EFAULT; | ||
| 81 | } | 67 | } |
| 68 | kunmap(page); | ||
| 82 | 69 | ||
| 83 | return 0; | 70 | return ret ? -EFAULT : 0; |
| 84 | } | 71 | } |
| 85 | EXPORT_SYMBOL_GPL(rds_page_copy_user); | 72 | EXPORT_SYMBOL_GPL(rds_page_copy_user); |
| 86 | 73 | ||
