[PATCH] SAO: fix illegal table access when input pixel is out of range (fixes #351)
authorDirk Farin <dirk.farin@gmail.com>
Tue, 24 Jan 2023 15:53:06 +0000 (16:53 +0100)
committerTobias Frost <tobi@debian.org>
Tue, 24 Jan 2023 21:39:16 +0000 (21:39 +0000)
Gbp-Pq: Name CVE-2022-43245-fix-asan-wildpointer-apply_sao_internal.patch

libde265/sao.cc

index 62e8c06d5957ef59e980e6350bffd0bc17deb527..7cb6014da8d23e0b3dca62d8f4aa4d6cd1c7dae9 100644 (file)
@@ -211,11 +211,21 @@ void apply_sao_internal(de265_image* img, int xCtb,int yCtb,
             continue;
           }
 
-          int bandIdx = bandTable[ in_img[xC+i+(yC+j)*in_stride]>>bandShift ];
-
           // Shifts are a strange thing. On x86, >>x actually computes >>(x%64).
           // So we have to take care of large bandShifts.
-          if (bandShift>=8) { bandIdx=0; }
+          int bandIdx;
+          if (bandShift >= 8) {
+            bandIdx = 0;
+          } else {
+            int pixel = in_img[xC+i+(yC+j)*in_stride];
+
+            // Note: the input pixel value should never exceed the valid range, but it seems that it still does,
+            // maybe when there was a decoding error and the pixels have not been filled in correctly.
+            // Thus, we have to limit the pixel range to ensure that we have no illegal table access.
+            pixel = Clip3(0,maxPixelValue, pixel);
+
+            bandIdx = bandTable[ pixel>>bandShift ];
+          }
 
           if (bandIdx>0) {
             int offset = saoinfo->saoOffsetVal[cIdx][bandIdx-1];
@@ -237,10 +247,13 @@ void apply_sao_internal(de265_image* img, int xCtb,int yCtb,
         for (int j=0;j<ctbH;j++)
           for (int i=0;i<ctbW;i++) {
 
-            int bandIdx = bandTable[ in_img[xC+i+(yC+j)*in_stride]>>bandShift ];
-
             // see above
-            if (bandShift>=8) { bandIdx=0; }
+            int bandIdx;
+            if (bandShift >= 8) {
+              bandIdx = 0;
+            } else {
+              bandIdx = bandTable[ in_img[xC+i+(yC+j)*in_stride]>>bandShift ];
+            }
 
             if (bandIdx>0) {
               int offset = saoinfo->saoOffsetVal[cIdx][bandIdx-1];