Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  s0143.patch   Sprache: unbekannt

 
Spracherkennung für: .patch vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

From: Jan Grulich <jgrulich@redhat.com>
Date: Mon, 11 May 2026 13:14:00 +0000
Subject: Bug 2029760 - WebRTC backport: Wayland capture: validate buffer
 geometry before pixel copy r=pehrsons

Reject Memfd buffers where stride exceeds the mapped region to prevent
out-of-bounds reads. Cap stream dimensions to prevent integer overflow
in frame allocation. Bound cursor bitmap stride to reject oversized
values.

This is a simple backport of an WebRTC upstream change.

Upstream commit: 125a9d22b0edd885012a492fcb2fb2d795e5a106

Differential Revision: https://phabricator.services.mozilla.com/D299701
Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/eeff6f8f9ba06980cff396edd90c3d6e52b83cdd
---
 .../linux/wayland/shared_screencast_stream.cc | 44 ++++++++++++++-----
 .../shared_screencast_stream_unittest.cc      | 11 +++++
 .../test/test_screencast_stream_provider.cc   |  2 +
 .../test/test_screencast_stream_provider.h    |  8 +++-
 4 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
index e09a2d8b3e..90985c5ae2 100644
--- a/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
+++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream.cc
@@ -72,6 +72,9 @@ namespace webrtc {
 constexpr int kBytesPerPixel = 4;
 constexpr int kMaxCursorSize = 1024;
 constexpr int kVideoDamageRegionCount = 16;
+// A reasonable maximum size so "width * height * kBytesPerPixel" doesn't
+// overflow
+constexpr int kMaxScreenCastDimension = 16384;
 
 constexpr int CursorMetaSize(int w, int h) {
   return (sizeof(struct spa_meta_cursor) + sizeof(struct spa_meta_bitmap) +
@@ -338,6 +341,12 @@ void SharedScreenCastStreamPrivate::OnStreamParamChanged(
       has_modifier ? that->spa_video_format_.modifier : DRM_FORMAT_MOD_INVALID;
   that->stream_size_ = DesktopSize(that->spa_video_format_.size.width,
                                    that->spa_video_format_.size.height);
+  if (that->stream_size_.is_empty() ||
+      that->stream_size_.width() > kMaxScreenCastDimension ||
+      that->stream_size_.height() > kMaxScreenCastDimension) {
+    that->stream_size_ = DesktopSize();
+    return;
+  }
 
   if (that->observer_) {
     that->observer_->OnFormatChanged(
@@ -787,7 +796,11 @@ void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) {
 
         if (bitmap && bitmap->size.width > 0 &&
             bitmap->size.width <= kMaxCursorSize && bitmap->size.height > 0 &&
-            bitmap->size.height <= kMaxCursorSize) {
+            bitmap->size.height <= kMaxCursorSize &&
+            bitmap->stride >=
+                static_cast<int32_t>(bitmap->size.width * kBytesPerPixel) &&
+            bitmap->stride * bitmap->size.height <=
+                kMaxCursorSize * kMaxCursorSize * kBytesPerPixel) {
           const uint8_t* bitmap_data =
               SPA_MEMBER(bitmap, bitmap->offset, uint8_t);
           // TODO(bugs.webrtc.org/436974448): Convert `spa_video_format` to
@@ -1012,29 +1025,38 @@ bool SharedScreenCastStreamPrivate::ProcessMemFDBuffer(
   ScopedBuf map;
   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,
-               spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset,
-               PROT_READ, MAP_PRIVATE, spa_buffer->datas[0].fd, 0)),
-      spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset,
-      spa_buffer->datas[0].fd);
+      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);
 
   if (!map) {
     RTC_LOG(LS_ERROR) << "Failed to mmap the memory: " << std::strerror(errno);
     return false;
   }
 
-  src = SPA_MEMBER(map.get(), spa_buffer->datas[0].mapoffset, uint8_t);
+  src = SPA_MEMBER(map.get(), mapoffset, uint8_t);
 
-  uint32_t buffer_stride = spa_buffer->datas[0].chunk->stride;
-  uint32_t src_stride = buffer_stride;
+  const uint64_t src_stride = spa_buffer->datas[0].chunk->stride;
+
+  if (src_stride > INT32_MAX ||
+      src_stride < static_cast<uint64_t>(offset.x() + frame.size().width()) *
+                       kBytesPerPixel ||
+      src_stride * (offset.y() + frame.size().height()) > maxsize) {
+    RTC_LOG(LS_ERROR) << "Rejecting MemFd buffer with invalid geometry: stride="
+                      << src_stride << " maxsize=" << maxsize;
+    return false;
+  }
 
   uint8_t* updated_src =
       src + (src_stride * offset.y()) + (kBytesPerPixel * offset.x());
 
   frame.CopyPixelsFrom(
-      updated_src, (src_stride - (kBytesPerPixel * offset.x())),
+      updated_src, static_cast<int>(src_stride),
       DesktopRect::MakeWH(frame.size().width(), frame.size().height()));
 
   return true;
diff --git a/modules/desktop_capture/linux/wayland/shared_screencast_stream_unittest.cc b/modules/desktop_capture/linux/wayland/shared_screencast_stream_unittest.cc
index d51305be43..45f4aa3ee5 100644
--- a/modules/desktop_capture/linux/wayland/shared_screencast_stream_unittest.cc
+++ b/modules/desktop_capture/linux/wayland/shared_screencast_stream_unittest.cc
@@ -395,6 +395,17 @@ TEST_F(MAYBE_PipeWireStreamTest, TestModifierFallback) {
       blue_color, TestScreenCastStreamProvider::EmptyData);
   emptyFrameEvent.Wait(kShortWait);
 
+  // Check that a MemFd buffer with an invalid stride is rejected
+  Event invalidStrideEvent;
+  EXPECT_CALL(*this, OnFrameRecorded);
+  EXPECT_CALL(*this, OnFailedToProcessBuffer).WillOnce([&invalidStrideEvent] {
+    invalidStrideEvent.Set();
+  });
+
+  test_screencast_stream_provider_->RecordFrame(
+      blue_color, TestScreenCastStreamProvider::InvalidStride);
+  invalidStrideEvent.Wait(kShortWait);
+
   // Test disconnection from stream
   EXPECT_CALL(*this, OnStopStreaming);
   shared_screencast_stream_->StopScreenCastStream();
diff --git a/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc b/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc
index e1eaa369b8..14780310ef 100644
--- a/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc
+++ b/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.cc
@@ -235,6 +235,8 @@ void TestScreenCastStreamProvider::RecordFrame(RgbaColor rgba_color,
     spa_data->chunk->size = 0;
   } else if (frame_defect == CorruptedData) {
     spa_data->chunk->flags = SPA_CHUNK_FLAG_CORRUPTED;
+  } else if (frame_defect == InvalidStride) {
+    spa_data->chunk->stride = spa_data->maxsize + 1;
   } else if (frame_defect == CorruptedMetadata) {
     struct spa_meta_header* spa_header =
         static_cast<spa_meta_header*>(spa_buffer_find_meta_data(
diff --git a/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.h b/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.h
index 2262d49200..82feb90e61 100644
--- a/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.h
+++ b/modules/desktop_capture/linux/wayland/test/test_screencast_stream_provider.h
@@ -41,7 +41,13 @@ class TestScreenCastStreamProvider {
     virtual ~Observer() = default;
   };
 
-  enum FrameDefect { None, EmptyData, CorruptedData, CorruptedMetadata };
+  enum FrameDefect {
+    None,
+    EmptyData,
+    CorruptedData,
+    CorruptedMetadata,
+    InvalidStride
+  };
 
   explicit TestScreenCastStreamProvider(Observer* observer,
                                         uint32_t width,

[Dauer der Verarbeitung: 0.47 Sekunden]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002