CVE-2024-38949, CVE-2024-38950: fix SDL OOB in dec265 display path
authorDebian Multimedia Maintainers <debian-multimedia@lists.debian.org>
Sun, 30 Aug 2026 20:56:35 +0000 (22:56 +0200)
committerMoritz Mühlenhoff <jmm@debian.org>
Sun, 30 Aug 2026 20:56:35 +0000 (22:56 +0200)
Origin: upstream, https://github.com/strukturag/libde265/commit/4089de0845e0009e019be4ca5cbebaf2aee0a8ce
Bug: https://github.com/strukturag/libde265/issues/460
Bug-Debian: https://bugs.debian.org/1074416
Applied-Upstream: 1.0.19

Heap buffer overflow in the dec265 SDL output on 4:4:4 streams
(display444as420) and on mid-stream resolution changes.

Gbp-Pq: Name CVE-2024-38949_CVE-2024-38950.patch

dec265/dec265.cc
dec265/sdl.cc
dec265/sdl.hh

index ecf5d131ed86f2ec8be4832eae66ba2cc77bd2d8..708408b98d41c2d20b59801b785f62c4d69378f3 100644 (file)
@@ -270,17 +270,20 @@ bool display_sdl(const struct de265_image* img)
 
   de265_chroma chroma = de265_get_chroma_format(img);
 
+  enum SDL_YUV_Display::SDL_Chroma sdlChroma;
+  switch (chroma) {
+  case de265_chroma_420:  sdlChroma = SDL_YUV_Display::SDL_CHROMA_420;  break;
+  case de265_chroma_422:  sdlChroma = SDL_YUV_Display::SDL_CHROMA_422;  break;
+  case de265_chroma_444:  sdlChroma = SDL_YUV_Display::SDL_CHROMA_444;  break;
+  case de265_chroma_mono: sdlChroma = SDL_YUV_Display::SDL_CHROMA_MONO; break;
+  default: assert(false); sdlChroma = SDL_YUV_Display::SDL_CHROMA_MONO;
+  }
+
   if (!sdl_active) {
     sdl_active=true;
-    enum SDL_YUV_Display::SDL_Chroma sdlChroma;
-    switch (chroma) {
-    case de265_chroma_420:  sdlChroma = SDL_YUV_Display::SDL_CHROMA_420;  break;
-    case de265_chroma_422:  sdlChroma = SDL_YUV_Display::SDL_CHROMA_422;  break;
-    case de265_chroma_444:  sdlChroma = SDL_YUV_Display::SDL_CHROMA_444;  break;
-    case de265_chroma_mono: sdlChroma = SDL_YUV_Display::SDL_CHROMA_MONO; break;
-    }
-
-    sdlWin.init(width,height, sdlChroma);
+    if (!sdlWin.init(width,height, sdlChroma)) return true;
+  } else {
+    if (!sdlWin.resize(width,height, sdlChroma)) return true;
   }
 
   int stride,chroma_stride;
index eab1f8f1432f60916b3b4bebc5596dd76b57a465..4211011d50d65ff6acd4176f76da43e004da6312 100644 (file)
@@ -94,6 +94,43 @@ bool SDL_YUV_Display::init(int frame_width, int frame_height, enum SDL_Chroma ch
   return true;
 }
 
+bool SDL_YUV_Display::resize(int frame_width, int frame_height, enum SDL_Chroma chroma)
+{
+  if (!mWindowOpen) {
+    return init(frame_width, frame_height, chroma);
+  }
+
+  // SDL_PIXELFORMAT_YV12 requires even dimensions; init() rounds down to a
+  // multiple of 8, so we do the same here for consistency.
+  frame_width  &= ~7;
+  frame_height &= ~7;
+
+  if (frame_width == rect.w && frame_height == rect.h && mChroma == chroma) {
+    return true;
+  }
+
+  // All chroma formats currently map to SDL_PIXELFORMAT_YV12 (we down-convert
+  // 4:2:2 and 4:4:4 ourselves), so the texture pixel format never changes.
+  // Only the texture dimensions and the window size need updating.
+  SDL_DestroyTexture(mTexture);
+  mTexture = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_YV12,
+                               SDL_TEXTUREACCESS_STREAMING,
+                               frame_width, frame_height);
+  if (!mTexture) {
+    printf("SDL: Couldn't recreate SDL texture: %s\n", SDL_GetError());
+    mWindowOpen = false;
+    return false;
+  }
+
+  SDL_SetWindowSize(mWindow, frame_width, frame_height);
+
+  mChroma = chroma;
+  rect.w  = frame_width;
+  rect.h  = frame_height;
+
+  return true;
+}
+
 void SDL_YUV_Display::display(const unsigned char *Y,
                               const unsigned char *U,
                               const unsigned char *V,
@@ -247,7 +284,7 @@ void SDL_YUV_Display::display444as420(const unsigned char *Y,
     }
 
   uint8_t *startV = mPixels + (rect.h*mStride);
-  uint8_t *startU = startV + (rect.h*mStride/2);
+  uint8_t *startU = startV + (rect.h*mStride/4);
   for (int y=0;y<rect.h;y+=2)
     {
       unsigned char* u = startU + y/2*mStride/2;
index f94aad660533c562076755c9fae2ac568c41ebac..f976edf387160d6eea94c727a76dd5612d2a0ad0 100644 (file)
@@ -39,6 +39,7 @@ public:
   };
 
   bool init(int frame_width, int frame_height, enum SDL_Chroma chroma = SDL_CHROMA_420);
+  bool resize(int frame_width, int frame_height, enum SDL_Chroma chroma);
   void display(const unsigned char *Y, const unsigned char *U, const unsigned char *V,
                int stride, int chroma_stride);
   void close();