* [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; 10+ 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] 10+ 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-04-09 13:52 ` Paul Kocialkowski
2026-03-23 20:36 ` kernel test robot
` (3 subsequent siblings)
4 siblings, 1 reply; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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
2026-04-08 20:01 ` Nicolas Dufresne
4 siblings, 1 reply; 10+ 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] 10+ messages in thread
* Re: [PATCH v3] media: v4l2-ctrls: validate HEVC active reference counts
2026-03-24 3:13 ` [PATCH v3] media: v4l2-ctrls: validate HEVC active reference counts Pengpeng Hou
@ 2026-04-08 20:01 ` Nicolas Dufresne
0 siblings, 0 replies; 10+ messages in thread
From: Nicolas Dufresne @ 2026-04-08 20:01 UTC (permalink / raw)
To: Pengpeng Hou, mchehab
Cc: hverkuil, sakari.ailus, laurent.pinchart, opensource206,
jernej.skrabec, lkp, oe-kbuild-all, llvm, linux-media,
linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2746 bytes --]
Le mardi 24 mars 2026 à 11:13 +0800, Pengpeng Hou a écrit :
> 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>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
> ---
> 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:
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists
2026-03-23 13:41 ` Nicolas Dufresne
@ 2026-04-09 13:52 ` Paul Kocialkowski
2026-04-09 14:14 ` Nicolas Dufresne
0 siblings, 1 reply; 10+ messages in thread
From: Paul Kocialkowski @ 2026-04-09 13:52 UTC (permalink / raw)
To: Nicolas Dufresne
Cc: Pengpeng Hou, mchehab, hverkuil, sakari.ailus, laurent.pinchart,
opensource206, jernej.skrabec, linux-media, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2066 bytes --]
Hi Nicolas,
On Mon 23 Mar 26, 09:41, Nicolas Dufresne wrote:
> > +
> > + 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.
So while some decoders may be able to deal with missing references, it seems
that cedrus should still error out in that case. I don't think it will be very
happy if we configure the hardware with L0/L1 lists that don't match what was
used for the encode.
But maybe we could pick up another (existing or empty) reference to replace the
missing one, which would be better than failing to decode the frame. IMO this
would be best done by userspace, but maybe we'd need some indication to know
that the hardware cannot deal with missing references.
What do you think?
All the best,
Paul
> > +
> > + 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:
--
Paul Kocialkowski,
Independent contractor - sys-base - https://www.sys-base.io/
Free software developer - https://www.paulk.fr/
Expert in multimedia, graphics and embedded hardware support with Linux.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists
2026-04-09 13:52 ` Paul Kocialkowski
@ 2026-04-09 14:14 ` Nicolas Dufresne
2026-04-09 14:44 ` Paul Kocialkowski
0 siblings, 1 reply; 10+ messages in thread
From: Nicolas Dufresne @ 2026-04-09 14:14 UTC (permalink / raw)
To: Paul Kocialkowski
Cc: Pengpeng Hou, mchehab, hverkuil, sakari.ailus, laurent.pinchart,
opensource206, jernej.skrabec, linux-media, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 3019 bytes --]
Le jeudi 09 avril 2026 à 15:52 +0200, Paul Kocialkowski a écrit :
> Hi Nicolas,
>
> On Mon 23 Mar 26, 09:41, Nicolas Dufresne wrote:
> > > +
> > > + 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.
>
> So while some decoders may be able to deal with missing references, it seems
> that cedrus should still error out in that case. I don't think it will be very
> happy if we configure the hardware with L0/L1 lists that don't match what was
> used for the encode.
The L0/L1 list passed by application do match the decoder list, but has gaps. By
the spec, decoder should be gap resistant. You are better place them me to know
what the Cedrus hardware can and cannot do. This is rarely well document, and in
RE case like this, you probably have to do some trial and errors.
>
> But maybe we could pick up another (existing or empty) reference to replace the
> missing one, which would be better than failing to decode the frame. IMO this
> would be best done by userspace, but maybe we'd need some indication to know
> that the hardware cannot deal with missing references.
Exact, experimenting first seems key, every hardware I've worked with behaves
differently. Hantro G2 notably tends to cause system wide issues on imx8mq if
you don't carefully select your replacement. Yet, after testing and looking at
the visual result, its way better (visually) to pick a replacement. I have
patches coming that tracks which frame have decoded successfully and holds
initialized MV data (which was the reason it was going wild).
Note that going one step further, on HEVC we could use the poc to find a valid
replacement that is temporarily closer, but that would simply be an enhancement
for streams with reordering.
Nicolas
>
> What do you think?
>
> All the best,
>
> Paul
>
> > > +
> > > + 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] 10+ messages in thread
* Re: [PATCH v2] media: v4l2-ctrls: validate HEVC slice reference lists
2026-04-09 14:14 ` Nicolas Dufresne
@ 2026-04-09 14:44 ` Paul Kocialkowski
0 siblings, 0 replies; 10+ messages in thread
From: Paul Kocialkowski @ 2026-04-09 14:44 UTC (permalink / raw)
To: Nicolas Dufresne
Cc: Pengpeng Hou, mchehab, hverkuil, sakari.ailus, laurent.pinchart,
opensource206, jernej.skrabec, linux-media, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 4046 bytes --]
Hi Nicolas,
On Thu 09 Apr 26, 10:14, Nicolas Dufresne wrote:
> Le jeudi 09 avril 2026 à 15:52 +0200, Paul Kocialkowski a écrit :
> > Hi Nicolas,
> >
> > On Mon 23 Mar 26, 09:41, Nicolas Dufresne wrote:
> > > > +
> > > > + 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.
> >
> > So while some decoders may be able to deal with missing references, it seems
> > that cedrus should still error out in that case. I don't think it will be very
> > happy if we configure the hardware with L0/L1 lists that don't match what was
> > used for the encode.
>
> The L0/L1 list passed by application do match the decoder list, but has gaps. By
> the spec, decoder should be gap resistant. You are better place them me to know
> what the Cedrus hardware can and cannot do. This is rarely well document, and in
> RE case like this, you probably have to do some trial and errors.
Indeed. My concern here is more specific to cedrus: since the references are
written to a SRAM area we have to configure something for the entry or it will
just keep the value from the previous frame.
Also the current cedrus h265 code doesn't check for cases of missing references,
which will certainly blow up when trying to access the corresponding DPB index.
> > But maybe we could pick up another (existing or empty) reference to replace the
> > missing one, which would be better than failing to decode the frame. IMO this
> > would be best done by userspace, but maybe we'd need some indication to know
> > that the hardware cannot deal with missing references.
>
> Exact, experimenting first seems key, every hardware I've worked with behaves
> differently. Hantro G2 notably tends to cause system wide issues on imx8mq if
> you don't carefully select your replacement. Yet, after testing and looking at
> the visual result, its way better (visually) to pick a replacement. I have
> patches coming that tracks which frame have decoded successfully and holds
> initialized MV data (which was the reason it was going wild).
>
> Note that going one step further, on HEVC we could use the poc to find a valid
> replacement that is temporarily closer, but that would simply be an enhancement
> for streams with reordering.
Right, for both H.264 and H.265 we could have a (hopefully generic) way to find
the most recent frame to replace a missing reference, and return an error status
with a full payload size.
All the best,
Paul
> Nicolas
>
> >
> > What do you think?
> >
> > All the best,
> >
> > Paul
> >
> > > > +
> > > > + 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:
> >
> >
--
Paul Kocialkowski,
Independent contractor - sys-base - https://www.sys-base.io/
Free software developer - https://www.paulk.fr/
Expert in multimedia, graphics and embedded hardware support with Linux.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-04-09 14:44 UTC | newest]
Thread overview: 10+ 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-04-09 13:52 ` Paul Kocialkowski
2026-04-09 14:14 ` Nicolas Dufresne
2026-04-09 14:44 ` Paul Kocialkowski
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
2026-04-08 20:01 ` Nicolas Dufresne
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox