public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists
@ 2026-03-23  8:30 Pengpeng Hou
  2026-03-23 13:41 ` Nicolas Dufresne
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Pengpeng Hou @ 2026-03-23  8:30 UTC (permalink / raw)
  To: mchehab
  Cc: hverkuil, nicolas.dufresne, sakari.ailus, laurent.pinchart,
	opensource206, jernej.skrabec, linux-media, linux-kernel,
	pengpeng

HEVC slice parameters are shared stateless V4L2 controls, but the common
control validation path currently does not verify the active reference
counts or the ref_idx_l0/ref_idx_l1 entries before driver-specific code
uses them to index fixed 16-entry DPB arrays.

The original report was triggered by Cedrus, but the missing validation
is not Cedrus-specific. Move the bounds checks into the common HEVC slice
control validation path so every stateless HEVC driver gets the same
basic guarantees as soon as the control is queued.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
v2:
- move the validation from Cedrus-specific try_ctrl() into
  drivers/media/v4l2-core/v4l2-ctrls-core.c
- keep the checks limited to HEVC slice reference counts and indices

 drivers/media/v4l2-core/v4l2-ctrls-core.c | 24 +++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index 6b375720e395..4e7563c8bf4a 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -1260,6 +1260,30 @@ 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;
+
+		for (i = 0; i <= p_hevc_slice_params->num_ref_idx_l0_active_minus1;
+		     i++)
+			if (p_hevc_slice_params->ref_idx_l0[i] >=
+			    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;
+
+		for (i = 0; i <= p_hevc_slice_params->num_ref_idx_l1_active_minus1;
+		     i++)
+			if (p_hevc_slice_params->ref_idx_l1[i] >=
+			    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
+				return -EINVAL;
 		break;
 
 	case V4L2_CTRL_TYPE_HEVC_EXT_SPS_ST_RPS:
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists
  2026-03-23  8:30 [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists Pengpeng Hou
@ 2026-03-23 13:41 ` Nicolas Dufresne
  2026-03-23 20:36 ` kernel test robot
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Nicolas Dufresne @ 2026-03-23 13:41 UTC (permalink / raw)
  To: Pengpeng Hou, mchehab
  Cc: hverkuil, sakari.ailus, laurent.pinchart, opensource206,
	jernej.skrabec, linux-media, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2681 bytes --]

Le lundi 23 mars 2026 à 16:30 +0800, Pengpeng Hou a écrit :
> HEVC slice parameters are shared stateless V4L2 controls, but the common
> control validation path currently does not verify the active reference
> counts or the ref_idx_l0/ref_idx_l1 entries before driver-specific code
> uses them to index fixed 16-entry DPB arrays.
> 
> The original report was triggered by Cedrus, but the missing validation
> is not Cedrus-specific. Move the bounds checks into the common HEVC slice
> control validation path so every stateless HEVC driver gets the same
> basic guarantees as soon as the control is queued.
> 
> Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
> ---
> v2:
> - move the validation from Cedrus-specific try_ctrl() into
>   drivers/media/v4l2-core/v4l2-ctrls-core.c
> - keep the checks limited to HEVC slice reference counts and indices
> 
>  drivers/media/v4l2-core/v4l2-ctrls-core.c | 24 +++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> index 6b375720e395..4e7563c8bf4a 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> @@ -1260,6 +1260,30 @@ 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;

Ack.

> +
> +		for (i = 0; i <= p_hevc_slice_params->num_ref_idx_l0_active_minus1;
> +		     i++)
> +			if (p_hevc_slice_params->ref_idx_l0[i] >=
> +			    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
> +				return -EINVAL;

That one is a breaking change since userspace already passes off limit values
such as 0xff when a reference is missing (was lost). See:

	47825b1646a6a9eca0f90baa3d4f98947c2add96

The hardware may or may not be capable of doing concealment, but with this
change, we bring down all drivers to failing the decode completely.

> +
> +		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;

Ack.

> +
> +		for (i = 0; i <= p_hevc_slice_params->num_ref_idx_l1_active_minus1;
> +		     i++)
> +			if (p_hevc_slice_params->ref_idx_l1[i] >=
> +			    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
> +				return -EINVAL;

Same.

cheers,
Nicolas

>  		break;
>  
>  	case V4L2_CTRL_TYPE_HEVC_EXT_SPS_ST_RPS:

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists
  2026-03-23  8:30 [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists Pengpeng Hou
  2026-03-23 13:41 ` Nicolas Dufresne
@ 2026-03-23 20:36 ` kernel test robot
  2026-03-23 20:36 ` kernel test robot
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2026-03-23 20:36 UTC (permalink / raw)
  To: Pengpeng Hou, mchehab
  Cc: oe-kbuild-all, hverkuil, nicolas.dufresne, sakari.ailus,
	laurent.pinchart, opensource206, jernej.skrabec, linux-media,
	linux-kernel, pengpeng

Hi Pengpeng,

kernel test robot noticed the following build errors:

[auto build test ERROR on linuxtv-media-pending/master]
[also build test ERROR on linus/master v7.0-rc5 next-20260323]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Pengpeng-Hou/media-v4l2-ctrls-validate-HEVC-slice-reference-lists/20260323-221415
base:   https://git.linuxtv.org/media-ci/media-pending.git master
patch link:    https://lore.kernel.org/r/20260323083031.30941-1-pengpeng%40iscas.ac.cn
patch subject: [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists
config: csky-randconfig-r071-20260324 (https://download.01.org/0day-ci/archive/20260324/202603240420.trq8jAvG-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 15.2.0
smatch: v0.5.0-9004-gb810ac53
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260324/202603240420.trq8jAvG-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603240420.trq8jAvG-lkp@intel.com/

All errors (new ones prefixed by >>):

   drivers/media/v4l2-core/v4l2-ctrls-core.c: In function 'std_validate_compound':
>> drivers/media/v4l2-core/v4l2-ctrls-core.c:1263:17: error: 'p_hevc_slice_params' undeclared (first use in this function); did you mean 'p_h264_slice_params'?
    1263 |                 p_hevc_slice_params = p;
         |                 ^~~~~~~~~~~~~~~~~~~
         |                 p_h264_slice_params
   drivers/media/v4l2-core/v4l2-ctrls-core.c:1263:17: note: each undeclared identifier is reported only once for each function it appears in


vim +1263 drivers/media/v4l2-core/v4l2-ctrls-core.c

   952	
   953	/*
   954	 * Compound controls validation requires setting unused fields/flags to zero
   955	 * in order to properly detect unchanged controls with v4l2_ctrl_type_op_equal's
   956	 * memcmp.
   957	 */
   958	static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
   959					 union v4l2_ctrl_ptr ptr)
   960	{
   961		struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
   962		struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
   963		struct v4l2_ctrl_vp8_frame *p_vp8_frame;
   964		struct v4l2_ctrl_fwht_params *p_fwht_params;
   965		struct v4l2_ctrl_h264_sps *p_h264_sps;
   966		struct v4l2_ctrl_h264_pps *p_h264_pps;
   967		struct v4l2_ctrl_h264_pred_weights *p_h264_pred_weights;
   968		struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
   969		struct v4l2_ctrl_h264_decode_params *p_h264_dec_params;
   970		struct v4l2_ctrl_hevc_ext_sps_lt_rps *p_hevc_lt_rps;
   971		struct v4l2_ctrl_hevc_ext_sps_st_rps *p_hevc_st_rps;
   972		struct v4l2_ctrl_hevc_sps *p_hevc_sps;
   973		struct v4l2_ctrl_hevc_pps *p_hevc_pps;
   974		struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering;
   975		struct v4l2_ctrl_hevc_decode_params *p_hevc_decode_params;
   976		struct v4l2_area *area;
   977		struct v4l2_rect *rect;
   978		void *p = ptr.p + idx * ctrl->elem_size;
   979		unsigned int i;
   980	
   981		switch ((u32)ctrl->type) {
   982		case V4L2_CTRL_TYPE_MPEG2_SEQUENCE:
   983			p_mpeg2_sequence = p;
   984	
   985			switch (p_mpeg2_sequence->chroma_format) {
   986			case 1: /* 4:2:0 */
   987			case 2: /* 4:2:2 */
   988			case 3: /* 4:4:4 */
   989				break;
   990			default:
   991				return -EINVAL;
   992			}
   993			break;
   994	
   995		case V4L2_CTRL_TYPE_MPEG2_PICTURE:
   996			p_mpeg2_picture = p;
   997	
   998			switch (p_mpeg2_picture->intra_dc_precision) {
   999			case 0: /* 8 bits */
  1000			case 1: /* 9 bits */
  1001			case 2: /* 10 bits */
  1002			case 3: /* 11 bits */
  1003				break;
  1004			default:
  1005				return -EINVAL;
  1006			}
  1007	
  1008			switch (p_mpeg2_picture->picture_structure) {
  1009			case V4L2_MPEG2_PIC_TOP_FIELD:
  1010			case V4L2_MPEG2_PIC_BOTTOM_FIELD:
  1011			case V4L2_MPEG2_PIC_FRAME:
  1012				break;
  1013			default:
  1014				return -EINVAL;
  1015			}
  1016	
  1017			switch (p_mpeg2_picture->picture_coding_type) {
  1018			case V4L2_MPEG2_PIC_CODING_TYPE_I:
  1019			case V4L2_MPEG2_PIC_CODING_TYPE_P:
  1020			case V4L2_MPEG2_PIC_CODING_TYPE_B:
  1021				break;
  1022			default:
  1023				return -EINVAL;
  1024			}
  1025			zero_reserved(*p_mpeg2_picture);
  1026			break;
  1027	
  1028		case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
  1029			break;
  1030	
  1031		case V4L2_CTRL_TYPE_FWHT_PARAMS:
  1032			p_fwht_params = p;
  1033			if (p_fwht_params->version < V4L2_FWHT_VERSION)
  1034				return -EINVAL;
  1035			if (!p_fwht_params->width || !p_fwht_params->height)
  1036				return -EINVAL;
  1037			break;
  1038	
  1039		case V4L2_CTRL_TYPE_H264_SPS:
  1040			p_h264_sps = p;
  1041	
  1042			/* Some syntax elements are only conditionally valid */
  1043			if (p_h264_sps->pic_order_cnt_type != 0) {
  1044				p_h264_sps->log2_max_pic_order_cnt_lsb_minus4 = 0;
  1045			} else if (p_h264_sps->pic_order_cnt_type != 1) {
  1046				p_h264_sps->num_ref_frames_in_pic_order_cnt_cycle = 0;
  1047				p_h264_sps->offset_for_non_ref_pic = 0;
  1048				p_h264_sps->offset_for_top_to_bottom_field = 0;
  1049				memset(&p_h264_sps->offset_for_ref_frame, 0,
  1050				       sizeof(p_h264_sps->offset_for_ref_frame));
  1051			}
  1052	
  1053			if (!V4L2_H264_SPS_HAS_CHROMA_FORMAT(p_h264_sps)) {
  1054				p_h264_sps->chroma_format_idc = 1;
  1055				p_h264_sps->bit_depth_luma_minus8 = 0;
  1056				p_h264_sps->bit_depth_chroma_minus8 = 0;
  1057	
  1058				p_h264_sps->flags &=
  1059					~V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS;
  1060			}
  1061	
  1062			if (p_h264_sps->chroma_format_idc < 3)
  1063				p_h264_sps->flags &=
  1064					~V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE;
  1065	
  1066			if (p_h264_sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)
  1067				p_h264_sps->flags &=
  1068					~V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD;
  1069	
  1070			/*
  1071			 * Chroma 4:2:2 format require at least High 4:2:2 profile.
  1072			 *
  1073			 * The H264 specification and well-known parser implementations
  1074			 * use profile-idc values directly, as that is clearer and
  1075			 * less ambiguous. We do the same here.
  1076			 */
  1077			if (p_h264_sps->profile_idc < 122 &&
  1078			    p_h264_sps->chroma_format_idc > 1)
  1079				return -EINVAL;
  1080			/* Chroma 4:4:4 format require at least High 4:2:2 profile */
  1081			if (p_h264_sps->profile_idc < 244 &&
  1082			    p_h264_sps->chroma_format_idc > 2)
  1083				return -EINVAL;
  1084			if (p_h264_sps->chroma_format_idc > 3)
  1085				return -EINVAL;
  1086	
  1087			if (p_h264_sps->bit_depth_luma_minus8 > 6)
  1088				return -EINVAL;
  1089			if (p_h264_sps->bit_depth_chroma_minus8 > 6)
  1090				return -EINVAL;
  1091			if (p_h264_sps->log2_max_frame_num_minus4 > 12)
  1092				return -EINVAL;
  1093			if (p_h264_sps->pic_order_cnt_type > 2)
  1094				return -EINVAL;
  1095			if (p_h264_sps->log2_max_pic_order_cnt_lsb_minus4 > 12)
  1096				return -EINVAL;
  1097			if (p_h264_sps->max_num_ref_frames > V4L2_H264_REF_LIST_LEN)
  1098				return -EINVAL;
  1099			break;
  1100	
  1101		case V4L2_CTRL_TYPE_H264_PPS:
  1102			p_h264_pps = p;
  1103	
  1104			if (p_h264_pps->num_slice_groups_minus1 > 7)
  1105				return -EINVAL;
  1106			if (p_h264_pps->num_ref_idx_l0_default_active_minus1 >
  1107			    (V4L2_H264_REF_LIST_LEN - 1))
  1108				return -EINVAL;
  1109			if (p_h264_pps->num_ref_idx_l1_default_active_minus1 >
  1110			    (V4L2_H264_REF_LIST_LEN - 1))
  1111				return -EINVAL;
  1112			if (p_h264_pps->weighted_bipred_idc > 2)
  1113				return -EINVAL;
  1114			/*
  1115			 * pic_init_qp_minus26 shall be in the range of
  1116			 * -(26 + QpBdOffset_y) to +25, inclusive,
  1117			 *  where QpBdOffset_y is 6 * bit_depth_luma_minus8
  1118			 */
  1119			if (p_h264_pps->pic_init_qp_minus26 < -62 ||
  1120			    p_h264_pps->pic_init_qp_minus26 > 25)
  1121				return -EINVAL;
  1122			if (p_h264_pps->pic_init_qs_minus26 < -26 ||
  1123			    p_h264_pps->pic_init_qs_minus26 > 25)
  1124				return -EINVAL;
  1125			if (p_h264_pps->chroma_qp_index_offset < -12 ||
  1126			    p_h264_pps->chroma_qp_index_offset > 12)
  1127				return -EINVAL;
  1128			if (p_h264_pps->second_chroma_qp_index_offset < -12 ||
  1129			    p_h264_pps->second_chroma_qp_index_offset > 12)
  1130				return -EINVAL;
  1131			break;
  1132	
  1133		case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
  1134			break;
  1135	
  1136		case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS:
  1137			p_h264_pred_weights = p;
  1138	
  1139			if (p_h264_pred_weights->luma_log2_weight_denom > 7)
  1140				return -EINVAL;
  1141			if (p_h264_pred_weights->chroma_log2_weight_denom > 7)
  1142				return -EINVAL;
  1143			break;
  1144	
  1145		case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
  1146			p_h264_slice_params = p;
  1147	
  1148			if (p_h264_slice_params->slice_type != V4L2_H264_SLICE_TYPE_B)
  1149				p_h264_slice_params->flags &=
  1150					~V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED;
  1151	
  1152			if (p_h264_slice_params->colour_plane_id > 2)
  1153				return -EINVAL;
  1154			if (p_h264_slice_params->cabac_init_idc > 2)
  1155				return -EINVAL;
  1156			if (p_h264_slice_params->disable_deblocking_filter_idc > 2)
  1157				return -EINVAL;
  1158			if (p_h264_slice_params->slice_alpha_c0_offset_div2 < -6 ||
  1159			    p_h264_slice_params->slice_alpha_c0_offset_div2 > 6)
  1160				return -EINVAL;
  1161			if (p_h264_slice_params->slice_beta_offset_div2 < -6 ||
  1162			    p_h264_slice_params->slice_beta_offset_div2 > 6)
  1163				return -EINVAL;
  1164	
  1165			if (p_h264_slice_params->slice_type == V4L2_H264_SLICE_TYPE_I ||
  1166			    p_h264_slice_params->slice_type == V4L2_H264_SLICE_TYPE_SI)
  1167				p_h264_slice_params->num_ref_idx_l0_active_minus1 = 0;
  1168			if (p_h264_slice_params->slice_type != V4L2_H264_SLICE_TYPE_B)
  1169				p_h264_slice_params->num_ref_idx_l1_active_minus1 = 0;
  1170	
  1171			if (p_h264_slice_params->num_ref_idx_l0_active_minus1 >
  1172			    (V4L2_H264_REF_LIST_LEN - 1))
  1173				return -EINVAL;
  1174			if (p_h264_slice_params->num_ref_idx_l1_active_minus1 >
  1175			    (V4L2_H264_REF_LIST_LEN - 1))
  1176				return -EINVAL;
  1177			zero_reserved(*p_h264_slice_params);
  1178			break;
  1179	
  1180		case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
  1181			p_h264_dec_params = p;
  1182	
  1183			if (p_h264_dec_params->nal_ref_idc > 3)
  1184				return -EINVAL;
  1185			for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) {
  1186				struct v4l2_h264_dpb_entry *dpb_entry =
  1187					&p_h264_dec_params->dpb[i];
  1188	
  1189				zero_reserved(*dpb_entry);
  1190			}
  1191			zero_reserved(*p_h264_dec_params);
  1192			break;
  1193	
  1194		case V4L2_CTRL_TYPE_VP8_FRAME:
  1195			p_vp8_frame = p;
  1196	
  1197			switch (p_vp8_frame->num_dct_parts) {
  1198			case 1:
  1199			case 2:
  1200			case 4:
  1201			case 8:
  1202				break;
  1203			default:
  1204				return -EINVAL;
  1205			}
  1206			zero_padding(p_vp8_frame->segment);
  1207			zero_padding(p_vp8_frame->lf);
  1208			zero_padding(p_vp8_frame->quant);
  1209			zero_padding(p_vp8_frame->entropy);
  1210			zero_padding(p_vp8_frame->coder_state);
  1211			break;
  1212	
  1213		case V4L2_CTRL_TYPE_HEVC_SPS:
  1214			p_hevc_sps = p;
  1215	
  1216			if (!(p_hevc_sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED)) {
  1217				p_hevc_sps->pcm_sample_bit_depth_luma_minus1 = 0;
  1218				p_hevc_sps->pcm_sample_bit_depth_chroma_minus1 = 0;
  1219				p_hevc_sps->log2_min_pcm_luma_coding_block_size_minus3 = 0;
  1220				p_hevc_sps->log2_diff_max_min_pcm_luma_coding_block_size = 0;
  1221			}
  1222	
  1223			if (!(p_hevc_sps->flags &
  1224			      V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT))
  1225				p_hevc_sps->num_long_term_ref_pics_sps = 0;
  1226			break;
  1227	
  1228		case V4L2_CTRL_TYPE_HEVC_PPS:
  1229			p_hevc_pps = p;
  1230	
  1231			if (!(p_hevc_pps->flags &
  1232			      V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED))
  1233				p_hevc_pps->diff_cu_qp_delta_depth = 0;
  1234	
  1235			if (!(p_hevc_pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED)) {
  1236				p_hevc_pps->num_tile_columns_minus1 = 0;
  1237				p_hevc_pps->num_tile_rows_minus1 = 0;
  1238				memset(&p_hevc_pps->column_width_minus1, 0,
  1239				       sizeof(p_hevc_pps->column_width_minus1));
  1240				memset(&p_hevc_pps->row_height_minus1, 0,
  1241				       sizeof(p_hevc_pps->row_height_minus1));
  1242	
  1243				p_hevc_pps->flags &=
  1244					~V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED;
  1245			}
  1246	
  1247			if (p_hevc_pps->flags &
  1248			    V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER) {
  1249				p_hevc_pps->pps_beta_offset_div2 = 0;
  1250				p_hevc_pps->pps_tc_offset_div2 = 0;
  1251			}
  1252			break;
  1253	
  1254		case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS:
  1255			p_hevc_decode_params = p;
  1256	
  1257			if (p_hevc_decode_params->num_active_dpb_entries >
  1258			    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
  1259				return -EINVAL;
  1260			break;
  1261	
  1262		case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
> 1263			p_hevc_slice_params = p;
  1264	
  1265			if (p_hevc_slice_params->num_ref_idx_l0_active_minus1 >=
  1266			    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
  1267				return -EINVAL;
  1268	
  1269			for (i = 0; i <= p_hevc_slice_params->num_ref_idx_l0_active_minus1;
  1270			     i++)
  1271				if (p_hevc_slice_params->ref_idx_l0[i] >=
  1272				    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
  1273					return -EINVAL;
  1274	
  1275			if (p_hevc_slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_B)
  1276				break;
  1277	
  1278			if (p_hevc_slice_params->num_ref_idx_l1_active_minus1 >=
  1279			    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
  1280				return -EINVAL;
  1281	
  1282			for (i = 0; i <= p_hevc_slice_params->num_ref_idx_l1_active_minus1;
  1283			     i++)
  1284				if (p_hevc_slice_params->ref_idx_l1[i] >=
  1285				    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
  1286					return -EINVAL;
  1287			break;
  1288	
  1289		case V4L2_CTRL_TYPE_HEVC_EXT_SPS_ST_RPS:
  1290			p_hevc_st_rps = p;
  1291	
  1292			if (p_hevc_st_rps->flags & ~V4L2_HEVC_EXT_SPS_ST_RPS_FLAG_INTER_REF_PIC_SET_PRED)
  1293				return -EINVAL;
  1294			break;
  1295	
  1296		case V4L2_CTRL_TYPE_HEVC_EXT_SPS_LT_RPS:
  1297			p_hevc_lt_rps = p;
  1298	
  1299			if (p_hevc_lt_rps->flags & ~V4L2_HEVC_EXT_SPS_LT_RPS_FLAG_USED_LT)
  1300				return -EINVAL;
  1301			break;
  1302	
  1303		case V4L2_CTRL_TYPE_HDR10_CLL_INFO:
  1304			break;
  1305	
  1306		case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY:
  1307			p_hdr10_mastering = p;
  1308	
  1309			for (i = 0; i < 3; ++i) {
  1310				if (p_hdr10_mastering->display_primaries_x[i] <
  1311					V4L2_HDR10_MASTERING_PRIMARIES_X_LOW ||
  1312				    p_hdr10_mastering->display_primaries_x[i] >
  1313					V4L2_HDR10_MASTERING_PRIMARIES_X_HIGH ||
  1314				    p_hdr10_mastering->display_primaries_y[i] <
  1315					V4L2_HDR10_MASTERING_PRIMARIES_Y_LOW ||
  1316				    p_hdr10_mastering->display_primaries_y[i] >
  1317					V4L2_HDR10_MASTERING_PRIMARIES_Y_HIGH)
  1318					return -EINVAL;
  1319			}
  1320	
  1321			if (p_hdr10_mastering->white_point_x <
  1322				V4L2_HDR10_MASTERING_WHITE_POINT_X_LOW ||
  1323			    p_hdr10_mastering->white_point_x >
  1324				V4L2_HDR10_MASTERING_WHITE_POINT_X_HIGH ||
  1325			    p_hdr10_mastering->white_point_y <
  1326				V4L2_HDR10_MASTERING_WHITE_POINT_Y_LOW ||
  1327			    p_hdr10_mastering->white_point_y >
  1328				V4L2_HDR10_MASTERING_WHITE_POINT_Y_HIGH)
  1329				return -EINVAL;
  1330	
  1331			if (p_hdr10_mastering->max_display_mastering_luminance <
  1332				V4L2_HDR10_MASTERING_MAX_LUMA_LOW ||
  1333			    p_hdr10_mastering->max_display_mastering_luminance >
  1334				V4L2_HDR10_MASTERING_MAX_LUMA_HIGH ||
  1335			    p_hdr10_mastering->min_display_mastering_luminance <
  1336				V4L2_HDR10_MASTERING_MIN_LUMA_LOW ||
  1337			    p_hdr10_mastering->min_display_mastering_luminance >
  1338				V4L2_HDR10_MASTERING_MIN_LUMA_HIGH)
  1339				return -EINVAL;
  1340	
  1341			/* The following restriction comes from ITU-T Rec. H.265 spec */
  1342			if (p_hdr10_mastering->max_display_mastering_luminance ==
  1343				V4L2_HDR10_MASTERING_MAX_LUMA_LOW &&
  1344			    p_hdr10_mastering->min_display_mastering_luminance ==
  1345				V4L2_HDR10_MASTERING_MIN_LUMA_HIGH)
  1346				return -EINVAL;
  1347	
  1348			break;
  1349	
  1350		case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
  1351			break;
  1352	
  1353		case V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR:
  1354			return validate_vp9_compressed_hdr(p);
  1355	
  1356		case V4L2_CTRL_TYPE_VP9_FRAME:
  1357			return validate_vp9_frame(p);
  1358		case V4L2_CTRL_TYPE_AV1_FRAME:
  1359			return validate_av1_frame(p);
  1360		case V4L2_CTRL_TYPE_AV1_SEQUENCE:
  1361			return validate_av1_sequence(p);
  1362		case V4L2_CTRL_TYPE_AV1_TILE_GROUP_ENTRY:
  1363			break;
  1364		case V4L2_CTRL_TYPE_AV1_FILM_GRAIN:
  1365			return validate_av1_film_grain(p);
  1366	
  1367		case V4L2_CTRL_TYPE_AREA:
  1368			area = p;
  1369			if (!area->width || !area->height)
  1370				return -EINVAL;
  1371			break;
  1372	
  1373		case V4L2_CTRL_TYPE_RECT:
  1374			rect = p;
  1375			if (!rect->width || !rect->height)
  1376				return -EINVAL;
  1377			break;
  1378	
  1379		default:
  1380			return -EINVAL;
  1381		}
  1382	
  1383		return 0;
  1384	}
  1385	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists
  2026-03-23  8:30 [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists Pengpeng Hou
  2026-03-23 13:41 ` Nicolas Dufresne
  2026-03-23 20:36 ` kernel test robot
@ 2026-03-23 20:36 ` kernel test robot
  2026-03-24  3:13 ` Pengpeng Hou
  2026-03-24  3:13 ` [PATCH v3] media: v4l2-ctrls: validate HEVC active reference counts Pengpeng Hou
  4 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2026-03-23 20:36 UTC (permalink / raw)
  To: Pengpeng Hou, mchehab
  Cc: llvm, oe-kbuild-all, hverkuil, nicolas.dufresne, sakari.ailus,
	laurent.pinchart, opensource206, jernej.skrabec, linux-media,
	linux-kernel, pengpeng

Hi Pengpeng,

kernel test robot noticed the following build errors:

[auto build test ERROR on linuxtv-media-pending/master]
[also build test ERROR on linus/master v7.0-rc5 next-20260323]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Pengpeng-Hou/media-v4l2-ctrls-validate-HEVC-slice-reference-lists/20260323-221415
base:   https://git.linuxtv.org/media-ci/media-pending.git master
patch link:    https://lore.kernel.org/r/20260323083031.30941-1-pengpeng%40iscas.ac.cn
patch subject: [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists
config: s390-randconfig-002-20260324 (https://download.01.org/0day-ci/archive/20260324/202603240457.8kfXE4xy-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 054e11d1a17e5ba88bb1a8ef32fad3346e80b186)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260324/202603240457.8kfXE4xy-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603240457.8kfXE4xy-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/media/v4l2-core/v4l2-ctrls-core.c:1263:3: error: use of undeclared identifier 'p_hevc_slice_params'; did you mean 'p_h264_slice_params'?
    1263 |                 p_hevc_slice_params = p;
         |                 ^~~~~~~~~~~~~~~~~~~
         |                 p_h264_slice_params
   drivers/media/v4l2-core/v4l2-ctrls-core.c:968:38: note: 'p_h264_slice_params' declared here
     968 |         struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
         |                                             ^
   drivers/media/v4l2-core/v4l2-ctrls-core.c:1265:7: error: use of undeclared identifier 'p_hevc_slice_params'; did you mean 'p_h264_slice_params'?
    1265 |                 if (p_hevc_slice_params->num_ref_idx_l0_active_minus1 >=
         |                     ^~~~~~~~~~~~~~~~~~~
         |                     p_h264_slice_params
   drivers/media/v4l2-core/v4l2-ctrls-core.c:968:38: note: 'p_h264_slice_params' declared here
     968 |         struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
         |                                             ^
   drivers/media/v4l2-core/v4l2-ctrls-core.c:1269:20: error: use of undeclared identifier 'p_hevc_slice_params'; did you mean 'p_h264_slice_params'?
    1269 |                 for (i = 0; i <= p_hevc_slice_params->num_ref_idx_l0_active_minus1;
         |                                  ^~~~~~~~~~~~~~~~~~~
         |                                  p_h264_slice_params
   drivers/media/v4l2-core/v4l2-ctrls-core.c:968:38: note: 'p_h264_slice_params' declared here
     968 |         struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
         |                                             ^
   drivers/media/v4l2-core/v4l2-ctrls-core.c:1271:8: error: use of undeclared identifier 'p_hevc_slice_params'; did you mean 'p_h264_slice_params'?
    1271 |                         if (p_hevc_slice_params->ref_idx_l0[i] >=
         |                             ^~~~~~~~~~~~~~~~~~~
         |                             p_h264_slice_params
   drivers/media/v4l2-core/v4l2-ctrls-core.c:968:38: note: 'p_h264_slice_params' declared here
     968 |         struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
         |                                             ^
>> drivers/media/v4l2-core/v4l2-ctrls-core.c:1271:29: error: no member named 'ref_idx_l0' in 'struct v4l2_ctrl_h264_slice_params'
    1271 |                         if (p_hevc_slice_params->ref_idx_l0[i] >=
         |                             ~~~~~~~~~~~~~~~~~~~  ^
   drivers/media/v4l2-core/v4l2-ctrls-core.c:1275:7: error: use of undeclared identifier 'p_hevc_slice_params'; did you mean 'p_h264_slice_params'?
    1275 |                 if (p_hevc_slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_B)
         |                     ^~~~~~~~~~~~~~~~~~~
         |                     p_h264_slice_params
   drivers/media/v4l2-core/v4l2-ctrls-core.c:968:38: note: 'p_h264_slice_params' declared here
     968 |         struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
         |                                             ^
   drivers/media/v4l2-core/v4l2-ctrls-core.c:1278:7: error: use of undeclared identifier 'p_hevc_slice_params'; did you mean 'p_h264_slice_params'?
    1278 |                 if (p_hevc_slice_params->num_ref_idx_l1_active_minus1 >=
         |                     ^~~~~~~~~~~~~~~~~~~
         |                     p_h264_slice_params
   drivers/media/v4l2-core/v4l2-ctrls-core.c:968:38: note: 'p_h264_slice_params' declared here
     968 |         struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
         |                                             ^
   drivers/media/v4l2-core/v4l2-ctrls-core.c:1282:20: error: use of undeclared identifier 'p_hevc_slice_params'; did you mean 'p_h264_slice_params'?
    1282 |                 for (i = 0; i <= p_hevc_slice_params->num_ref_idx_l1_active_minus1;
         |                                  ^~~~~~~~~~~~~~~~~~~
         |                                  p_h264_slice_params
   drivers/media/v4l2-core/v4l2-ctrls-core.c:968:38: note: 'p_h264_slice_params' declared here
     968 |         struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
         |                                             ^
   drivers/media/v4l2-core/v4l2-ctrls-core.c:1284:8: error: use of undeclared identifier 'p_hevc_slice_params'; did you mean 'p_h264_slice_params'?
    1284 |                         if (p_hevc_slice_params->ref_idx_l1[i] >=
         |                             ^~~~~~~~~~~~~~~~~~~
         |                             p_h264_slice_params
   drivers/media/v4l2-core/v4l2-ctrls-core.c:968:38: note: 'p_h264_slice_params' declared here
     968 |         struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
         |                                             ^
>> drivers/media/v4l2-core/v4l2-ctrls-core.c:1284:29: error: no member named 'ref_idx_l1' in 'struct v4l2_ctrl_h264_slice_params'
    1284 |                         if (p_hevc_slice_params->ref_idx_l1[i] >=
         |                             ~~~~~~~~~~~~~~~~~~~  ^
   10 errors generated.


vim +1263 drivers/media/v4l2-core/v4l2-ctrls-core.c

   952	
   953	/*
   954	 * Compound controls validation requires setting unused fields/flags to zero
   955	 * in order to properly detect unchanged controls with v4l2_ctrl_type_op_equal's
   956	 * memcmp.
   957	 */
   958	static int std_validate_compound(const struct v4l2_ctrl *ctrl, u32 idx,
   959					 union v4l2_ctrl_ptr ptr)
   960	{
   961		struct v4l2_ctrl_mpeg2_sequence *p_mpeg2_sequence;
   962		struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
   963		struct v4l2_ctrl_vp8_frame *p_vp8_frame;
   964		struct v4l2_ctrl_fwht_params *p_fwht_params;
   965		struct v4l2_ctrl_h264_sps *p_h264_sps;
   966		struct v4l2_ctrl_h264_pps *p_h264_pps;
   967		struct v4l2_ctrl_h264_pred_weights *p_h264_pred_weights;
   968		struct v4l2_ctrl_h264_slice_params *p_h264_slice_params;
   969		struct v4l2_ctrl_h264_decode_params *p_h264_dec_params;
   970		struct v4l2_ctrl_hevc_ext_sps_lt_rps *p_hevc_lt_rps;
   971		struct v4l2_ctrl_hevc_ext_sps_st_rps *p_hevc_st_rps;
   972		struct v4l2_ctrl_hevc_sps *p_hevc_sps;
   973		struct v4l2_ctrl_hevc_pps *p_hevc_pps;
   974		struct v4l2_ctrl_hdr10_mastering_display *p_hdr10_mastering;
   975		struct v4l2_ctrl_hevc_decode_params *p_hevc_decode_params;
   976		struct v4l2_area *area;
   977		struct v4l2_rect *rect;
   978		void *p = ptr.p + idx * ctrl->elem_size;
   979		unsigned int i;
   980	
   981		switch ((u32)ctrl->type) {
   982		case V4L2_CTRL_TYPE_MPEG2_SEQUENCE:
   983			p_mpeg2_sequence = p;
   984	
   985			switch (p_mpeg2_sequence->chroma_format) {
   986			case 1: /* 4:2:0 */
   987			case 2: /* 4:2:2 */
   988			case 3: /* 4:4:4 */
   989				break;
   990			default:
   991				return -EINVAL;
   992			}
   993			break;
   994	
   995		case V4L2_CTRL_TYPE_MPEG2_PICTURE:
   996			p_mpeg2_picture = p;
   997	
   998			switch (p_mpeg2_picture->intra_dc_precision) {
   999			case 0: /* 8 bits */
  1000			case 1: /* 9 bits */
  1001			case 2: /* 10 bits */
  1002			case 3: /* 11 bits */
  1003				break;
  1004			default:
  1005				return -EINVAL;
  1006			}
  1007	
  1008			switch (p_mpeg2_picture->picture_structure) {
  1009			case V4L2_MPEG2_PIC_TOP_FIELD:
  1010			case V4L2_MPEG2_PIC_BOTTOM_FIELD:
  1011			case V4L2_MPEG2_PIC_FRAME:
  1012				break;
  1013			default:
  1014				return -EINVAL;
  1015			}
  1016	
  1017			switch (p_mpeg2_picture->picture_coding_type) {
  1018			case V4L2_MPEG2_PIC_CODING_TYPE_I:
  1019			case V4L2_MPEG2_PIC_CODING_TYPE_P:
  1020			case V4L2_MPEG2_PIC_CODING_TYPE_B:
  1021				break;
  1022			default:
  1023				return -EINVAL;
  1024			}
  1025			zero_reserved(*p_mpeg2_picture);
  1026			break;
  1027	
  1028		case V4L2_CTRL_TYPE_MPEG2_QUANTISATION:
  1029			break;
  1030	
  1031		case V4L2_CTRL_TYPE_FWHT_PARAMS:
  1032			p_fwht_params = p;
  1033			if (p_fwht_params->version < V4L2_FWHT_VERSION)
  1034				return -EINVAL;
  1035			if (!p_fwht_params->width || !p_fwht_params->height)
  1036				return -EINVAL;
  1037			break;
  1038	
  1039		case V4L2_CTRL_TYPE_H264_SPS:
  1040			p_h264_sps = p;
  1041	
  1042			/* Some syntax elements are only conditionally valid */
  1043			if (p_h264_sps->pic_order_cnt_type != 0) {
  1044				p_h264_sps->log2_max_pic_order_cnt_lsb_minus4 = 0;
  1045			} else if (p_h264_sps->pic_order_cnt_type != 1) {
  1046				p_h264_sps->num_ref_frames_in_pic_order_cnt_cycle = 0;
  1047				p_h264_sps->offset_for_non_ref_pic = 0;
  1048				p_h264_sps->offset_for_top_to_bottom_field = 0;
  1049				memset(&p_h264_sps->offset_for_ref_frame, 0,
  1050				       sizeof(p_h264_sps->offset_for_ref_frame));
  1051			}
  1052	
  1053			if (!V4L2_H264_SPS_HAS_CHROMA_FORMAT(p_h264_sps)) {
  1054				p_h264_sps->chroma_format_idc = 1;
  1055				p_h264_sps->bit_depth_luma_minus8 = 0;
  1056				p_h264_sps->bit_depth_chroma_minus8 = 0;
  1057	
  1058				p_h264_sps->flags &=
  1059					~V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS;
  1060			}
  1061	
  1062			if (p_h264_sps->chroma_format_idc < 3)
  1063				p_h264_sps->flags &=
  1064					~V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE;
  1065	
  1066			if (p_h264_sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)
  1067				p_h264_sps->flags &=
  1068					~V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD;
  1069	
  1070			/*
  1071			 * Chroma 4:2:2 format require at least High 4:2:2 profile.
  1072			 *
  1073			 * The H264 specification and well-known parser implementations
  1074			 * use profile-idc values directly, as that is clearer and
  1075			 * less ambiguous. We do the same here.
  1076			 */
  1077			if (p_h264_sps->profile_idc < 122 &&
  1078			    p_h264_sps->chroma_format_idc > 1)
  1079				return -EINVAL;
  1080			/* Chroma 4:4:4 format require at least High 4:2:2 profile */
  1081			if (p_h264_sps->profile_idc < 244 &&
  1082			    p_h264_sps->chroma_format_idc > 2)
  1083				return -EINVAL;
  1084			if (p_h264_sps->chroma_format_idc > 3)
  1085				return -EINVAL;
  1086	
  1087			if (p_h264_sps->bit_depth_luma_minus8 > 6)
  1088				return -EINVAL;
  1089			if (p_h264_sps->bit_depth_chroma_minus8 > 6)
  1090				return -EINVAL;
  1091			if (p_h264_sps->log2_max_frame_num_minus4 > 12)
  1092				return -EINVAL;
  1093			if (p_h264_sps->pic_order_cnt_type > 2)
  1094				return -EINVAL;
  1095			if (p_h264_sps->log2_max_pic_order_cnt_lsb_minus4 > 12)
  1096				return -EINVAL;
  1097			if (p_h264_sps->max_num_ref_frames > V4L2_H264_REF_LIST_LEN)
  1098				return -EINVAL;
  1099			break;
  1100	
  1101		case V4L2_CTRL_TYPE_H264_PPS:
  1102			p_h264_pps = p;
  1103	
  1104			if (p_h264_pps->num_slice_groups_minus1 > 7)
  1105				return -EINVAL;
  1106			if (p_h264_pps->num_ref_idx_l0_default_active_minus1 >
  1107			    (V4L2_H264_REF_LIST_LEN - 1))
  1108				return -EINVAL;
  1109			if (p_h264_pps->num_ref_idx_l1_default_active_minus1 >
  1110			    (V4L2_H264_REF_LIST_LEN - 1))
  1111				return -EINVAL;
  1112			if (p_h264_pps->weighted_bipred_idc > 2)
  1113				return -EINVAL;
  1114			/*
  1115			 * pic_init_qp_minus26 shall be in the range of
  1116			 * -(26 + QpBdOffset_y) to +25, inclusive,
  1117			 *  where QpBdOffset_y is 6 * bit_depth_luma_minus8
  1118			 */
  1119			if (p_h264_pps->pic_init_qp_minus26 < -62 ||
  1120			    p_h264_pps->pic_init_qp_minus26 > 25)
  1121				return -EINVAL;
  1122			if (p_h264_pps->pic_init_qs_minus26 < -26 ||
  1123			    p_h264_pps->pic_init_qs_minus26 > 25)
  1124				return -EINVAL;
  1125			if (p_h264_pps->chroma_qp_index_offset < -12 ||
  1126			    p_h264_pps->chroma_qp_index_offset > 12)
  1127				return -EINVAL;
  1128			if (p_h264_pps->second_chroma_qp_index_offset < -12 ||
  1129			    p_h264_pps->second_chroma_qp_index_offset > 12)
  1130				return -EINVAL;
  1131			break;
  1132	
  1133		case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
  1134			break;
  1135	
  1136		case V4L2_CTRL_TYPE_H264_PRED_WEIGHTS:
  1137			p_h264_pred_weights = p;
  1138	
  1139			if (p_h264_pred_weights->luma_log2_weight_denom > 7)
  1140				return -EINVAL;
  1141			if (p_h264_pred_weights->chroma_log2_weight_denom > 7)
  1142				return -EINVAL;
  1143			break;
  1144	
  1145		case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
  1146			p_h264_slice_params = p;
  1147	
  1148			if (p_h264_slice_params->slice_type != V4L2_H264_SLICE_TYPE_B)
  1149				p_h264_slice_params->flags &=
  1150					~V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED;
  1151	
  1152			if (p_h264_slice_params->colour_plane_id > 2)
  1153				return -EINVAL;
  1154			if (p_h264_slice_params->cabac_init_idc > 2)
  1155				return -EINVAL;
  1156			if (p_h264_slice_params->disable_deblocking_filter_idc > 2)
  1157				return -EINVAL;
  1158			if (p_h264_slice_params->slice_alpha_c0_offset_div2 < -6 ||
  1159			    p_h264_slice_params->slice_alpha_c0_offset_div2 > 6)
  1160				return -EINVAL;
  1161			if (p_h264_slice_params->slice_beta_offset_div2 < -6 ||
  1162			    p_h264_slice_params->slice_beta_offset_div2 > 6)
  1163				return -EINVAL;
  1164	
  1165			if (p_h264_slice_params->slice_type == V4L2_H264_SLICE_TYPE_I ||
  1166			    p_h264_slice_params->slice_type == V4L2_H264_SLICE_TYPE_SI)
  1167				p_h264_slice_params->num_ref_idx_l0_active_minus1 = 0;
  1168			if (p_h264_slice_params->slice_type != V4L2_H264_SLICE_TYPE_B)
  1169				p_h264_slice_params->num_ref_idx_l1_active_minus1 = 0;
  1170	
  1171			if (p_h264_slice_params->num_ref_idx_l0_active_minus1 >
  1172			    (V4L2_H264_REF_LIST_LEN - 1))
  1173				return -EINVAL;
  1174			if (p_h264_slice_params->num_ref_idx_l1_active_minus1 >
  1175			    (V4L2_H264_REF_LIST_LEN - 1))
  1176				return -EINVAL;
  1177			zero_reserved(*p_h264_slice_params);
  1178			break;
  1179	
  1180		case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
  1181			p_h264_dec_params = p;
  1182	
  1183			if (p_h264_dec_params->nal_ref_idc > 3)
  1184				return -EINVAL;
  1185			for (i = 0; i < V4L2_H264_NUM_DPB_ENTRIES; i++) {
  1186				struct v4l2_h264_dpb_entry *dpb_entry =
  1187					&p_h264_dec_params->dpb[i];
  1188	
  1189				zero_reserved(*dpb_entry);
  1190			}
  1191			zero_reserved(*p_h264_dec_params);
  1192			break;
  1193	
  1194		case V4L2_CTRL_TYPE_VP8_FRAME:
  1195			p_vp8_frame = p;
  1196	
  1197			switch (p_vp8_frame->num_dct_parts) {
  1198			case 1:
  1199			case 2:
  1200			case 4:
  1201			case 8:
  1202				break;
  1203			default:
  1204				return -EINVAL;
  1205			}
  1206			zero_padding(p_vp8_frame->segment);
  1207			zero_padding(p_vp8_frame->lf);
  1208			zero_padding(p_vp8_frame->quant);
  1209			zero_padding(p_vp8_frame->entropy);
  1210			zero_padding(p_vp8_frame->coder_state);
  1211			break;
  1212	
  1213		case V4L2_CTRL_TYPE_HEVC_SPS:
  1214			p_hevc_sps = p;
  1215	
  1216			if (!(p_hevc_sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED)) {
  1217				p_hevc_sps->pcm_sample_bit_depth_luma_minus1 = 0;
  1218				p_hevc_sps->pcm_sample_bit_depth_chroma_minus1 = 0;
  1219				p_hevc_sps->log2_min_pcm_luma_coding_block_size_minus3 = 0;
  1220				p_hevc_sps->log2_diff_max_min_pcm_luma_coding_block_size = 0;
  1221			}
  1222	
  1223			if (!(p_hevc_sps->flags &
  1224			      V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT))
  1225				p_hevc_sps->num_long_term_ref_pics_sps = 0;
  1226			break;
  1227	
  1228		case V4L2_CTRL_TYPE_HEVC_PPS:
  1229			p_hevc_pps = p;
  1230	
  1231			if (!(p_hevc_pps->flags &
  1232			      V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED))
  1233				p_hevc_pps->diff_cu_qp_delta_depth = 0;
  1234	
  1235			if (!(p_hevc_pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED)) {
  1236				p_hevc_pps->num_tile_columns_minus1 = 0;
  1237				p_hevc_pps->num_tile_rows_minus1 = 0;
  1238				memset(&p_hevc_pps->column_width_minus1, 0,
  1239				       sizeof(p_hevc_pps->column_width_minus1));
  1240				memset(&p_hevc_pps->row_height_minus1, 0,
  1241				       sizeof(p_hevc_pps->row_height_minus1));
  1242	
  1243				p_hevc_pps->flags &=
  1244					~V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED;
  1245			}
  1246	
  1247			if (p_hevc_pps->flags &
  1248			    V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER) {
  1249				p_hevc_pps->pps_beta_offset_div2 = 0;
  1250				p_hevc_pps->pps_tc_offset_div2 = 0;
  1251			}
  1252			break;
  1253	
  1254		case V4L2_CTRL_TYPE_HEVC_DECODE_PARAMS:
  1255			p_hevc_decode_params = p;
  1256	
  1257			if (p_hevc_decode_params->num_active_dpb_entries >
  1258			    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
  1259				return -EINVAL;
  1260			break;
  1261	
  1262		case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS:
> 1263			p_hevc_slice_params = p;
  1264	
  1265			if (p_hevc_slice_params->num_ref_idx_l0_active_minus1 >=
  1266			    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
  1267				return -EINVAL;
  1268	
  1269			for (i = 0; i <= p_hevc_slice_params->num_ref_idx_l0_active_minus1;
  1270			     i++)
> 1271				if (p_hevc_slice_params->ref_idx_l0[i] >=
  1272				    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
  1273					return -EINVAL;
  1274	
  1275			if (p_hevc_slice_params->slice_type != V4L2_HEVC_SLICE_TYPE_B)
  1276				break;
  1277	
  1278			if (p_hevc_slice_params->num_ref_idx_l1_active_minus1 >=
  1279			    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
  1280				return -EINVAL;
  1281	
  1282			for (i = 0; i <= p_hevc_slice_params->num_ref_idx_l1_active_minus1;
  1283			     i++)
> 1284				if (p_hevc_slice_params->ref_idx_l1[i] >=
  1285				    V4L2_HEVC_DPB_ENTRIES_NUM_MAX)
  1286					return -EINVAL;
  1287			break;
  1288	
  1289		case V4L2_CTRL_TYPE_HEVC_EXT_SPS_ST_RPS:
  1290			p_hevc_st_rps = p;
  1291	
  1292			if (p_hevc_st_rps->flags & ~V4L2_HEVC_EXT_SPS_ST_RPS_FLAG_INTER_REF_PIC_SET_PRED)
  1293				return -EINVAL;
  1294			break;
  1295	
  1296		case V4L2_CTRL_TYPE_HEVC_EXT_SPS_LT_RPS:
  1297			p_hevc_lt_rps = p;
  1298	
  1299			if (p_hevc_lt_rps->flags & ~V4L2_HEVC_EXT_SPS_LT_RPS_FLAG_USED_LT)
  1300				return -EINVAL;
  1301			break;
  1302	
  1303		case V4L2_CTRL_TYPE_HDR10_CLL_INFO:
  1304			break;
  1305	
  1306		case V4L2_CTRL_TYPE_HDR10_MASTERING_DISPLAY:
  1307			p_hdr10_mastering = p;
  1308	
  1309			for (i = 0; i < 3; ++i) {
  1310				if (p_hdr10_mastering->display_primaries_x[i] <
  1311					V4L2_HDR10_MASTERING_PRIMARIES_X_LOW ||
  1312				    p_hdr10_mastering->display_primaries_x[i] >
  1313					V4L2_HDR10_MASTERING_PRIMARIES_X_HIGH ||
  1314				    p_hdr10_mastering->display_primaries_y[i] <
  1315					V4L2_HDR10_MASTERING_PRIMARIES_Y_LOW ||
  1316				    p_hdr10_mastering->display_primaries_y[i] >
  1317					V4L2_HDR10_MASTERING_PRIMARIES_Y_HIGH)
  1318					return -EINVAL;
  1319			}
  1320	
  1321			if (p_hdr10_mastering->white_point_x <
  1322				V4L2_HDR10_MASTERING_WHITE_POINT_X_LOW ||
  1323			    p_hdr10_mastering->white_point_x >
  1324				V4L2_HDR10_MASTERING_WHITE_POINT_X_HIGH ||
  1325			    p_hdr10_mastering->white_point_y <
  1326				V4L2_HDR10_MASTERING_WHITE_POINT_Y_LOW ||
  1327			    p_hdr10_mastering->white_point_y >
  1328				V4L2_HDR10_MASTERING_WHITE_POINT_Y_HIGH)
  1329				return -EINVAL;
  1330	
  1331			if (p_hdr10_mastering->max_display_mastering_luminance <
  1332				V4L2_HDR10_MASTERING_MAX_LUMA_LOW ||
  1333			    p_hdr10_mastering->max_display_mastering_luminance >
  1334				V4L2_HDR10_MASTERING_MAX_LUMA_HIGH ||
  1335			    p_hdr10_mastering->min_display_mastering_luminance <
  1336				V4L2_HDR10_MASTERING_MIN_LUMA_LOW ||
  1337			    p_hdr10_mastering->min_display_mastering_luminance >
  1338				V4L2_HDR10_MASTERING_MIN_LUMA_HIGH)
  1339				return -EINVAL;
  1340	
  1341			/* The following restriction comes from ITU-T Rec. H.265 spec */
  1342			if (p_hdr10_mastering->max_display_mastering_luminance ==
  1343				V4L2_HDR10_MASTERING_MAX_LUMA_LOW &&
  1344			    p_hdr10_mastering->min_display_mastering_luminance ==
  1345				V4L2_HDR10_MASTERING_MIN_LUMA_HIGH)
  1346				return -EINVAL;
  1347	
  1348			break;
  1349	
  1350		case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX:
  1351			break;
  1352	
  1353		case V4L2_CTRL_TYPE_VP9_COMPRESSED_HDR:
  1354			return validate_vp9_compressed_hdr(p);
  1355	
  1356		case V4L2_CTRL_TYPE_VP9_FRAME:
  1357			return validate_vp9_frame(p);
  1358		case V4L2_CTRL_TYPE_AV1_FRAME:
  1359			return validate_av1_frame(p);
  1360		case V4L2_CTRL_TYPE_AV1_SEQUENCE:
  1361			return validate_av1_sequence(p);
  1362		case V4L2_CTRL_TYPE_AV1_TILE_GROUP_ENTRY:
  1363			break;
  1364		case V4L2_CTRL_TYPE_AV1_FILM_GRAIN:
  1365			return validate_av1_film_grain(p);
  1366	
  1367		case V4L2_CTRL_TYPE_AREA:
  1368			area = p;
  1369			if (!area->width || !area->height)
  1370				return -EINVAL;
  1371			break;
  1372	
  1373		case V4L2_CTRL_TYPE_RECT:
  1374			rect = p;
  1375			if (!rect->width || !rect->height)
  1376				return -EINVAL;
  1377			break;
  1378	
  1379		default:
  1380			return -EINVAL;
  1381		}
  1382	
  1383		return 0;
  1384	}
  1385	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v3] media: v4l2-ctrls: validate HEVC active reference counts
  2026-03-23  8:30 [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists Pengpeng Hou
                   ` (3 preceding siblings ...)
  2026-03-24  3:13 ` Pengpeng Hou
@ 2026-03-24  3:13 ` Pengpeng Hou
  4 siblings, 0 replies; 6+ messages in thread
From: Pengpeng Hou @ 2026-03-24  3:13 UTC (permalink / raw)
  To: mchehab
  Cc: hverkuil, nicolas.dufresne, sakari.ailus, laurent.pinchart,
	opensource206, jernej.skrabec, lkp, oe-kbuild-all, llvm,
	linux-media, linux-kernel, pengpeng

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.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
v3:
- add the missing `p_hevc_slice_params` declaration to fix the build break
  reported by lkp
- keep only the active L0/L1 reference count validation in common code
- drop the ref_idx_l0/ref_idx_l1 rejection per Nicolas Dufresne's review,
  since existing userspace may use out-of-range sentinel values such as
  0xff for missing references

 drivers/media/v4l2-core/v4l2-ctrls-core.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index 6b375720e395..ba047d7d8601 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -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:
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists
  2026-03-23  8:30 [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists Pengpeng Hou
                   ` (2 preceding siblings ...)
  2026-03-23 20:36 ` kernel test robot
@ 2026-03-24  3:13 ` Pengpeng Hou
  2026-03-24  3:13 ` [PATCH v3] media: v4l2-ctrls: validate HEVC active reference counts Pengpeng Hou
  4 siblings, 0 replies; 6+ messages in thread
From: Pengpeng Hou @ 2026-03-24  3:13 UTC (permalink / raw)
  To: mchehab
  Cc: Pengpeng Hou, hverkuil, nicolas.dufresne, sakari.ailus,
	laurent.pinchart, opensource206, jernej.skrabec, lkp,
	oe-kbuild-all, llvm, linux-media, linux-kernel

Hi Nicolas,

Thanks, this makes sense.

You are right that rejecting ref_idx_l0/ref_idx_l1 values in the common
validation path would be a breaking change, since existing userspace may
pass out-of-range sentinel values such as 0xff for missing references.

I respun this by keeping only the active L0/L1 reference count checks in
common code. I also fixed the missing `p_hevc_slice_params`
declaration that caused the build failure reported by lkp.

Best regards,
Pengpeng


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-03-24  3:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-23  8:30 [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists Pengpeng Hou
2026-03-23 13:41 ` Nicolas Dufresne
2026-03-23 20:36 ` kernel test robot
2026-03-23 20:36 ` kernel test robot
2026-03-24  3:13 ` Pengpeng Hou
2026-03-24  3:13 ` [PATCH v3] media: v4l2-ctrls: validate HEVC active reference counts Pengpeng Hou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox