Firefox · DOM
CVE-2025-3030
Memory Corruption in DOM
Overview
High
Severity
8.1
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifdom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp |
modified | |
VAAPIDisplayHolderdom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp |
modified | |
ifdom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp |
modified | |
ifdom/media/platforms/ffmpeg/VALibWrapper.cpp |
modified | |
MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORSdom/media/platforms/ffmpeg/VALibWrapper.h |
modified |
Files Changed
dom/media/platforms/ffmpeg/FFmpegLibWrapper.cppdom/media/platforms/ffmpeg/FFmpegLibWrapper.hdom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cppdom/media/platforms/ffmpeg/FFmpegVideoDecoder.cppdom/media/platforms/ffmpeg/VALibWrapper.cppdom/media/platforms/ffmpeg/VALibWrapper.hdom/media/platforms/ffmpeg/ffvpx/FFVPXRuntimeLinker.cppdom/media/platforms/ffmpeg/moz.build
Patch
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;
};
@@ -283,17 +283,17 @@ bool FFmpegVideoDecoder<LIBAV_VER>::CreateVAAPIDeviceContext() {
AVVAAPIDeviceContext* vactx = (AVVAAPIDeviceContext*)hwctx->hwctx;
int drmFd = widget::GetDMABufDevice()->OpenDRMFd();
- mDisplay = mLib->vaGetDisplayDRM(drmFd);
+ mDisplay = VALibWrapper::sFuncs.vaGetDisplayDRM(drmFd);
if (!mDisplay) {
FFMPEG_LOG(" Can't get DRM VA-API display.");
return false;
}
- hwctx->user_opaque = new VAAPIDisplayHolder<LIBAV_VER>(mLib, mDisplay, drmFd);
+ hwctx->user_opaque = new VAAPIDisplayHolder<LIBAV_VER>(mDisplay, drmFd);
hwctx->free = VAAPIDisplayReleaseCallback;
int major, minor;
- int status = mLib->vaInitialize(mDisplay, &major, &minor);
+ int status = VALibWrapper::sFuncs.vaInitialize(mDisplay, &major, &minor);
if (status != VA_STATUS_SUCCESS) {
FFMPEG_LOG(" vaInitialize failed.");
return false;
@@ -1607,13 +1607,13 @@ MediaResult FFmpegVideoDecoder<LIBAV_VER>::CreateImage(
bool FFmpegVideoDecoder<LIBAV_VER>::GetVAAPISurfaceDescriptor(
VADRMPRIMESurfaceDescriptor* aVaDesc) {
VASurfaceID surface_id = (VASurfaceID)(uintptr_t)mFrame->data[3];
- VAStatus vas = mLib->vaExportSurfaceHandle(
+ VAStatus vas = VALibWrapper::sFuncs.vaExportSurfaceHandle(
mDisplay, surface_id, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2,
VA_EXPORT_SURFACE_READ_ONLY | VA_EXPORT_SURFACE_SEPARATE_LAYERS, aVaDesc);
if (vas != VA_STATUS_SUCCESS) {
return false;
}
- vas = mLib->vaSyncSurface(mDisplay, surface_id);
+ vas = VALibWrapper::sFuncs.vaSyncSurface(mDisplay, surface_id);
if (vas != VA_STATUS_SUCCESS) {
NS_WARNING("vaSyncSurface() failed.");
}
diff --git a/dom/media/platforms/ffmpeg/VALibWrapper.cpp b/dom/media/platforms/ffmpeg/VALibWrapper.cpp
new file mode 100644
index 00000000000..b3870f2d81a
--- /dev/null
+++ b/dom/media/platforms/ffmpeg/VALibWrapper.cpp
@@ -0,0 +1,90 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "VALibWrapper.h"
+
+#include "FFmpegLog.h"
+#include "PlatformDecoderModule.h"
+#include "prlink.h"
+#include "mozilla/gfx/gfxVars.h"
+
+namespace mozilla {
+
+VALibWrapper VALibWrapper::sFuncs;
+
+void VALibWrapper::Link() {
+#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
+}
+
+bool VALibWrapper::LinkVAAPILibs() {
+ if (!gfx::gfxVars::CanUseHardwareVideoDecoding() || !XRE_IsRDDProcess()) {
+ return false;
+ }
+
+ 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 false;
+ }
+
+ 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);
+ return false;
+ }
+
+ Link();
+ return true;
+}
+
+bool VALibWrapper::AreVAAPIFuncsAvailable() {
+#define VA_FUNC_LOADED(func) ((func) != nullptr)
+ return VA_FUNC_LOADED(vaExportSurfaceHandle) &&
+ VA_FUNC_LOADED(vaSyncSurface) && VA_FUNC_LOADED(vaInitialize) &&
+ VA_FUNC_LOADED(vaTerminate) && VA_FUNC_LOADED(vaGetDisplayDRM);
+}
+
+/* static */
+bool VALibWrapper::IsVAAPIAvailable() {
+ static bool once = sFuncs.LinkVAAPILibs();
+ (void)once;
+
+ return sFuncs.AreVAAPIFuncsAvailable();
+}
+
+} // namespace mozilla
diff --git a/dom/media/platforms/ffmpeg/VALibWrapper.h b/dom/media/platforms/ffmpeg/VALibWrapper.h
new file mode 100644
index 00000000000..20f1c9d74c4
--- /dev/null
+++ b/dom/media/platforms/ffmpeg/VALibWrapper.h
@@ -0,0 +1,54 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef DOM_MEDIA_PLATFORMS_FFMPEG_VALIBWRAPPER_H_
+#define DOM_MEDIA_PLATFORMS_FFMPEG_VALIBWRAPPER_H_
+
+#include "mozilla/Attributes.h"
+#include "mozilla/Types.h"
+
+struct PRLibrary;
+
+#ifdef MOZ_WIDGET_GTK
+namespace mozilla {
+
+class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS VALibWrapper {
+ public:
+ // The class is used only in static storage and so is zero initialized.
+ VALibWrapper() = default;
+ // The libraries are not unloaded in the destructor, because doing so would
+ // require a static constructor to register the static destructor. As the
+ // class is in static storage, the destructor would only run on shutdown
+ // anyway.
+ ~VALibWrapper() = default;
+
+ // Check if sVALib and sVALibDrm are available with necessary symbols and
+ // initialize sFuncs;
+ static bool IsVAAPIAvailable();
+ static VALibWrapper sFuncs;
+
+ private:
+ void Link();
+ bool AreVAAPIFuncsAvailable();
+ // Attempt to load libva-drm and libva and resolve necessary symbols.
+ // Upon failure, the entire object will be reset and any attached libraries
+ // will be unlinked. Do not invoke more than once.
+ bool LinkVAAPILibs();
+
+ public:
+ 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);
+
+ private:
+ PRLibrary* mVALib;
+ PRLibrary* mVALibDrm;
+};
+
+} // namespace mozilla
+#endif // MOZ_WIDGET_GTK
+
+#endif // DOM_MEDIA_PLATFORMS_FFMPEG_VALIBWRAPPER_H_
diff --git a/dom/media/platforms/ffmpeg/ffvpx/FFVPXRuntimeLinker.cpp b/dom/media/platforms/ffmpeg/ffvpx/FFVPXRuntimeLinker.cpp
index 02bd401596c..a167e641328 100644
--- a/dom/media/platforms/ffmpeg/ffvpx/FFVPXRuntimeLinker.cpp
+++ b/dom/media/platforms/ffmpeg/ffvpx/FFVPXRuntimeLinker.cpp
@@ -78,10 +78,6 @@ bool FFVPXRuntimeLinker::Init() {
sLinkStatus = LinkStatus_FAILED;
... (file diff truncated)
Loading diff…
References
On This Page