Browse code

diracdec: Check dirac_unpack_idwt_params parameters before storing them.

Fixes CVE-2011-3949

Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2012/01/26 23:41:43
Showing 1 changed files
... ...
@@ -933,6 +933,15 @@ static int dirac_unpack_idwt_params(DiracContext *s)
933 933
 {
934 934
     GetBitContext *gb = &s->gb;
935 935
     int i, level;
936
+    unsigned tmp;
937
+
938
+#define CHECKEDREAD(dst, cond, errmsg) \
939
+    tmp = svq3_get_ue_golomb(gb); \
940
+    if (cond) { \
941
+        av_log(s->avctx, AV_LOG_ERROR, errmsg); \
942
+        return -1; \
943
+    }\
944
+    dst = tmp;
936 945
 
937 946
     align_get_bits(gb);
938 947
 
... ...
@@ -941,29 +950,19 @@ static int dirac_unpack_idwt_params(DiracContext *s)
941 941
         return 0;
942 942
 
943 943
     /*[DIRAC_STD] 11.3.1 Transform parameters. transform_parameters() */
944
-    s->wavelet_idx = svq3_get_ue_golomb(gb);
945
-    if (s->wavelet_idx > 6)
946
-        return -1;
944
+    CHECKEDREAD(s->wavelet_idx, tmp > 6, "wavelet_idx is too big\n")
947 945
 
948
-    s->wavelet_depth = svq3_get_ue_golomb(gb);
949
-    if (s->wavelet_depth > MAX_DWT_LEVELS) {
950
-        av_log(s->avctx, AV_LOG_ERROR, "too many dwt decompositions\n");
951
-        return -1;
952
-    }
946
+    CHECKEDREAD(s->wavelet_depth, tmp > MAX_DWT_LEVELS || tmp < 1, "invalid number of DWT decompositions\n")
953 947
 
954 948
     if (!s->low_delay) {
955 949
         /* Codeblock paramaters (core syntax only) */
956 950
         if (get_bits1(gb)) {
957 951
             for (i = 0; i <= s->wavelet_depth; i++) {
958
-                s->codeblock[i].width  = svq3_get_ue_golomb(gb);
959
-                s->codeblock[i].height = svq3_get_ue_golomb(gb);
952
+                CHECKEDREAD(s->codeblock[i].width , tmp < 1, "codeblock width invalid\n")
953
+                CHECKEDREAD(s->codeblock[i].height, tmp < 1, "codeblock height invalid\n")
960 954
             }
961 955
 
962
-            s->codeblock_mode = svq3_get_ue_golomb(gb);
963
-            if (s->codeblock_mode > 1) {
964
-                av_log(s->avctx, AV_LOG_ERROR, "unknown codeblock mode\n");
965
-                return -1;
966
-            }
956
+            CHECKEDREAD(s->codeblock_mode, tmp > 1, "unknown codeblock mode\n")
967 957
         } else
968 958
             for (i = 0; i <= s->wavelet_depth; i++)
969 959
                 s->codeblock[i].width = s->codeblock[i].height = 1;