@@ -2872,9 +2872,9 @@ static const struct v4l2_ioctl_info v4l2_ioctls[] = {
28722872 IOCTL_INFO (VIDIOC_S_PRIORITY , v4l_s_priority , v4l_print_u32 , INFO_FL_PRIO ),
28732873 IOCTL_INFO (VIDIOC_G_SLICED_VBI_CAP , v4l_g_sliced_vbi_cap , v4l_print_sliced_vbi_cap , INFO_FL_CLEAR (v4l2_sliced_vbi_cap , type )),
28742874 IOCTL_INFO (VIDIOC_LOG_STATUS , v4l_log_status , v4l_print_newline , 0 ),
2875- IOCTL_INFO (VIDIOC_G_EXT_CTRLS , v4l_g_ext_ctrls , v4l_print_ext_controls , INFO_FL_CTRL ),
2876- IOCTL_INFO (VIDIOC_S_EXT_CTRLS , v4l_s_ext_ctrls , v4l_print_ext_controls , INFO_FL_PRIO | INFO_FL_CTRL ),
2877- IOCTL_INFO (VIDIOC_TRY_EXT_CTRLS , v4l_try_ext_ctrls , v4l_print_ext_controls , INFO_FL_CTRL ),
2875+ IOCTL_INFO (VIDIOC_G_EXT_CTRLS , v4l_g_ext_ctrls , v4l_print_ext_controls , INFO_FL_CTRL | INFO_FL_ALWAYS_COPY ),
2876+ IOCTL_INFO (VIDIOC_S_EXT_CTRLS , v4l_s_ext_ctrls , v4l_print_ext_controls , INFO_FL_PRIO | INFO_FL_CTRL | INFO_FL_ALWAYS_COPY ),
2877+ IOCTL_INFO (VIDIOC_TRY_EXT_CTRLS , v4l_try_ext_ctrls , v4l_print_ext_controls , INFO_FL_CTRL | INFO_FL_ALWAYS_COPY ),
28782878 IOCTL_INFO (VIDIOC_ENUM_FRAMESIZES , v4l_stub_enum_framesizes , v4l_print_frmsizeenum , INFO_FL_CLEAR (v4l2_frmsizeenum , pixel_format )),
28792879 IOCTL_INFO (VIDIOC_ENUM_FRAMEINTERVALS , v4l_stub_enum_frameintervals , v4l_print_frmivalenum , INFO_FL_CLEAR (v4l2_frmivalenum , height )),
28802880 IOCTL_INFO (VIDIOC_G_ENC_INDEX , v4l_stub_g_enc_index , v4l_print_enc_idx , 0 ),
@@ -3367,8 +3367,7 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
33673367 array_buf = kvmalloc (array_size , GFP_KERNEL );
33683368 err = - ENOMEM ;
33693369 if (array_buf == NULL )
3370- goto out_array_args ;
3371- err = - EFAULT ;
3370+ goto out ;
33723371 if (in_compat_syscall ())
33733372 err = v4l2_compat_get_array_args (file , array_buf ,
33743373 user_ptr , array_size ,
@@ -3377,7 +3376,7 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
33773376 err = copy_from_user (array_buf , user_ptr , array_size ) ?
33783377 - EFAULT : 0 ;
33793378 if (err )
3380- goto out_array_args ;
3379+ goto out ;
33813380 * kernel_ptr = array_buf ;
33823381 }
33833382
@@ -3395,6 +3394,13 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
33953394 trace_v4l2_qbuf (video_devdata (file )-> minor , parg );
33963395 }
33973396
3397+ /*
3398+ * Some ioctls can return an error, but still have valid
3399+ * results that must be returned.
3400+ */
3401+ if (err < 0 && !always_copy )
3402+ goto out ;
3403+
33983404 if (has_array_args ) {
33993405 * kernel_ptr = (void __force * )user_ptr ;
34003406 if (in_compat_syscall ()) {
@@ -3409,16 +3415,8 @@ video_usercopy(struct file *file, unsigned int orig_cmd, unsigned long arg,
34093415 } else if (copy_to_user (user_ptr , array_buf , array_size )) {
34103416 err = - EFAULT ;
34113417 }
3412- goto out_array_args ;
34133418 }
3414- /*
3415- * Some ioctls can return an error, but still have valid
3416- * results that must be returned.
3417- */
3418- if (err < 0 && !always_copy )
3419- goto out ;
34203419
3421- out_array_args :
34223420 if (video_put_user ((void __user * )arg , parg , cmd , orig_cmd ))
34233421 err = - EFAULT ;
34243422out :
0 commit comments