Browse code

Check for out of bounds reads in sun rasterfile decoder.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Laurent Aimar authored on 2011/09/28 06:43:53
Showing 1 changed files
... ...
@@ -46,6 +46,7 @@ static av_cold int sunrast_init(AVCodecContext *avctx) {
46 46
 static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
47 47
                                 int *data_size, AVPacket *avpkt) {
48 48
     const uint8_t *buf = avpkt->data;
49
+    const uint8_t *buf_end = avpkt->data + avpkt->size;
49 50
     SUNRASTContext * const s = avctx->priv_data;
50 51
     AVFrame *picture = data;
51 52
     AVFrame * const p = &s->picture;
... ...
@@ -53,6 +54,9 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
53 53
     uint8_t *ptr;
54 54
     const uint8_t *bufstart = buf;
55 55
 
56
+    if (avpkt->size < 32)
57
+        return AVERROR_INVALIDDATA;
58
+
56 59
     if (AV_RB32(buf) != 0x59a66a95) {
57 60
         av_log(avctx, AV_LOG_ERROR, "this is not sunras encoded data\n");
58 61
         return -1;
... ...
@@ -109,6 +113,9 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
109 109
 
110 110
     p->pict_type = AV_PICTURE_TYPE_I;
111 111
 
112
+    if (buf_end - buf < maplength)
113
+        return AVERROR_INVALIDDATA;
114
+
112 115
     if (depth != 8 && maplength) {
113 116
         av_log(avctx, AV_LOG_WARNING, "useless colormap found or file is corrupted, trying to recover\n");
114 117
 
... ...
@@ -143,8 +150,11 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
143 143
         uint8_t *end = ptr + h*stride;
144 144
 
145 145
         x = 0;
146
-        while (ptr != end) {
146
+        while (ptr != end && buf < buf_end) {
147 147
             run = 1;
148
+            if (buf_end - buf < 1)
149
+                return AVERROR_INVALIDDATA;
150
+
148 151
             if ((value = *buf++) == 0x80) {
149 152
                 run = *buf++ + 1;
150 153
                 if (run != 1)
... ...
@@ -163,6 +173,8 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
163 163
         }
164 164
     } else {
165 165
         for (y=0; y<h; y++) {
166
+            if (buf_end - buf < len)
167
+                break;
166 168
             memcpy(ptr, buf, len);
167 169
             ptr += stride;
168 170
             buf += alen;