Browse code

fix potential inifinite loop in UPX code

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@668 77e5149b-7576-45b1-b177-96237e5ba77b

Tomasz Kojm authored on 2004/07/14 01:42:33
Showing 3 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue Jul 13 18:37:23 CEST 2004 (tk)
2
+----------------------------------
3
+  * libclamav: upx: fix potential infinite loop (aCaB)
4
+
1 5
 Tue Jul 13 05:24:07 CEST 2004 (tk)
2 6
 ----------------------------------
3 7
   * libclamav: initial support for MD5 signatures
... ...
@@ -376,7 +376,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
376 376
 	strncpy(sname, section_hdr[i].Name, 8);
377 377
 	sname[8] = 0;
378 378
 	cli_dbgmsg("------------------------------------\n");
379
-	cli_dbgmsg("Section %d of %d\n", i, nsections);
379
+	cli_dbgmsg("Section %d\n", i);
380 380
 	cli_dbgmsg("Section name: %s\n", sname);
381 381
 	cli_dbgmsg("VirtualSize: %d\n", EC32(section_hdr[i].VirtualSize));
382 382
 	cli_dbgmsg("VirtualAddress: 0x%x\n", EC32(section_hdr[i].VirtualAddress));
... ...
@@ -490,7 +490,7 @@ int cli_scanpe(int desc, const char **virname, long int *scanned, const struct c
490 490
 
491 491
 	lseek(desc, EC32(section_hdr[i + 1].PointerToRawData), SEEK_SET);
492 492
 	if(read(desc, src, ssize) != ssize) {
493
-	    cli_dbgmsg("Can't read raw data of section %d\n", i + 1);
493
+	    cli_dbgmsg("Can't read raw data of section %d\n", i);
494 494
 	    free(section_hdr);
495 495
 	    free(src);
496 496
 	    free(dest);
... ...
@@ -62,7 +62,7 @@ static int doubleebx(char *src, int32_t *myebx, int *scur, int ssize)
62 62
   *myebx*=2;
63 63
   if ( !(oldebx & 0x7fffffff)) {
64 64
     if (*scur<0 || ssize-*scur<4)
65
-      return 0;
65
+      return -1;
66 66
 #if WORDS_BIGENDIAN == 0
67 67
     oldebx = *(int*)(src+*scur);
68 68
 #else
... ...
@@ -85,21 +85,28 @@ static int doubleebx(char *src, int32_t *myebx, int *scur, int ssize)
85 85
 int upx_inflate2b(char *src, int ssize, char *dst, int dsize)
86 86
 {
87 87
   int32_t backbytes, unp_offset = -1, myebx = 0;
88
-  int scur=0, dcur=0, i, backsize;
88
+  int scur=0, dcur=0, i, backsize,oob;
89 89
 
90 90
   while (1) {
91
-    while (doubleebx(src, &myebx, &scur, ssize)) {
91
+    while ((oob = doubleebx(src, &myebx, &scur, ssize)) == 1) {
92 92
       if (scur<0 || scur>=ssize || dcur<0 || dcur>=dsize)
93 93
 	return -1;
94 94
       dst[dcur++] = src[scur++];
95 95
     }
96 96
 
97
+    if ( oob == -1 )
98
+      return -1;
99
+    
97 100
     backbytes = 1;
98 101
 
99 102
     while (1) {
100
-      backbytes = backbytes*2+doubleebx(src, &myebx, &scur, ssize);
101
-      if (doubleebx(src, &myebx, &scur, ssize))
102
-	break;
103
+      if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1 )
104
+        return -1;
105
+      backbytes = backbytes*2+oob;
106
+      if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1 )
107
+	return -1;
108
+      if (oob)
109
+        break;
103 110
     }
104 111
 
105 112
     backsize = 0;	
... ...
@@ -118,13 +125,21 @@ int upx_inflate2b(char *src, int ssize, char *dst, int dsize)
118 118
       unp_offset = backbytes;
119 119
     }
120 120
 
121
-    backsize = doubleebx(src, &myebx, &scur, ssize);
122
-    backsize = backsize*2 + doubleebx(src, &myebx, &scur, ssize);
121
+    if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1)
122
+      return -1;
123
+    backsize = oob;
124
+    if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1)
125
+      return -1;
126
+    backsize = backsize*2 + oob;
123 127
     if (!backsize) {
124 128
       backsize++;
125 129
       do {
126
-	backsize = backsize*2 + doubleebx(src, &myebx, &scur, ssize);
127
-      } while (!doubleebx(src, &myebx, &scur, ssize));
130
+        if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1)
131
+          return -1;
132
+	backsize = backsize*2 + oob;
133
+      } while ((oob = doubleebx(src, &myebx, &scur, ssize)) == 0);
134
+      if ( oob == -1 )
135
+        return -1;
128 136
       backsize+=2;
129 137
     }
130 138
 
... ...
@@ -146,26 +161,35 @@ int upx_inflate2b(char *src, int ssize, char *dst, int dsize)
146 146
 int upx_inflate2d(char *src, int ssize, char *dst, int dsize)
147 147
 {
148 148
   int32_t backbytes, unp_offset = -1, myebx = 0;
149
-  int scur=0, dcur=0, i, backsize;
149
+  int scur=0, dcur=0, i, backsize, oob;
150 150
 
151 151
   while (1) {
152
-    while (doubleebx(src, &myebx, &scur, ssize)) {
152
+    while ( (oob = doubleebx(src, &myebx, &scur, ssize)) == 1) {
153 153
       if (scur<0 || scur>=ssize || dcur<0 || dcur>=dsize)
154 154
 	return -1;
155 155
       dst[dcur++] = src[scur++];
156 156
     }
157 157
 
158
+    if ( oob == -1 )
159
+      return -1;
160
+
158 161
     backbytes = 1;
159 162
 
160 163
     while (1) {
161
-      backbytes = backbytes*2+doubleebx(src, &myebx, &scur, ssize);
162
-      if (doubleebx(src, &myebx, &scur, ssize))
164
+      if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1 )
165
+        return -1;
166
+      backbytes = backbytes*2+oob;
167
+      if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1 )
168
+        return -1;
169
+      if (oob)
163 170
 	break;
164 171
       backbytes--;
165
-      backbytes=backbytes*2+doubleebx(src, &myebx, &scur, ssize);
172
+      if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1 )
173
+        return -1;
174
+      backbytes=backbytes*2+oob;
166 175
     }
167 176
 
168
-    backsize = 0;	
177
+    backsize = 0;
169 178
     backbytes-=3;
170 179
   
171 180
     if ( backbytes >= 0 ) {
... ...
@@ -182,15 +206,23 @@ int upx_inflate2d(char *src, int ssize, char *dst, int dsize)
182 182
       backbytes>>=1;
183 183
       unp_offset = backbytes;
184 184
     }
185
-    else
186
-      backsize = doubleebx(src, &myebx, &scur, ssize);
185
+    else {
186
+      if ( (backsize = doubleebx(src, &myebx, &scur, ssize)) == -1 )
187
+        return -1;
188
+    }
187 189
  
188
-    backsize = backsize*2 + doubleebx(src, &myebx, &scur, ssize);
190
+    if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1 )
191
+      return -1;
192
+    backsize = backsize*2 + oob;
189 193
     if (!backsize) {
190 194
       backsize++;
191 195
       do {
192
-	backsize = backsize*2 + doubleebx(src, &myebx, &scur, ssize);
193
-      } while (!doubleebx(src, &myebx, &scur, ssize));
196
+        if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1 )
197
+          return -1;
198
+	backsize = backsize*2 + oob;
199
+      } while ( (oob = doubleebx(src, &myebx, &scur, ssize)) == 0);
200
+      if ( oob == -1 )
201
+        return -1;
194 202
       backsize+=2;
195 203
     }
196 204
 
... ...
@@ -211,10 +243,12 @@ int upx_inflate2d(char *src, int ssize, char *dst, int dsize)
211 211
 int upx_inflate2e(char *src, int ssize, char *dst, int dsize)
212 212
 {
213 213
   int32_t backbytes, unp_offset = -1, myebx = 0;
214
-  int scur=0, dcur=0, i, backsize;
214
+  int scur=0, dcur=0, i, backsize, oob;
215 215
 
216 216
   while (1) {
217
-    while (doubleebx(src, &myebx, &scur, ssize)) {
217
+    while ( (oob = doubleebx(src, &myebx, &scur, ssize)) ) {
218
+      if (oob == -1)
219
+        return -1;
218 220
       if (scur<0 || scur>=ssize || dcur<0 || dcur>=dsize)
219 221
 	return -1;
220 222
       dst[dcur++] = src[scur++];
... ...
@@ -223,11 +257,17 @@ int upx_inflate2e(char *src, int ssize, char *dst, int dsize)
223 223
     backbytes = 1;
224 224
 
225 225
     while (1) {
226
-      backbytes = backbytes*2+doubleebx(src, &myebx, &scur, ssize);
227
-      if (doubleebx(src, &myebx, &scur, ssize))
226
+      if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1 )
227
+        return -1;
228
+      backbytes = backbytes*2+oob;
229
+      if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1 )
230
+        return -1;
231
+      if ( oob )
228 232
 	break;
229 233
       backbytes--;
230
-      backbytes=backbytes*2+doubleebx(src, &myebx, &scur, ssize);
234
+      if ( (oob = doubleebx(src, &myebx, &scur, ssize)) == -1 )
235
+        return -1;
236
+      backbytes=backbytes*2+oob;
231 237
     }
232 238
 
233 239
     backsize = 0;
... ...
@@ -247,20 +287,32 @@ int upx_inflate2e(char *src, int ssize, char *dst, int dsize)
247 247
       backbytes>>=1;
248 248
       unp_offset = backbytes;
249 249
     }
250
-    else
251
-      backsize = doubleebx(src, &myebx, &scur, ssize); /* Using backsize to carry on the doubleebx result (UPX uses CF) */
250
+    else {
251
+      if ( (backsize = doubleebx(src, &myebx, &scur, ssize)) == -1 )
252
+        return -1;
253
+    } /* Using backsize to carry on the doubleebx result (UPX uses CF) */
252 254
 
253 255
     if (backsize) { /* i.e. IF ( last sar shifted out 1 bit || last doubleebx()==1 ) */
254
-      backsize = doubleebx(src, &myebx, &scur, ssize);
256
+      if ( (backsize = doubleebx(src, &myebx, &scur, ssize)) == -1 )
257
+        return -1;
255 258
     }
256 259
     else {
257 260
       backsize = 1;
258
-      if (doubleebx(src, &myebx, &scur, ssize))
259
-	backsize = 2 + doubleebx(src, &myebx, &scur, ssize);
261
+      if ((oob = doubleebx(src, &myebx, &scur, ssize)) == -1)
262
+        return -1;
263
+      if (oob) {
264
+	if ((oob = doubleebx(src, &myebx, &scur, ssize)) == -1)
265
+	  return -1;
266
+	  backsize = 2 + oob;
267
+	}
260 268
       else {
261 269
 	do {
262
-	  backsize = backsize * 2 + doubleebx(src, &myebx, &scur, ssize);
263
-	} while (!doubleebx(src, &myebx, &scur, ssize));
270
+          if ((oob = doubleebx(src, &myebx, &scur, ssize)) == -1)
271
+          return -1;
272
+	  backsize = backsize * 2 + oob;
273
+	} while ((oob = doubleebx(src, &myebx, &scur, ssize)) == 0);
274
+	if (oob == -1)
275
+          return -1;
264 276
 	backsize+=2;
265 277
       }
266 278
     }
... ...
@@ -278,3 +330,4 @@ int upx_inflate2e(char *src, int ssize, char *dst, int dsize)
278 278
   }
279 279
   return 0;
280 280
 }
281
+