libs: context: use attribs index instead pointers

Coverity scan bug:

Out-of-bounds write. This could cause an immediate crash or incorrect
computations.

Coverity basically found that it is possible to assign more than 4
attribs in the array.

In my opinion this was produced because code pattern used pointer
arithmetic, which is not readable nor maintainable.

This patch refactors config_create() to use an array index rather than
pointer arithmetic. Also a run-time check for index size was added.
This commit is contained in:
Víctor Manuel Jáquez Leal 2017-08-08 18:52:37 +02:00
parent 9578fd1f7b
commit e42ec3ad3c

View file

@ -229,9 +229,9 @@ config_create (GstVaapiContext * context)
{ {
const GstVaapiContextInfo *const cip = &context->info; const GstVaapiContextInfo *const cip = &context->info;
GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context); GstVaapiDisplay *const display = GST_VAAPI_OBJECT_DISPLAY (context);
VAConfigAttrib attribs[4], *attrib = attribs; VAConfigAttrib attribs[6], *attrib;
VAStatus status; VAStatus status;
guint value, va_chroma_format; guint value, va_chroma_format, attrib_index;
/* Reset profile and entrypoint */ /* Reset profile and entrypoint */
if (!cip->profile || !cip->entrypoint) if (!cip->profile || !cip->entrypoint)
@ -240,6 +240,10 @@ config_create (GstVaapiContext * context)
context->va_entrypoint = context->va_entrypoint =
gst_vaapi_entrypoint_get_va_entrypoint (cip->entrypoint); gst_vaapi_entrypoint_get_va_entrypoint (cip->entrypoint);
attrib_index = 0;
attrib = &attribs[attrib_index++];
g_assert (attrib_index < G_N_ELEMENTS (attribs));
/* Validate VA surface format */ /* Validate VA surface format */
va_chroma_format = from_GstVaapiChromaType (cip->chroma_type); va_chroma_format = from_GstVaapiChromaType (cip->chroma_type);
if (!va_chroma_format) if (!va_chroma_format)
@ -253,7 +257,8 @@ config_create (GstVaapiContext * context)
goto cleanup; goto cleanup;
} }
attrib->value = va_chroma_format; attrib->value = va_chroma_format;
attrib++; attrib = &attribs[attrib_index++];
g_assert (attrib_index < G_N_ELEMENTS (attribs));
switch (cip->usage) { switch (cip->usage) {
#if USE_ENCODERS #if USE_ENCODERS
@ -275,7 +280,8 @@ config_create (GstVaapiContext * context)
goto cleanup; goto cleanup;
} }
attrib->value = va_rate_control; attrib->value = va_rate_control;
attrib++; attrib = &attribs[attrib_index++];
g_assert (attrib_index < G_N_ELEMENTS (attribs));
} }
/* Packed headers */ /* Packed headers */
if (config->packed_headers) { if (config->packed_headers) {
@ -289,7 +295,8 @@ config_create (GstVaapiContext * context)
goto cleanup; goto cleanup;
} }
attrib->value = config->packed_headers; attrib->value = config->packed_headers;
attrib++; attrib = &attribs[attrib_index++];
g_assert (attrib_index < G_N_ELEMENTS (attribs));
} }
#if VA_CHECK_VERSION(0,37,0) #if VA_CHECK_VERSION(0,37,0)
if (cip->profile == GST_VAAPI_PROFILE_JPEG_BASELINE) { if (cip->profile == GST_VAAPI_PROFILE_JPEG_BASELINE) {
@ -297,18 +304,18 @@ config_create (GstVaapiContext * context)
if (!context_get_attribute (context, attrib->type, &value)) if (!context_get_attribute (context, attrib->type, &value))
goto cleanup; goto cleanup;
attrib->value = value; attrib->value = value;
attrib++; attrib = &attribs[attrib_index++];
g_assert (attrib_index < G_N_ELEMENTS (attribs));
} }
#endif #endif
#if VA_CHECK_VERSION(0,39,1) #if VA_CHECK_VERSION(0,39,1)
if (config->roi_capability) { if (config->roi_capability) {
VAConfigAttribValEncROI *roi_config; VAConfigAttribValEncROI *roi_config;
attrib->type = VAConfigAttribEncROI; attrib->type = VAConfigAttribEncROI;
if (!context_get_attribute (context, attrib->type, &value)) if (!context_get_attribute (context, attrib->type, &value))
goto cleanup; goto cleanup;
roi_config = (VAConfigAttribValEncROI *) & value; roi_config = (VAConfigAttribValEncROI *) & value;
if (roi_config->bits.num_roi_regions != config->roi_num_supported || if (roi_config->bits.num_roi_regions != config->roi_num_supported ||
roi_config->bits.roi_rc_qp_delat_support == 0) { roi_config->bits.roi_rc_qp_delat_support == 0) {
GST_ERROR ("ROI unsupported - number of regions supported: %d" GST_ERROR ("ROI unsupported - number of regions supported: %d"
@ -317,7 +324,8 @@ config_create (GstVaapiContext * context)
goto cleanup; goto cleanup;
} }
attrib->value = value; attrib->value = value;
attrib++; attrib = &attribs[attrib_index++];
g_assert (attrib_index < G_N_ELEMENTS (attribs));
} }
#endif #endif
break; break;
@ -329,7 +337,7 @@ config_create (GstVaapiContext * context)
GST_VAAPI_DISPLAY_LOCK (display); GST_VAAPI_DISPLAY_LOCK (display);
status = vaCreateConfig (GST_VAAPI_DISPLAY_VADISPLAY (display), status = vaCreateConfig (GST_VAAPI_DISPLAY_VADISPLAY (display),
context->va_profile, context->va_entrypoint, attribs, attrib - attribs, context->va_profile, context->va_entrypoint, attribs, attrib_index,
&context->va_config); &context->va_config);
GST_VAAPI_DISPLAY_UNLOCK (display); GST_VAAPI_DISPLAY_UNLOCK (display);
if (!vaapi_check_status (status, "vaCreateConfig()")) if (!vaapi_check_status (status, "vaCreateConfig()"))