CVE-2021-40566 (published 2022-01-12T22:15Z)

A Segmentation fault casued by heap use after free vulnerability exists in Gpac through 1.0.1 via the mpgviddmx_process function in reframe_mpgvid.c when using mp4box, which causes a denial of service.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 5.5, MEDIUM (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-416
cwe_name: Use After Free
description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
extended_description: 
             
             
             
			 
             
             
         
         

Fix information:
repo_url: https://github.com/gpac/gpac
commit_details: repo_url: https://github.com/gpac/gpac
author: jeanlf
author_date: 2021-08-30 15:46:16+02:00
msg: fixed #1887
repository: repo_url: https://github.com/gpac/gpac
repo_name: gpac/gpac
description: GPAC Ultramedia OSS for Video Streaming & Next-Gen Multimedia Transcoding, Packaging & Delivery
repo_language: C
owner: gpac
file_changes: filename: dec_xvid.c
change_type: ModificationType.MODIFY
diff: @@ -181,7 +181,7 @@ static GF_Err xviddec_configure_pid(GF_Filter *filter, GF_FilterPid *pid, Bool i
 	/*decode DSI*/
 	e = gf_m4v_get_config(p->value.data.ptr, p->value.data.size, &dsi);
 	if (e) return e;
-	if (!dsi.width || !dsi.height) return GF_NON_COMPLIANT_BITSTREAM;
+	if (!dsi.width || (dsi.width%2) || !dsi.height) return GF_NON_COMPLIANT_BITSTREAM;
 
 	memset(&par, 0, sizeof(par));
 	par.width = dsi.width;

programming_language: C
filename: reframe_mpgvid.c
change_type: ModificationType.MODIFY
diff: @@ -805,12 +805,17 @@ GF_Err mpgviddmx_process(GF_Filter *filter)
 				//not enough data, accumulate until we can parse the full header
 				if (e==GF_EOS) {
 					if (vosh_start<0) vosh_start = 0;
-					if (ctx->hdr_store_alloc < ctx->hdr_store_size + pck_size - vosh_start) {
-						ctx->hdr_store_alloc = (u32) (ctx->hdr_store_size + pck_size - vosh_start);
-						ctx->hdr_store = gf_realloc(ctx->hdr_store, sizeof(char)*ctx->hdr_store_alloc);
+					if (data == ctx->hdr_store) {
+						memmove(ctx->hdr_store, start, remain);
+						ctx->hdr_store_size = remain;
+					} else {
+						if (ctx->hdr_store_alloc < ctx->hdr_store_size + pck_size - vosh_start) {
+							ctx->hdr_store_alloc = (u32) (ctx->hdr_store_size + pck_size - vosh_start);
+							ctx->hdr_store = gf_realloc(ctx->hdr_store, sizeof(char)*ctx->hdr_store_alloc);
+						}
+						memcpy(ctx->hdr_store + ctx->hdr_store_size, data + vosh_start, (size_t) (pck_size - vosh_start) );
+						ctx->hdr_store_size += pck_size - (u32) vosh_start;
 					}
-					memcpy(ctx->hdr_store + ctx->hdr_store_size, data + vosh_start, (size_t) (pck_size - vosh_start) );
-					ctx->hdr_store_size += pck_size - (u32) vosh_start;
 					gf_filter_pid_drop_packet(ctx->ipid);
 					return GF_OK;
 				} else if (e != GF_OK) {
@@ -844,12 +849,17 @@ GF_Err mpgviddmx_process(GF_Filter *filter)
 				//not enough data, accumulate until we can parse the full header
 				if (e==GF_EOS) {
 					if (vosh_start<0) vosh_start = 0;
-					if (ctx->hdr_store_alloc < ctx->hdr_store_size + pck_size - vosh_start) {
-						ctx->hdr_store_alloc = (u32) (ctx->hdr_store_size + pck_size - (u32) vosh_start);
-						ctx->hdr_store = gf_realloc(ctx->hdr_store, sizeof(char)*ctx->hdr_store_alloc);
+					if (data == ctx->hdr_store) {
+						memmove(ctx->hdr_store, start, remain);
+						ctx->hdr_store_size = remain;
+					} else {
+						if (ctx->hdr_store_alloc < ctx->hdr_store_size + pck_size - vosh_start) {
+							ctx->hdr_store_alloc = (u32) (ctx->hdr_store_size + pck_size - (u32) vosh_start);
+							ctx->hdr_store = gf_realloc(ctx->hdr_store, sizeof(char)*ctx->hdr_store_alloc);
+						}
+						memcpy(ctx->hdr_store + ctx->hdr_store_size, data + vosh_start, (size_t) (pck_size - vosh_start) );
+						ctx->hdr_store_size += pck_size - (u32) vosh_start;
 					}
-					memcpy(ctx->hdr_store + ctx->hdr_store_size, data + vosh_start, (size_t) (pck_size - vosh_start) );
-					ctx->hdr_store_size += pck_size - (u32) vosh_start;
 					gf_filter_pid_drop_packet(ctx->ipid);
 					return GF_OK;
 				} else if (e != GF_OK) {

programming_language: C