@@ -193,17 +193,24 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u
193193struct video_code32 {
194194 char loadwhat [16 ]; /* name or tag of file being passed */
195195 compat_int_t datasize ;
196- unsigned char * data ;
196+ compat_uptr_t data ;
197197};
198198
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 )
200200{
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 ;
207214}
208215
209216#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
739746 struct video_tuner vt ;
740747 struct video_buffer vb ;
741748 struct video_window vw ;
742- struct video_code vc ;
749+ struct video_code32 vc ;
743750 struct video_audio va ;
744751#endif
745752 struct v4l2_format v2f ;
@@ -818,8 +825,11 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
818825 break ;
819826
820827 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 );
823833 break ;
824834
825835 case VIDIOCSFREQ :
0 commit comments