Browse code

add more sanity checks

git-svn: trunk@2754

Tomasz Kojm authored on 2007/02/16 00:36:14
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Thu Feb 15 16:34:48 CET 2007 (tk)
2
+---------------------------------
3
+  * libclamav/rtf.c: add more sanity checks (Edwin)
4
+
1 5
 Thu Feb 15 16:18:53 CET 2007 (tk)
2 6
 ---------------------------------
3 7
   * freshclam/manager.c: fix warning message (bb#292)
... ...
@@ -201,7 +201,8 @@ static int load_actions(table_t* t)
201 201
 {
202 202
 	size_t i;
203 203
 	for(i=0; i<rtf_action_mapping_cnt; i++)
204
-		tableInsert(t, rtf_action_mapping[i].controlword, rtf_action_mapping[i].action);
204
+		if(tableInsert(t, rtf_action_mapping[i].controlword, rtf_action_mapping[i].action) == -1)
205
+			return -1;
205 206
 	return 0;
206 207
 }
207 208
 
... ...
@@ -217,6 +218,8 @@ static int rtf_object_begin(struct rtf_state* state,cli_ctx* ctx,const char* tmp
217 217
 	data->internal_state = WAIT_MAGIC;
218 218
 	data->tmpdir = tmpdir;
219 219
 	data->ctx    = ctx;
220
+	data->name   = NULL;
221
+	data->desc_name = NULL;
220 222
 
221 223
 	state->cb_data = data;
222 224
 	return 0;
... ...
@@ -227,8 +230,8 @@ static int decode_and_scan(struct rtf_object_data* data, cli_ctx* ctx)
227 227
 {
228 228
 	int ofd, ret=0;
229 229
 
230
-	cli_dbgmsg("Scanning embedded object:%s\n",data->name);
231
-	if(data->bread == 1) {
230
+	cli_dbgmsg("RTF:Scanning embedded object:%s\n",data->name);
231
+	if(data->bread == 1 && data->fd > 0) {
232 232
 		cli_dbgmsg("Decoding ole object\n");
233 233
 		lseek(data->fd,0,SEEK_SET);
234 234
 		ofd = cli_decode_ole_object(data->fd,data->tmpdir);
... ...
@@ -237,10 +240,11 @@ static int decode_and_scan(struct rtf_object_data* data, cli_ctx* ctx)
237 237
 			close(ofd);
238 238
 		}
239 239
 	}
240
-	else
240
+	else if(data->fd > 0)
241 241
 		ret = cli_magic_scandesc(data->fd,ctx);
242
+	if(data->fd > 0)
242 243
 	close(data->fd);
243
-	data->fd = 0;
244
+	data->fd = -1;
244 245
 	if(data->name) {
245 246
 		if(!cli_leavetemps_flag)
246 247
 			unlink(data->name);
... ...
@@ -295,9 +299,10 @@ static int rtf_object_process(struct rtf_state* state, const unsigned char* inpu
295 295
 	while(out_data && out_cnt) {
296 296
 		switch(data->internal_state) {
297 297
 			case WAIT_MAGIC: {
298
+						 cli_dbgmsg("RTF: waiting for magic\n");
298 299
 						 for(i=0; i<out_cnt && data->bread < rtf_data_magic_len; i++, data->bread++)
299 300
 							 if(rtf_data_magic[data->bread] != out_data[i]) {
300
-								 cli_dbgmsg("Warning: rtf objdata magic number not matched, expected:%d, got: %d, at pos:%d\n",rtf_data_magic[i],out_data[i],data->bread);
301
+								 cli_dbgmsg("Warning: rtf objdata magic number not matched, expected:%d, got: %d, at pos:%lu\n",rtf_data_magic[i],out_data[i],data->bread);
301 302
 							 }
302 303
 						 out_cnt  -= i;
303 304
 						 if(data->bread == rtf_data_magic_len) {
... ...
@@ -317,7 +322,7 @@ static int rtf_object_process(struct rtf_state* state, const unsigned char* inpu
317 317
 							    out_data += i;
318 318
 							    data->bread=0;
319 319
 							    if(data->desc_len > 64) {
320
-								    cli_dbgmsg("Description length too big (%d), showing only 64 bytes of it\n",data->desc_len);
320
+								    cli_dbgmsg("Description length too big (%lu), showing only 64 bytes of it\n",data->desc_len);
321 321
 								    data->desc_name = cli_malloc(65);
322 322
 							    }
323 323
 							    else
... ...
@@ -326,21 +331,29 @@ static int rtf_object_process(struct rtf_state* state, const unsigned char* inpu
326 326
 								    return CL_EMEM;
327 327
 							    }
328 328
 							    data->internal_state = WAIT_DESC;
329
+							    cli_dbgmsg("RTF: description length:%lu\n",data->desc_len);
329 330
 						    }
330 331
 						    break;
331 332
 					    }
332 333
 			case WAIT_DESC:{
334
+					       cli_dbgmsg("RTF: in WAIT_DESC\n");
333 335
 					       for(i=0;i<out_cnt && data->bread < data->desc_len && data->bread < 64;i++, data->bread++)
334 336
 						       data->desc_name[data->bread] = out_data[i];
335
-					       /*FIXME: sanity check here, to avoid segfault */
336
-					       if(i+data->desc_len-data->bread > out_cnt) {
337
-						       cli_dbgmsg("Can't interpret length in wait_desc\n");
338
-						       return 0;/* bail out */
337
+					       out_cnt -= i;
338
+					       out_data += i;
339
+					       if(data->bread < data->desc_len && data->bread < 64) {
340
+						       cli_dbgmsg("RTF: waiting for more data(1)\n");
341
+						       return 0;/* wait for more data */
339 342
 					       }
340
-					       out_cnt  -= i + data->desc_len - data->bread;
341
-					       if(data->bread <= data->desc_len) {
342
-						       out_data += i + data->desc_len - data->bread;
343 343
 						       data->desc_name[data->bread] = '\0';
344
+					       if(data->desc_len - data->bread > out_cnt) {
345
+						       data->desc_len -= out_cnt;
346
+						       cli_dbgmsg("RTF: waiting for more data(2)\n");
347
+						       return 0;/* wait for more data */
348
+					       }
349
+					       out_cnt  -= data->desc_len - data->bread;
350
+					       if(data->bread >= data->desc_len) {
351
+						       out_data += data->desc_len - data->bread;
344 352
 						       data->bread = 0;
345 353
 						       cli_dbgmsg("Preparing to dump rtf embedded object, description:%s\n",data->desc_name);
346 354
 						       free(data->desc_name);
... ...
@@ -361,12 +374,14 @@ static int rtf_object_process(struct rtf_state* state, const unsigned char* inpu
361 361
 					       if(data->bread == 8) {
362 362
 						       out_data += 8;
363 363
 						       data->bread = 0;
364
+						       cli_dbgmsg("RTF: next state: wait_data_size\n");
364 365
 						       data->internal_state = WAIT_DATA_SIZE;
365 366
 					       }
366 367
 					       break;
367 368
 				       }
368 369
 
369 370
 			case WAIT_DATA_SIZE: {
371
+						     cli_dbgmsg("RTF: in WAIT_DATA_SIZE\n");
370 372
 						    if(data->bread == 0)
371 373
 							    data->desc_len = 0;
372 374
 						    for(i=0; i<out_cnt && data->bread < 4; i++,data->bread++)
... ...
@@ -377,9 +392,10 @@ static int rtf_object_process(struct rtf_state* state, const unsigned char* inpu
377 377
 							    data->bread=0;
378 378
 							    cli_dbgmsg("Dumping rtf embedded object of size:%ld\n",data->desc_len);
379 379
 					    		    data->name = cli_gentempdesc(data->tmpdir, &data->fd);
380
-							    if(!data->name)
380
+							    if(!data->name || data->fd < 0)
381 381
 								    return CL_ETMPFILE;
382 382
 							    data->internal_state = DUMP_DATA;
383
+	    						    cli_dbgmsg("RTF: next state: DUMP_DATA\n");
383 384
 						    }
384 385
 						    break;
385 386
 					     }
... ...
@@ -431,7 +447,7 @@ static int rtf_object_end(struct rtf_state* state,cli_ctx* ctx)
431 431
 	int rc = 0;
432 432
 	if(!data)
433 433
 		return 0;
434
-	if(data->fd) { 
434
+	if(data->fd > 0) { 
435 435
 		rc = decode_and_scan(data, ctx);
436 436
 	}
437 437
 	if(data->name)
... ...
@@ -531,6 +547,7 @@ int cli_scanrtf(int desc, cli_ctx *ctx)
531 531
 		if(!cli_leavetemps_flag)
532 532
 			cli_rmdirs(tempname);
533 533
 		free(tempname);
534
+		tableDestroy(actiontable);
534 535
 		return ret;
535 536
 	}
536 537