heap-based buffer overflow in gf_base64_encode, CVE-2022-26967, Closes: #1007224
authorReinhard Tartler <siretart@tauware.de>
Sun, 5 Mar 2023 13:02:42 +0000 (08:02 -0500)
committerReinhard Tartler <siretart@tauware.de>
Sun, 5 Mar 2023 13:03:11 +0000 (08:03 -0500)
debian/patches/CVE-2022-26967.patch [new file with mode: 0644]
debian/patches/series

diff --git a/debian/patches/CVE-2022-26967.patch b/debian/patches/CVE-2022-26967.patch
new file mode 100644 (file)
index 0000000..606b238
--- /dev/null
@@ -0,0 +1,269 @@
+commit ea1eca00fd92fa17f0e25ac25652622924a9a6a0
+Author: jeanlf <jeanlf@gpac.io>
+Date:   Thu Mar 10 15:43:11 2022 +0100
+
+    fixed #2138
+
+diff --git a/include/gpac/base_coding.h b/include/gpac/base_coding.h
+index 6dd73ab16..3a749b936 100644
+--- a/include/gpac/base_coding.h
++++ b/include/gpac/base_coding.h
+@@ -56,7 +56,7 @@ Encodes a data buffer to Base64
+ \param in_buffer_size input data buffer size
+ \param out_buffer output Base64 buffer location
+ \param out_buffer_size output Base64 buffer allocated size
+-\return size of the encoded Base64 buffer
++\return size of the encoded Base64 buffer, 0 if error
+ \note the encoded data buffer is not NULL-terminated.
+  */
+ u32 gf_base64_encode(const u8 *in_buffer, u32 in_buffer_size, u8 *out_buffer, u32 out_buffer_size);
+@@ -80,7 +80,7 @@ Encodes a data buffer to Base16
+ \param in_buffer_size input data buffer size
+ \param out_buffer output Base16 buffer location
+ \param out_buffer_size output Base16 buffer allocated size
+-\return size of the encoded Base16 buffer
++\return size of the encoded Base16 buffer, 0 if error
+ \note the encoded data buffer is not NULL-terminated.
+  */
+ u32 gf_base16_encode(u8 *in_buffer, u32 in_buffer_size, u8 *out_buffer, u32 out_buffer_size);
+diff --git a/src/filters/dasher.c b/src/filters/dasher.c
+index 3ecf25277..961e73cab 100644
+--- a/src/filters/dasher.c
++++ b/src/filters/dasher.c
+@@ -2178,8 +2178,8 @@ static GF_List *dasher_get_content_protection_desc(GF_DasherCtx *ctx, GF_DashStr
+                                               pnode->type = GF_XML_TEXT_TYPE;
+                                               gf_list_add(node->content, pnode);
+-                                              size_64 = 2*pssh_len;
+-                                              pnode->name = gf_malloc(size_64);
++                                              size_64 = 2*pssh_len + 3;
++                                              pnode->name = gf_malloc(sizeof(char) * size_64);
+                                               if (pnode->name) {
+                                                       size_64 = gf_base64_encode((const char *)pssh_data, pssh_len, (char *)pnode->name, size_64);
+                                                       pnode->name[size_64] = 0;
+diff --git a/src/filters/write_generic.c b/src/filters/write_generic.c
+index b77e30838..8191ab8ec 100644
+--- a/src/filters/write_generic.c
++++ b/src/filters/write_generic.c
+@@ -778,12 +778,13 @@ static GF_Err ttml_embed_data(GF_XMLNode *node, u8 *aux_data, u32 aux_data_size,
+               GF_SAFEALLOC(node, GF_XMLNode)
+               if (!node) return GF_OUT_OF_MEM;
+               node->type = GF_XML_TEXT_TYPE;
+-              node->name = gf_malloc(sizeof(u8) * subs_size * 2);
++              u64 size_64 = (subs_size * 2) + 3;
++              node->name = gf_malloc(sizeof(char) * size_64);
+               if (!node->name) {
+                       gf_free(node);
+                       return GF_OUT_OF_MEM;
+               }
+-              subs_size = gf_base64_encode(aux_data + subs_offset, subs_size, (u8*) node->name, subs_size * 2);
++              subs_size = gf_base64_encode(aux_data + subs_offset, subs_size, (u8*) node->name, size_64);
+               node->name[subs_size] = 0;
+               return gf_list_add(data->content, node);
+       }
+diff --git a/src/filters/write_nhml.c b/src/filters/write_nhml.c
+index 045112578..2389f373f 100644
+--- a/src/filters/write_nhml.c
++++ b/src/filters/write_nhml.c
+@@ -781,8 +781,8 @@ static void nhmldump_send_frame(GF_NHMLDumpCtx *ctx, char *data, u32 data_size,
+                                       gf_bs_write_data(ctx->bs_w, nhml, (u32) strlen(nhml));
+                               } else {
+                                       u32 d_size;
+-                                      if (ctx->b64_buffer_size<2*s_size) {
+-                                              ctx->b64_buffer_size = 2 * s_size;
++                                      if (ctx->b64_buffer_size < 2*s_size + 3) {
++                                              ctx->b64_buffer_size = 2 * s_size + 3;
+                                               ctx->b64_buffer = gf_realloc(ctx->b64_buffer, ctx->b64_buffer_size);
+                                       }
+                                       d_size = gf_base64_encode(data + offset_in_sample, s_size, ctx->b64_buffer, ctx->b64_buffer_size);
+diff --git a/src/isomedia/box_dump.c b/src/isomedia/box_dump.c
+index de181b498..8364f6c05 100644
+--- a/src/isomedia/box_dump.c
++++ b/src/isomedia/box_dump.c
+@@ -5488,8 +5488,8 @@ GF_Err colr_box_dump(GF_Box *a, FILE * trace)
+                       gf_fprintf(trace, "colour_type=\"%s\">\n", gf_4cc_to_str(ptr->colour_type));
+                       if (ptr->opaque != NULL) {
+                               gf_fprintf(trace, "<profile><![CDATA[");
+-                              size_64 = 2*ptr->opaque_size;
+-                              prof_data_64 = gf_malloc(size_64);
++                              size_64 = 2*ptr->opaque_size+3;
++                              prof_data_64 = gf_malloc(sizeof(char) * size_64);
+                               size_64 = gf_base64_encode((const char *) ptr->opaque, ptr->opaque_size, (char *)prof_data_64, size_64);
+                               prof_data_64[size_64] = 0;
+                               gf_fprintf(trace, "%s", prof_data_64);
+diff --git a/src/jsmods/core.c b/src/jsmods/core.c
+index bf70ae8ce..6f0918f5b 100644
+--- a/src/jsmods/core.c
++++ b/src/jsmods/core.c
+@@ -1877,14 +1877,15 @@ static JSValue js_sys_basecode_ex(JSContext *ctx, JSValueConst this_val, int arg
+               size_t data_size;
+               data = JS_GetArrayBuffer(ctx, &data_size, argv[0] );
+               if (!data) return GF_JS_EXCEPTION(ctx);
+-              out_ptr = gf_malloc(sizeof(u8) * (1 + data_size * 2) );
++              u32 size64 = (u32) data_size * 2 + 3;
++              out_ptr = gf_malloc(sizeof(char) * size64);
+               if (!out_ptr) {
+                       e = GF_OUT_OF_MEM;
+               } else if (is_16) {
+-                      out_size = gf_base16_encode((u8*) data, (u32) data_size, out_ptr, 1 + (u32) data_size * 2);
++                      out_size = gf_base16_encode((u8*) data, (u32) data_size, out_ptr, size64);
+                       e = out_size ? GF_OK : GF_NON_COMPLIANT_BITSTREAM;
+               } else {
+-                      out_size = gf_base64_encode((u8*) data, (u32) data_size, out_ptr, 1 + (u32) data_size * 2);
++                      out_size = gf_base64_encode((u8*) data, (u32) data_size, out_ptr, size64);
+                       e = out_size ? GF_OK : GF_NON_COMPLIANT_BITSTREAM;
+               }
+       }
+diff --git a/src/media_tools/crypt_tools.c b/src/media_tools/crypt_tools.c
+index 4737b7ce0..6d2b25ca2 100644
+--- a/src/media_tools/crypt_tools.c
++++ b/src/media_tools/crypt_tools.c
+@@ -280,7 +280,7 @@ static void cryptinfo_node_start(void *sax_cbck, const char *node_name, const ch
+                               }
+                       }
+                       else if (!stricmp(att->name, "metadata")) {
+-                              u32 l = 2 * (u32) strlen(att->value);
++                              u32 l = 2 * (u32) strlen(att->value) + 3;
+                               tkc->metadata = gf_malloc(sizeof(char) * l);
+                               l = gf_base64_encode(att->value, (u32) strlen(att->value), tkc->metadata, l);
+                               tkc->metadata[l] = 0;
+diff --git a/src/media_tools/media_export.c b/src/media_tools/media_export.c
+index f433648e0..9952383f1 100644
+--- a/src/media_tools/media_export.c
++++ b/src/media_tools/media_export.c
+@@ -834,14 +834,12 @@ GF_Err gf_media_export_webvtt_metadata(GF_MediaExporter *dumper)
+                               samp->data[samp->dataLength] = 0;
+                               gf_fprintf(vtt, "%s\n", samp->data);
+                       } else {
+-                              u32 b64_size;
++                              u32 b64_size = samp->dataLength*2 + 3;
+                               char *b64;
+-                              b64 = (char *)gf_malloc(samp->dataLength*3);
+-                              b64_size = gf_base64_encode(samp->data, samp->dataLength, b64, samp->dataLength*3);
+-                              if (b64_size != (u32)-1) {
+-                                      b64[b64_size] = 0;
+-                                      gf_fprintf(vtt, "%s\n", b64);
+-                              }
++                              b64 = (char *)gf_malloc(sizeof(char)*b64_size);
++                              b64_size = gf_base64_encode(samp->data, samp->dataLength, b64, b64_size);
++                              b64[b64_size] = 0;
++                              gf_fprintf(vtt, "%s\n", b64);
+                               gf_free(b64);
+                       }
+               }
+diff --git a/src/scene_manager/loader_svg.c b/src/scene_manager/loader_svg.c
+index 314dbb41f..7c1f86f3f 100644
+--- a/src/scene_manager/loader_svg.c
++++ b/src/scene_manager/loader_svg.c
+@@ -2,7 +2,7 @@
+  *                    GPAC - Multimedia Framework C SDK
+  *
+  *                    Authors: Jean Le Feuvre, Cyril Concolato
+- *                    Copyright (c) Telecom ParisTech 2000-2012
++ *                    Copyright (c) Telecom ParisTech 2000-2022
+  *                                    All rights reserved
+  *
+  *  This file is part of GPAC / Scene Management sub-project
+@@ -259,10 +259,10 @@ static void svg_process_media_href(GF_SVG_Parser *parser, GF_Node *elt, XMLRI *i
+               } else {
+                       char *mtype;
+                       char *buf64;
+-                      u64 size64;
++                      u32 size64 = size*2 + 3;
+                       char *ext;
+-                      buf64 = (char *)gf_malloc((size_t)size*2);
+-                      size64 = gf_base64_encode(buffer, (u32)size, buf64, (u32)size*2);
++                      buf64 = (char *)gf_malloc(sizeof(char) * size64);
++                      size64 = gf_base64_encode(buffer, (u32)size, buf64, size64);
+                       buf64[size64] = 0;
+                       mtype = "application/data";
+                       ext = strchr(iri->string, '.');
+diff --git a/src/scene_manager/scene_dump.c b/src/scene_manager/scene_dump.c
+index 577cb7909..3104d23c3 100644
+--- a/src/scene_manager/scene_dump.c
++++ b/src/scene_manager/scene_dump.c
+@@ -2,7 +2,7 @@
+  *                    GPAC - Multimedia Framework C SDK
+  *
+  *                    Authors: Jean Le Feuvre
+- *                    Copyright (c) Telecom ParisTech 2000-2012
++ *                    Copyright (c) Telecom ParisTech 2000-2022
+  *                                    All rights reserved
+  *
+  *  This file is part of GPAC / Scene Management sub-project
+@@ -650,8 +650,8 @@ static void gf_dump_vrml_sffield(GF_SceneDumper *sdump, u32 type, void *ptr, Boo
+               str = ((SFString *)ptr)->buffer;
+               if (node && (gf_node_get_tag(node)==TAG_MPEG4_BitWrapper)) {
+-                      u32 bufsize = 50+ ((M_BitWrapper*)node)->buffer_len * 2;
+-                      str = gf_malloc(sizeof(char)* bufsize);
++                      u32 bufsize = 37 + ((M_BitWrapper*)node)->buffer_len * 2 + 3;
++                      str = gf_malloc(sizeof(char) * bufsize);
+                       if (str) {
+                               s32 res;
+                               strcpy(str, "data:application/octet-string;base64,");
+diff --git a/src/scene_manager/scene_engine.c b/src/scene_manager/scene_engine.c
+index 14424bb26..f0400e656 100644
+--- a/src/scene_manager/scene_engine.c
++++ b/src/scene_manager/scene_engine.c
+@@ -1105,8 +1105,9 @@ char *gf_seng_get_base64_iod(GF_SceneEngine *seng)
+       size = 0;
+       gf_odf_desc_write((GF_Descriptor *) seng->ctx->root_od, &buffer, &size);
+-      buf64 = gf_malloc(size*2);
+-      size64 = gf_base64_encode( buffer, size, buf64, size*2);
++      size64 = size*2 + 3;
++      buf64 = gf_malloc(sizeof(char) * size64);
++      size64 = gf_base64_encode( buffer, size, buf64, size64);
+       buf64[size64] = 0;
+       gf_free(buffer);
+       return buf64;
+diff --git a/src/utils/base_encoding.c b/src/utils/base_encoding.c
+index 822ff98f5..c15808bc7 100644
+--- a/src/utils/base_encoding.c
++++ b/src/utils/base_encoding.c
+@@ -42,6 +42,8 @@ u32 gf_base64_encode(const u8 *_in, u32 inSize, u8 *_out, u32 outSize)
+       while (i < inSize) {
+               padding = 3 - (inSize - i);
++              if (j+4>=outSize)
++                      return 0;
+               if (padding == 2) {
+                       out[j] = base_64[in[i]>>2];
+                       out[j+1] = base_64[(in[i] & 0x03) << 4];
+@@ -147,14 +149,12 @@ u32 gf_base16_encode(u8 *_in, u32 inSize, u8 *_out, u32 outSize)
+       unsigned char *in = (unsigned char *)_in;
+       unsigned char *out = (unsigned char *)_out;
+-      if (outSize < (inSize * 2)+1) return 0;
++      if (outSize < (inSize * 2)) return 0;
+       for (i=0; i<inSize; i++) {
+               out[2*i] = base_16[((in[i] & 0xf0) >> 4)];
+               out[2*i+1] = base_16[(in[i] & 0x0f)];
+       }
+-      out[(inSize * 2)] = 0;
+-
+       return inSize * 2;
+ }
+diff --git a/src/utils/xml_parser.c b/src/utils/xml_parser.c
+index bcecc4de8..483c00ce3 100644
+--- a/src/utils/xml_parser.c
++++ b/src/utils/xml_parser.c
+@@ -2333,12 +2333,13 @@ GF_Err gf_xml_parse_bit_sequence_bs(GF_XMLNode *bsroot, const char *parent_url,
+                       bs = bs_orig;
+                       if (bs_data) {
+                               u8 *bs_data_out;
+-                              bs_data_out = gf_malloc(sizeof(char)*2*bs_data_size);
++                              u32 res = 2*bs_data_size + 3;
++                              bs_data_out = gf_malloc(sizeof(char) * res);
+                               if (!bs_data_out) {
+                                       e = GF_OUT_OF_MEM;
+                                       goto exit;
+                               }
+-                              u32 res = gf_base64_encode(bs_data, bs_data_size, bs_data_out, 2*bs_data_size);
++                              res = gf_base64_encode(bs_data, bs_data_size, bs_data_out, res);
+                               bs_data_out[res] = 0;
+                               if (base64_prefix_bits) {
+                                       if (base64_prefix_bits % 8) {
index 23d97ef6cc76919e4161148b8d65d212e11cedd4..077a81047bf348db932e87e76cb379702cf281e7 100644 (file)
@@ -12,3 +12,4 @@ CVE-2022-2453.patch
 CVE-2022-2454.patch
 CVE-2022-38530.patch
 CVE-2022-36186.patch
+CVE-2022-26967.patch