Browse code

Handle incorrectly formed files (invalid length fields)

git-svn: trunk@1647

Nigel Horne authored on 2005/07/11 23:58:05
Showing 2 changed files
... ...
@@ -1,3 +1,9 @@
1
+Mon Jul 11 15:57:05 BST 2005 (njh)
2
+----------------------------------
3
+  * libclamav/tnef.c:	Fix possible crash if the length field is 0 or negative
4
+				in headers - reported by Alex Wheeler (alexbling
5
+				at gmail.com)
6
+
1 7
 Sat Jul  2 22:05:03 BST 2005 (njh)
2 8
 ----------------------------------
3 9
   * libclamav/mbox.c:	NEW_WORLD: Improved the handling of files which contain
... ...
@@ -24,7 +24,7 @@
24 24
 #include "clamav-config.h"
25 25
 #endif
26 26
 
27
-static	char	const	rcsid[] = "$Id: tnef.c,v 1.24 2005/05/18 20:55:59 nigelhorne Exp $";
27
+static	char	const	rcsid[] = "$Id: tnef.c,v 1.25 2005/07/11 14:55:10 nigelhorne Exp $";
28 28
 
29 29
 #include <stdio.h>
30 30
 #include <fcntl.h>
... ...
@@ -38,9 +38,9 @@ static	char	const	rcsid[] = "$Id: tnef.c,v 1.24 2005/05/18 20:55:59 nigelhorne E
38 38
 #endif
39 39
 #include "blob.h"
40 40
 
41
-static	int	tnef_message(FILE *fp, uint16_t type, uint16_t tag, uint32_t length);
42
-static	int	tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, uint32_t length, const char *dir, fileblob **fbref);
43
-static	int	tnef_header(FILE *fp, uint8_t *part, uint16_t *type, uint16_t *tag, uint32_t *length);
41
+static	int	tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length);
42
+static	int	tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, int32_t length, const char *dir, fileblob **fbref);
43
+static	int	tnef_header(FILE *fp, uint8_t *part, uint16_t *type, uint16_t *tag, int32_t *length);
44 44
 
45 45
 #define	TNEF_SIGNATURE	0x223E9f78
46 46
 #define	LVL_MESSAGE	0x01
... ...
@@ -104,7 +104,7 @@ cli_tnef(const char *dir, int desc)
104 104
 	do {
105 105
 		uint8_t part;
106 106
 		uint16_t type, tag;
107
-		uint32_t length;
107
+		int32_t length;
108 108
 
109 109
 		switch(tnef_header(fp, &part, &type, &tag, &length)) {
110 110
 			case 0:
... ...
@@ -183,6 +183,8 @@ cli_tnef(const char *dir, int desc)
183 183
 		}
184 184
 	} while(!alldone);
185 185
 
186
+	fclose(fp);
187
+
186 188
 	if(fb) {
187 189
 		cli_dbgmsg("cli_tnef: flushing final data\n");
188 190
 		if(fileblobGetFilename(fb) == NULL) {
... ...
@@ -192,14 +194,13 @@ cli_tnef(const char *dir, int desc)
192 192
 		fileblobDestroy(fb);
193 193
 		fb = NULL;
194 194
 	}
195
-	fclose(fp);
196 195
 
197 196
 	cli_dbgmsg("cli_tnef: returning %d\n", ret);
198 197
 	return ret;
199 198
 }
200 199
 
201 200
 static int
202
-tnef_message(FILE *fp, uint16_t type, uint16_t tag, uint32_t length)
201
+tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length)
203 202
 {
204 203
 	uint16_t i16;
205 204
 	off_t offset;
... ...
@@ -208,7 +209,7 @@ tnef_message(FILE *fp, uint16_t type, uint16_t tag, uint32_t length)
208 208
 	char *string;
209 209
 #endif
210 210
 
211
-	cli_dbgmsg("message tag 0x%x, type 0x%x, length %u\n", tag, type, length);
211
+	cli_dbgmsg("message tag 0x%x, type 0x%x, length %d\n", tag, type, length);
212 212
 
213 213
 	offset = ftell(fp);
214 214
 
... ...
@@ -239,8 +240,12 @@ tnef_message(FILE *fp, uint16_t type, uint16_t tag, uint32_t length)
239 239
 			/* 14 bytes, long */
240 240
 			break;
241 241
 		case attMSGCLASS:
242
+			if(length <= 0)
243
+				return -1;
242 244
 			string = cli_malloc(length + 1);
243
-			if(fread(string, 1, length, fp) != length) {
245
+			if(string == NULL)
246
+				return -1;
247
+			if(fread(string, 1, (uint32_t)length, fp) != (uint32_t)length) {
244 248
 				free(string);
245 249
 				return -1;
246 250
 			}
... ...
@@ -266,21 +271,25 @@ tnef_message(FILE *fp, uint16_t type, uint16_t tag, uint32_t length)
266 266
 }
267 267
 
268 268
 static int
269
-tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, uint32_t length, const char *dir, fileblob **fbref)
269
+tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, int32_t length, const char *dir, fileblob **fbref)
270 270
 {
271 271
 	uint32_t todo;
272 272
 	uint16_t i16;
273 273
 	off_t offset;
274 274
 	char *string;
275 275
 
276
-	cli_dbgmsg("attachment tag 0x%x, type 0x%x, length %u\n", tag, type, length);
276
+	cli_dbgmsg("attachment tag 0x%x, type 0x%x, length %d\n", tag, type, length);
277 277
 
278 278
 	offset = ftell(fp);
279 279
 
280 280
 	switch(tag) {
281 281
 		case attATTACHTITLE:
282
+			if(length <= 0)
283
+				return -1;
282 284
 			string = cli_malloc(length + 1);
283
-			if(fread(string, 1, length, fp) != length) {
285
+			if(string == NULL)
286
+				return -1;
287
+			if(fread(string, 1, (uint32_t)length, fp) != (uint32_t)length) {
284 288
 				free(string);
285 289
 				return -1;
286 290
 			}
... ...
@@ -337,7 +346,7 @@ tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, uint32_t length, const ch
337 337
 }
338 338
 
339 339
 static int
340
-tnef_header(FILE *fp, uint8_t *part, uint16_t *type, uint16_t *tag, uint32_t *length)
340
+tnef_header(FILE *fp, uint8_t *part, uint16_t *type, uint16_t *tag, int32_t *length)
341 341
 {
342 342
 	uint32_t i32;
343 343
 
... ...
@@ -356,7 +365,7 @@ tnef_header(FILE *fp, uint8_t *part, uint16_t *type, uint16_t *tag, uint32_t *le
356 356
 
357 357
 	if(fread(&i32, sizeof(uint32_t), 1, fp) != 1)
358 358
 		return -1;
359
-	*length = host32(i32);
359
+	*length = (int32_t)host32(i32);
360 360
 
361 361
 	cli_dbgmsg("message tag 0x%x, type 0x%x, length %u\n", *tag, *type, *length);
362 362