Browse code

Check fseeks will work before calling fsek - requirement by TK

git-svn: trunk@1862

Nigel Horne authored on 2006/03/14 20:39:43
Showing 1 changed files
... ...
@@ -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.30 2006/03/11 17:09:22 nigelhorne Exp $";
27
+static	char	const	rcsid[] = "$Id: tnef.c,v 1.31 2006/03/14 11:39:43 nigelhorne Exp $";
28 28
 
29 29
 #include <stdio.h>
30 30
 #include <fcntl.h>
... ...
@@ -38,8 +38,8 @@ static	char	const	rcsid[] = "$Id: tnef.c,v 1.30 2006/03/11 17:09:22 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, int32_t length);
42
-static	int	tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, int32_t length, const char *dir, fileblob **fbref);
41
+static	int	tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length, off_t fsize);
42
+static	int	tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, int32_t length, const char *dir, fileblob **fbref, off_t fsize);
43 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
... ...
@@ -73,9 +73,17 @@ cli_tnef(const char *dir, int desc)
73 73
 	fileblob *fb;
74 74
 	int i, ret, alldone;
75 75
 	FILE *fp;
76
+	off_t fsize;
77
+	struct stat statb;
76 78
 
77 79
 	lseek(desc, 0L, SEEK_SET);
78 80
 
81
+	if(fstat(desc, &statb) < 0) {
82
+		cli_errmsg("Can't fstat descriptor %d\n", desc);
83
+		return CL_EIO;
84
+	}
85
+	fsize = statb.st_size;
86
+
79 87
 	i = dup(desc);
80 88
 	if((fp = fdopen(i, "rb")) == NULL) {
81 89
 		cli_errmsg("Can't open descriptor %d\n", desc);
... ...
@@ -138,7 +146,7 @@ cli_tnef(const char *dir, int desc)
138 138
 					fb = NULL;
139 139
 				}
140 140
 				fb = fileblobCreate();
141
-				if(tnef_message(fp, type, tag, length) != 0) {
141
+				if(tnef_message(fp, type, tag, length, fsize) != 0) {
142 142
 					cli_errmsg("Error reading TNEF message\n");
143 143
 					ret = CL_EFORMAT;
144 144
 					alldone = 1;
... ...
@@ -146,7 +154,7 @@ cli_tnef(const char *dir, int desc)
146 146
 				break;
147 147
 			case LVL_ATTACHMENT:
148 148
 				cli_dbgmsg("TNEF - found attachment\n");
149
-				if(tnef_attachment(fp, type, tag, length, dir, &fb) != 0) {
149
+				if(tnef_attachment(fp, type, tag, length, dir, &fb, fsize) != 0) {
150 150
 					cli_errmsg("Error reading TNEF message\n");
151 151
 					ret = CL_EFORMAT;
152 152
 					alldone = 1;
... ...
@@ -156,7 +164,7 @@ cli_tnef(const char *dir, int desc)
156 156
 				break;
157 157
 			default:
158 158
 				cli_warnmsg("TNEF - unknown level %d tag 0x%x\n", (int)part, (int)tag);
159
-				
159
+
160 160
 				/*
161 161
 				 * Dump the file incase it was part of an
162 162
 				 * email that's about to be deleted
... ...
@@ -207,7 +215,7 @@ cli_tnef(const char *dir, int desc)
207 207
 }
208 208
 
209 209
 static int
210
-tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length)
210
+tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length, off_t fsize)
211 211
 {
212 212
 	uint16_t i16;
213 213
 	off_t offset;
... ...
@@ -268,6 +276,10 @@ tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length)
268 268
 
269 269
 	/*cli_dbgmsg("%lu %lu\n", (long)(offset + length), ftell(fp));*/
270 270
 
271
+	if(!CLI_ISCONTAINED2(0, fsize, (off_t)offset, (off_t)length)) {
272
+		cli_errmsg("TNEF: Incorrect length field\n");
273
+		return -1;
274
+	}
271 275
 	if(fseek(fp, offset + length, SEEK_SET) < 0)
272 276
 		return -1;
273 277
 
... ...
@@ -279,7 +291,7 @@ tnef_message(FILE *fp, uint16_t type, uint16_t tag, int32_t length)
279 279
 }
280 280
 
281 281
 static int
282
-tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, int32_t length, const char *dir, fileblob **fbref)
282
+tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, int32_t length, const char *dir, fileblob **fbref, off_t fsize)
283 283
 {
284 284
 	uint32_t todo;
285 285
 	uint16_t i16;
... ...
@@ -344,11 +356,15 @@ tnef_attachment(FILE *fp, uint16_t type, uint16_t tag, int32_t length, const cha
344 344
 
345 345
 	/*cli_dbgmsg("%lu %lu\n", (long)(offset + length), ftell(fp));*/
346 346
 
347
+	if(!CLI_ISCONTAINED2(0, fsize, (off_t)offset, (off_t)length)) {
348
+		cli_errmsg("TNEF: Incorrect length field\n");
349
+		return -1;
350
+	}
347 351
 	if(fseek(fp, (long)(offset + length), SEEK_SET) < 0)	/* shouldn't be needed */
348 352
 		return -1;
349 353
 
350 354
 	/* Checksum - TODO, verify */
351
-	if(fread(&i16, sizeof(uint16_t), 1, fp) != 1) 
355
+	if(fread(&i16, sizeof(uint16_t), 1, fp) != 1)
352 356
 		return -1;
353 357
 
354 358
 	return 0;