Firefox · Core
CVE-2026-92045
Logic Error in Core
Overview
Moderate
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifthird_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc |
modified | |
ifthird_party/libwebrtc/modules/portal/pipewire_utils.cc |
modified | |
ScopedBufthird_party/libwebrtc/modules/portal/pipewire_utils.h |
modified | |
ScopedBufthird_party/libwebrtc/modules/portal/pipewire_utils.h |
modified | |
ifthird_party/libwebrtc/modules/portal/pipewire_utils.h |
modified | |
ifthird_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc |
modified | |
ifthird_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_egl_dmabuf.cc |
modified | |
ifthird_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc |
modified |
Files Changed
third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.ccthird_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_egl_dmabuf.ccthird_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.ccthird_party/libwebrtc/modules/portal/pipewire_utils.ccthird_party/libwebrtc/modules/portal/pipewire_utils.hthird_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.ccthird_party/libwebrtc/moz-patch-stack/5c10f93376.no-op-cherry-pick-msgthird_party/libwebrtc/moz-patch-stack/c84dbe590a.no-op-cherry-pick-msg
Patch
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
index 2ddc03dd7bf..657eb346e8e 100644
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
@@ -1052,20 +1052,15 @@ bool SharedScreenCastStreamPrivate::ProcessMemFDBuffer(
uint8_t* src = nullptr;
const uint64_t maxsize = static_cast<uint64_t>(spa_buffer->datas[0].maxsize);
- const uint64_t mapoffset =
- static_cast<uint64_t>(spa_buffer->datas[0].mapoffset);
-
- map.initialize(
- static_cast<uint8_t*>(mmap(nullptr, maxsize + mapoffset, PROT_READ,
- MAP_PRIVATE, spa_buffer->datas[0].fd, 0)),
- maxsize + mapoffset, spa_buffer->datas[0].fd);
+ map.initialize(spa_buffer->datas[0].fd, maxsize,
+ spa_buffer->datas[0].mapoffset, ScopedBuf::BufferType::kMemFd);
if (!map) {
RTC_LOG(LS_ERROR) << "Failed to mmap the memory: " << std::strerror(errno);
return false;
}
- src = SPA_MEMBER(map.get(), mapoffset, uint8_t);
+ src = map.get();
const uint64_t src_stride = spa_buffer->datas[0].chunk->stride;
diff --git a/third_party/libwebrtc/modules/portal/pipewire_utils.cc b/third_party/libwebrtc/modules/portal/pipewire_utils.cc
index 7008696b7d2..bdea4318e7a 100644
--- a/third_party/libwebrtc/modules/portal/pipewire_utils.cc
+++ b/third_party/libwebrtc/modules/portal/pipewire_utils.cc
@@ -11,13 +11,18 @@
#include "modules/portal/pipewire_utils.h"
#include <pipewire/pipewire.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <cstddef>
+#include <cstdint>
#include <optional>
#include <string>
#include <string_view>
#include <tuple>
#include <vector>
+#include "rtc_base/checks.h"
#include "rtc_base/sanitizer.h"
#include "rtc_base/string_encode.h"
#include "rtc_base/string_to_number.h"
@@ -120,4 +125,41 @@ PipeWireInitializer::~PipeWireInitializer() {
}
}
+void ScopedBuf::initialize(int fd,
+ size_t maxsize,
+ off_t mapoffset,
+ BufferType buffer_type,
+ AccessMode mode) {
+ // PipeWire supports shared memory mappings <= 4GB in size.
+ RTC_CHECK_GE(mapoffset, 0);
+ RTC_CHECK_LE(mapoffset, UINT32_MAX);
+ RTC_CHECK_LE(maxsize, UINT32_MAX);
+
+ if (buffer_type == BufferType::kMemFd) {
+ struct stat sb;
+ if (fstat(fd, &sb) != 0 ||
+ static_cast<int64_t>(mapoffset) + static_cast<int64_t>(maxsize) >
+ static_cast<int64_t>(sb.st_size)) {
+ return;
+ }
+ }
+
+ int prot =
+ mode == AccessMode::kReadWrite ? (PROT_READ | PROT_WRITE) : PROT_READ;
+ int flags =
+ (buffer_type == BufferType::kDmaBuf || mode == AccessMode::kReadWrite)
+ ? MAP_SHARED
+ : MAP_PRIVATE;
+
+ map_ =
+ static_cast<uint8_t*>(mmap(nullptr, maxsize, prot, flags, fd, mapoffset));
+ map_size_ = maxsize;
+ fd_ = fd;
+ buffer_type_ = buffer_type;
+
+ if (buffer_type_ == BufferType::kDmaBuf && map_ != MAP_FAILED) {
+ SyncDmaBuf(fd_, DMA_BUF_SYNC_START);
+ }
+}
+
} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/portal/pipewire_utils.h b/third_party/libwebrtc/modules/portal/pipewire_utils.h
index d0734c19be0..e3769294f22 100644
--- a/third_party/libwebrtc/modules/portal/pipewire_utils.h
+++ b/third_party/libwebrtc/modules/portal/pipewire_utils.h
@@ -16,6 +16,7 @@
#include <sys/mman.h>
#include <cerrno>
+#include <cstddef>
#include <cstdint>
#include <string>
#include <string_view>
@@ -102,12 +103,17 @@ static bool SyncDmaBuf(int fd, uint64_t start_or_end) {
class ScopedBuf {
public:
+ enum class AccessMode { kReadOnly, kReadWrite };
+ enum class BufferType { kMemFd, kDmaBuf };
+
ScopedBuf() {}
- ScopedBuf(uint8_t* map, int map_size, int fd, bool is_dma_buf = false)
- : map_(map), map_size_(map_size), fd_(fd), is_dma_buf_(is_dma_buf) {}
+ ScopedBuf(const ScopedBuf&) = delete;
+ ScopedBuf& operator=(const ScopedBuf&) = delete;
+ ScopedBuf(ScopedBuf&&) = delete;
+ ScopedBuf& operator=(ScopedBuf&&) = delete;
~ScopedBuf() {
if (map_ != MAP_FAILED) {
- if (is_dma_buf_) {
+ if (buffer_type_ == BufferType::kDmaBuf) {
SyncDmaBuf(fd_, DMA_BUF_SYNC_END);
}
munmap(map_, map_size_);
@@ -116,24 +122,19 @@ class ScopedBuf {
explicit operator bool() { return map_ != MAP_FAILED; }
- void initialize(uint8_t* map, int map_size, int fd, bool is_dma_buf = false) {
- map_ = map;
- map_size_ = map_size;
- is_dma_buf_ = is_dma_buf;
- fd_ = fd;
-
- if (is_dma_buf_) {
- SyncDmaBuf(fd_, DMA_BUF_SYNC_START);
- }
- }
+ void initialize(int fd,
+ size_t maxsize,
+ off_t mapoffset,
+ BufferType buffer_type,
+ AccessMode mode = AccessMode::kReadOnly);
uint8_t* get() { return map_; }
protected:
uint8_t* map_ = static_cast<uint8_t*>(MAP_FAILED);
- int map_size_;
- int fd_;
- bool is_dma_buf_;
+ size_t map_size_ = 0;
+ int fd_ = -1;
+ BufferType buffer_type_ = BufferType::kMemFd;
};
} // namespace webrtc
diff --git a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
index 54586e26737..2b3b619c384 100644
--- a/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
+++ b/third_party/libwebrtc/modules/video_capture/linux/video_capture_pipewire.cc
@@ -24,7 +24,6 @@
#include <spa/utils/defs.h>
#include <spa/utils/result.h>
#include <spa/utils/type.h>
-#include <sys/mman.h>
#include <algorithm>
#include <cerrno>
@@ -483,12 +482,11 @@ void VideoCaptureModulePipeWire::ProcessBuffers() {
if (spaBuffer->datas[0].type == SPA_DATA_DmaBuf ||
spaBuffer->datas[0].type == SPA_DATA_MemFd) {
ScopedBuf frame;
- frame.initialize(
- static_cast<uint8_t*>(
- mmap(nullptr, spaBuffer->datas[0].maxsize, PROT_READ, MAP_SHARED,
- spaBuffer->datas[0].fd, spaBuffer->datas[0].mapoffset)),
- spaBuffer->datas[0].maxsize, spaBuffer->datas[0].fd,
- spaBuffer->datas[0].type == SPA_DATA_DmaBuf);
+ frame.initialize(spaBuffer->datas[0].fd, spaBuffer->datas[0].maxsize,
+ spaBuffer->datas[0].mapoffset,
+ spaBuffer->datas[0].type == SPA_DATA_DmaBuf
+ ? ScopedBuf::BufferType::kDmaBuf
+ : ScopedBuf::BufferType::kMemFd);
if (!frame) {
RTC_LOG(LS_ERROR) << "Failed to mmap the memory: "
diff --git a/third_party/libwebrtc/moz-patch-stack/5c10f93376.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/5c10f93376.no-op-cherry-pick-msg
new file mode 100644
index 00000000000..fb9139275fd
--- /dev/null
+++ b/third_party/libwebrtc/moz-patch-stack/5c10f93376.no-op-cherry-pick-msg
@@ -0,0 +1 @@
+We cherry-picked this in bug 2054622.
\ No newline at end of file
diff --git a/third_party/libwebrtc/moz-patch-stack/c84dbe590a.no-op-cherry-pick-msg b/third_party/libwebrtc/moz-patch-stack/c84dbe590a.no-op-cherry-pick-msg
new file mode 100644
index 00000000000..fb9139275fd
--- /dev/null
+++ b/third_party/libwebrtc/moz-patch-stack/c84dbe590a.no-op-cherry-pick-msg
@@ -0,0 +1 @@
+We cherry-picked this in bug 2054622.
\ No newline at end of file
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_egl_dmabuf.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_egl_dmabuf.cc
index 36be3fa8ee0..58f745ede5b 100644
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_egl_dmabuf.cc
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_egl_dmabuf.cc
@@ -60,10 +60,9 @@ bool TestEglDrmDevice::ImageFromDmaBuf(
const size_t plane_stride = plane.stride;
const size_t buffer_size_bytes = plane_stride * size.height();
- uint8_t* map = static_cast<uint8_t*>(
- mmap(nullptr, buffer_size_bytes, PROT_READ, MAP_SHARED, plane.fd, 0));
ScopedBuf scoped_buf;
- scoped_buf.initialize(map, buffer_size_bytes, plane.fd, true);
+ scoped_buf.initialize(plane.fd, buffer_size_bytes, 0,
+ ScopedBuf::BufferType::kDmaBuf);
if (!scoped_buf) {
RTC_LOG(LS_ERROR) << "TestEglDrmDevice: Failed to mmap DMA-BUF";
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc
index 14780310efb..183bb1cf308 100644
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc
@@ -195,10 +195,9 @@ void TestScreenCastStreamProvider::RecordFrame(RgbaColor rgba_color,
ScopedBuf scoped_buf;
if (spa_data->type == SPA_DATA_DmaBuf) {
- uint8_t* map =
- static_cast<uint8_t*>(mmap(nullptr, buffer_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, spa_data->fd, 0));
- scoped_buf.initialize(map, buffer_size, spa_data->fd, true);
+ scoped_buf.initialize(spa_data->fd, buffer_size, 0,
+ ScopedBuf::BufferType::kDmaBuf,
+ ScopedBuf::AccessMode::kReadWrite);
if (!scoped_buf) {
RTC_LOG(LS_ERROR) << "Failed to mmap DMA-BUF for recording";
pw_stream_queue_buffer(pw_stream_, buffer);
Loading diff…
Regression Test / PoC
shipped with the fix
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_egl_dmabuf.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_egl_dmabuf.cc
index 36be3fa8ee0..58f745ede5b 100644
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_egl_dmabuf.cc
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_egl_dmabuf.cc
@@ -60,10 +60,9 @@ bool TestEglDrmDevice::ImageFromDmaBuf(
const size_t plane_stride = plane.stride;
const size_t buffer_size_bytes = plane_stride * size.height();
- uint8_t* map = static_cast<uint8_t*>(
- mmap(nullptr, buffer_size_bytes, PROT_READ, MAP_SHARED, plane.fd, 0));
ScopedBuf scoped_buf;
- scoped_buf.initialize(map, buffer_size_bytes, plane.fd, true);
+ scoped_buf.initialize(plane.fd, buffer_size_bytes, 0,
+ ScopedBuf::BufferType::kDmaBuf);
if (!scoped_buf) {
RTC_LOG(LS_ERROR) << "TestEglDrmDevice: Failed to mmap DMA-BUF";
diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc
index 14780310efb..183bb1cf308 100644
--- a/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc
+++ b/third_party/libwebrtc/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc
@@ -195,10 +195,9 @@ void TestScreenCastStreamProvider::RecordFrame(RgbaColor rgba_color,
ScopedBuf scoped_buf;
if (spa_data->type == SPA_DATA_DmaBuf) {
- uint8_t* map =
- static_cast<uint8_t*>(mmap(nullptr, buffer_size, PROT_READ | PROT_WRITE,
- MAP_SHARED, spa_data->fd, 0));
- scoped_buf.initialize(map, buffer_size, spa_data->fd, true);
+ scoped_buf.initialize(spa_data->fd, buffer_size, 0,
+ ScopedBuf::BufferType::kDmaBuf,
+ ScopedBuf::AccessMode::kReadWrite);
if (!scoped_buf) {
RTC_LOG(LS_ERROR) << "Failed to mmap DMA-BUF for recording";
pw_stream_queue_buffer(pw_stream_, buffer);
Loading diff…
References
On This Page