@@ -193,17 +193,24 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u
193
193
struct video_code32 {
194
194
char loadwhat [16 ]; /* name or tag of file being passed */
195
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 )) ||
202
- copy_from_user (kp -> loadwhat , up -> loadwhat , sizeof (up -> loadwhat )) ||
203
- get_user (kp -> datasize , & up -> datasize ) ||
204
- copy_from_user (kp -> data , up -> data , up -> datasize ))
205
- return - EFAULT ;
206
- return 0 ;
201
+ struct video_code __user * up ;
202
+
203
+ up = compat_alloc_user_space (sizeof (* up ));
204
+
205
+ /*
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
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
746
struct video_tuner vt ;
740
747
struct video_buffer vb ;
741
748
struct video_window vw ;
742
- struct video_code vc ;
749
+ struct video_code32 vc ;
743
750
struct video_audio va ;
744
751
#endif
745
752
struct v4l2_format v2f ;
@@ -818,8 +825,11 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
818
825
break ;
819
826
820
827
case VIDIOCSMICROCODE :
821
- err = get_microcode32 (& karg .vc , up );
822
- compatible_arg = 0 ;
828
+ /* Copy the 32-bit "video_code32" to kernel space */
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
833
break ;
824
834
825
835
case VIDIOCSFREQ :
0 commit comments