Critical firefox Memory Corruption 🔧 Commit mapped

Overview

Critical
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impactcritical
DescriptionA double-free could have occurred in `vpx_codec_enc_init_multi` after a failed allocation when initializing the encoder for WebRTC. This could have caused memory corruption and a potentially exploitable crash.
ComponentMedia
Bug ClassMemory Corruption
Tracker1962421
Fix commit0aafd05b7bb3 (firefox) +14/-1
CISA KEVNot listed
CreditedRandell Jesup
Disclosed2025-05-27

Changed Functions

FunctionChangeNotes
if
media/libvpx/libvpx/vp8/vp8_cx_iface.c
modified

Files Changed

  • media/libvpx/libvpx/vp8/vp8_cx_iface.c
  • media/libvpx/libvpx/vpx/src/vpx_encoder.c
diff --git a/media/libvpx/libvpx/vp8/vp8_cx_iface.c b/media/libvpx/libvpx/vp8/vp8_cx_iface.c
index 668bd0816dc..e5d816cef36 100644
--- a/media/libvpx/libvpx/vp8/vp8_cx_iface.c
+++ b/media/libvpx/libvpx/vp8/vp8_cx_iface.c
@@ -732,7 +732,17 @@ static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx,
 
       set_vp8e_config(&priv->oxcf, priv->cfg, priv->vp8_cfg, mr_cfg);
       priv->cpi = vp8_create_compressor(&priv->oxcf);
-      if (!priv->cpi) res = VPX_CODEC_MEM_ERROR;
+      if (!priv->cpi) {
+#if CONFIG_MULTI_RES_ENCODING
+        // Release ownership of mr_cfg->mr_low_res_mode_info on failure. This
+        // prevents ownership confusion with the caller and avoids a double
+        // free when vpx_codec_destroy() is called on this instance.
+        priv->oxcf.mr_total_resolutions = 0;
+        priv->oxcf.mr_encoder_id = 0;
+        priv->oxcf.mr_low_res_mode_info = NULL;
+#endif
+        res = VPX_CODEC_MEM_ERROR;
+      }
     }
   }
 
diff --git a/media/libvpx/libvpx/vpx/src/vpx_encoder.c b/media/libvpx/libvpx/vpx/src/vpx_encoder.c
index 001d854abe9..3af4cea3a70 100644
--- a/media/libvpx/libvpx/vpx/src/vpx_encoder.c
+++ b/media/libvpx/libvpx/vpx/src/vpx_encoder.c
@@ -114,6 +114,9 @@ vpx_codec_err_t vpx_codec_enc_init_multi_ver(
           ctx->priv = NULL;
           ctx->init_flags = flags;
           ctx->config.enc = cfg;
+          // ctx takes ownership of mr_cfg.mr_low_res_mode_info if and only if
+          // this call succeeds. The first ctx entry in the array is
+          // responsible for freeing the memory.
           res = ctx->iface->init(ctx, &mr_cfg);
         }
 
Loading diff…