]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
media: v4l2-ctrls: validate HEVC active reference counts
authorPengpeng Hou <pengpeng@iscas.ac.cn>
Tue, 24 Mar 2026 03:13:26 +0000 (11:13 +0800)
committerHans Verkuil <hverkuil+cisco@kernel.org>
Mon, 4 May 2026 06:35:14 +0000 (08:35 +0200)
HEVC slice parameters are shared stateless V4L2 controls, but the common
validation path does not verify the active L0/L1 reference counts before
driver-specific code consumes them.

The original report came from Cedrus, but the active count bounds are
not Cedrus-specific. Validate them in the common HEVC slice control path
so stateless HEVC drivers get the same basic guarantees as soon as the
control is queued.

Do not reject ref_idx_l0/ref_idx_l1 entries here. Existing userspace may
use out-of-range sentinel values such as 0xff for missing references, and
some hardware can use that information for concealment. Keep this common
check limited to the active reference counts.

Fixes: d395a78db9eab ("media: hevc: Add decode params control")
Cc: stable@vger.kernel.org
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
drivers/media/v4l2-core/v4l2-ctrls-core.c

index 6b375720e395c4794591f1454dedc13c8899b587..ba047d7d86010bf0cf8f8fbf2dc343883d6bdae0 100644 (file)
@@ -971,6 +971,7 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
        struct v4l2_ctrl_hevc_ext_sps_st_rps *p_hevc_st_rps;
        struct v4l2_ctrl_hevc_sps *p_hevc_sps;
        struct v4l2_ctrl_hevc_pps *p_hevc_pps;
+       struct v4l2_ctrl_hevc_slice_params *p_hevc_slice_params;
        struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering;
        struct v4l2_ctrl_hevc_decode_params *p_hevc_decode_params;
        struct v4l2_area *area;
@@ -1260,6 +1261,18 @@ static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
                break;
 
        case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
+               p_hevc_slice_params = p;
+
+               if (p_hevc_slice_params->num_ref_idx_l0_active_minus1 >=
+                   V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
+                       return -EINVAL;
+
+               if (p_hevc_slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_B)
+                       break;
+
+               if (p_hevc_slice_params->num_ref_idx_l1_active_minus1 >=
+                   V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
+                       return -EINVAL;
                break;
 
        case V4L2_CTRL_TYPE_HEVC_EXT_SPS_ST_RPS: