High firefox Memory Corruption 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionMemory safety bugs present in Firefox 136, Thunderbird 136, Firefox ESR 128.8, and Thunderbird 128.8. Some of these bugs showed evidence of memory corruption and we presume that with enough effort some of these could have been exploited to run arbitrary code.
ComponentDOM
Bug ClassMemory Corruption
Tracker1850615
Fix commita3f9af6c4974 (firefox) +158/-98
CISA KEVNot listed
CreditedSylvestre Ledru, Paul Bone and the Mozilla Fuzzing Team
Disclosed2025-04-01

Changed Functions

FunctionChangeNotes
if
dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
modified
VAAPIDisplayHolder
dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
modified

Files Changed

  • dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
  • dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
  • dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
  • dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
  • dom/media/platforms/ffmpeg/VALibWrapper.cpp
  • dom/media/platforms/ffmpeg/VALibWrapper.h
  • dom/media/platforms/ffmpeg/ffvpx/FFVPXRuntimeLinker.cpp
  • dom/media/platforms/ffmpeg/moz.build
diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
index c99b114e279..ab23ca645ff 100644
--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp
@@ -14,6 +14,7 @@
 #ifdef MOZ_WIDGET_GTK
 #  include "mozilla/gfx/gfxVars.h"
 #  include "mozilla/widget/DMABufLibWrapper.h"
+#  include "VALibWrapper.h"
 #endif
 
 #define AV_LOG_INFO 32
@@ -294,33 +295,6 @@ FFmpegLibWrapper::LinkResult FFmpegLibWrapper::Link() {
 #undef AV_FUNC
 #undef AV_FUNC_OPTION
 
-#ifdef MOZ_WIDGET_GTK
-#  define VA_FUNC_OPTION_SILENT(func)                               \
-    if (!((func) = (decltype(func))PR_FindSymbol(mVALib, #func))) { \
-      (func) = (decltype(func))nullptr;                             \
-    }
-
-  // mVALib is optional and may not be present.
-  if (mVALib) {
-    VA_FUNC_OPTION_SILENT(vaExportSurfaceHandle)
-    VA_FUNC_OPTION_SILENT(vaSyncSurface)
-    VA_FUNC_OPTION_SILENT(vaInitialize)
-    VA_FUNC_OPTION_SILENT(vaTerminate)
-  }
-#  undef VA_FUNC_OPTION_SILENT
-
-#  define VAD_FUNC_OPTION_SILENT(func)                                 \
-    if (!((func) = (decltype(func))PR_FindSymbol(mVALibDrm, #func))) { \
-      FFMPEGP_LOG("Couldn't load function " #func);                    \
-    }
-
-  // mVALibDrm is optional and may not be present.
-  if (mVALibDrm) {
-    VAD_FUNC_OPTION_SILENT(vaGetDisplayDRM)
-  }
-#  undef VAD_FUNC_OPTION_SILENT
-#endif
-
   if (avcodec_register_all) {
     avcodec_register_all();
   }
@@ -356,48 +330,10 @@ void FFmpegLibWrapper::Unlink() {
   if (mAVCodecLib) {
     PR_UnloadLibrary(mAVCodecLib);
   }
-#endif
-#ifdef MOZ_WIDGET_GTK
-  if (mVALib) {
-    PR_UnloadLibrary(mVALib);
-  }
-  if (mVALibDrm) {
-    PR_UnloadLibrary(mVALibDrm);
-  }
 #endif
   PodZero(this);
 }
 
-#ifdef MOZ_WIDGET_GTK
-void FFmpegLibWrapper::LinkVAAPILibs() {
-  if (!gfx::gfxVars::CanUseHardwareVideoDecoding() || !XRE_IsRDDProcess()) {
-    return;
-  }
-
-  PRLibSpec lspec;
-  lspec.type = PR_LibSpec_Pathname;
-  const char* libDrm = "libva-drm.so.2";
-  lspec.value.pathname = libDrm;
-  mVALibDrm = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
-  if (!mVALibDrm) {
-    FFMPEGP_LOG("VA-API support: Missing or old %s library.\n", libDrm);
-    return;
-  }
-
-  const char* lib = "libva.so.2";
-  lspec.value.pathname = lib;
-  mVALib = PR_LoadLibraryWithFlags(lspec, PR_LD_NOW | PR_LD_LOCAL);
-  // Don't use libva when it's missing vaExportSurfaceHandle.
-  if (mVALib && !PR_FindSymbol(mVALib, "vaExportSurfaceHandle")) {
-    PR_UnloadLibrary(mVALib);
-    mVALib = nullptr;
-  }
-  if (!mVALib) {
-    FFMPEGP_LOG("VA-API support: Missing or old %s library.\n", lib);
-  }
-}
-#endif
-
 #ifdef MOZ_WIDGET_GTK
 bool FFmpegLibWrapper::IsVAAPIAvailable() {
 #  define VA_FUNC_LOADED(func) ((func) != nullptr)
@@ -413,9 +349,7 @@ bool FFmpegLibWrapper::IsVAAPIAvailable() {
          VA_FUNC_LOADED(av_hwframe_ctx_alloc) && VA_FUNC_LOADED(av_dict_set) &&
          VA_FUNC_LOADED(av_dict_free) && VA_FUNC_LOADED(avcodec_get_name) &&
          VA_FUNC_LOADED(av_get_pix_fmt_string) &&
-         VA_FUNC_LOADED(vaExportSurfaceHandle) &&
-         VA_FUNC_LOADED(vaSyncSurface) && VA_FUNC_LOADED(vaInitialize) &&
-         VA_FUNC_LOADED(vaTerminate) && VA_FUNC_LOADED(vaGetDisplayDRM);
+         VALibWrapper::IsVAAPIAvailable();
 }
 #endif
 
diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
index 8571dbe143b..8fbe244f958 100644
--- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
+++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
@@ -43,7 +43,7 @@ struct MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS FFmpegLibWrapper {
                    UnknownFutureFFMpegVersion, UnknownOlderFFMpegVersion,
                    MissingFFMpegFunction, MissingLibAVFunction));
 
-  // Examine mAVCodecLib, mAVUtilLib and mVALib, and attempt to resolve
+  // Examine mAVCodecLib and mAVUtilLib, and attempt to resolve
   // all symbols.
   // Upon failure, the entire object will be reset and any attached libraries
   // will be unlinked.
@@ -53,9 +53,8 @@ struct MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS FFmpegLibWrapper {
   void Unlink();
 
 #ifdef MOZ_WIDGET_GTK
-  // Check if mVALib are available and we can use HW decode.
+  // Check if libva and libva-drm are available and we can use HW decode.
   bool IsVAAPIAvailable();
-  void LinkVAAPILibs();
 #endif
 
   // indicate the version of libavcodec linked to.
@@ -179,12 +178,6 @@ struct MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS FFmpegLibWrapper {
                                         AVBufferRef* src_ctx, int flags);
   const char* (*avcodec_get_name)(int id);
   char* (*av_get_pix_fmt_string)(char* buf, int buf_size, int pix_fmt);
-
-  int (*vaExportSurfaceHandle)(void*, unsigned int, uint32_t, uint32_t, void*);
-  int (*vaSyncSurface)(void*, unsigned int);
-  int (*vaInitialize)(void* dpy, int* major_version, int* minor_version);
-  int (*vaTerminate)(void* dpy);
-  void* (*vaGetDisplayDRM)(int fd);
 #endif
 
   // Only ever used with ffvpx
@@ -193,10 +186,6 @@ struct MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS FFmpegLibWrapper {
 
   PRLibrary* mAVCodecLib;
   PRLibrary* mAVUtilLib;
-#ifdef MOZ_WIDGET_GTK
-  PRLibrary* mVALib;
-  PRLibrary* mVALibDrm;
-#endif
 };
 
 }  // namespace mozilla
diff --git a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
index 189b063cdb8..042218af04f 100644
--- a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp
@@ -69,10 +69,6 @@ bool FFmpegRuntimeLinker::Init() {
     return sLinkStatus == LinkStatus_SUCCEEDED;
   }
 
-#ifdef MOZ_WIDGET_GTK
-  sLibAV.LinkVAAPILibs();
-#endif
-
   // While going through all possible libs, this status will be updated with a
   // more precise error if possible.
   sLinkStatus = LinkStatus_NOT_FOUND;
diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
index ad328580284..cbb4bb43167 100644
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
@@ -11,6 +11,7 @@
 #include "ImageContainer.h"
 #include "MP4Decoder.h"
 #include "MediaInfo.h"
+#include "VALibWrapper.h"
 #include "VideoUtils.h"
 #include "VPXDecoder.h"
 #include "mozilla/layers/KnowsCompositor.h"
@@ -250,15 +251,14 @@ class VAAPIDisplayHolder<LIBAV_VER>;
 template <>
 class VAAPIDisplayHolder<LIBAV_VER> {
  public:
-  VAAPIDisplayHolder(FFmpegLibWrapper* aLib, VADisplay aDisplay, int aDRMFd)
-      : mLib(aLib), mDisplay(aDisplay), mDRMFd(aDRMFd) {};
+  VAAPIDisplayHolder(VADisplay aDisplay, int aDRMFd)
+      : mDisplay(aDisplay), mDRMFd(aDRMFd) {};
   ~VAAPIDisplayHolder() {
-    mLib->vaTerminate(mDisplay);
+    VALibWrapper::sFuncs.vaTerminate(mDisplay);
     close(mDRMFd);
   }
 
  private:
-  FFmpegLibWrapper* mLib;
   VADisplay mDisplay;
   int mDRMFd;
 };
Loading diff…