git-svn: trunk@2928
Nigel Horne authored on 2007/03/10 10:18:38... | ... |
@@ -1,3 +1,8 @@ |
1 |
+Fri Mar 9 23:24:24 GMT 2007 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * libclamav/pdf.c: Fix fd leak on empty objects |
|
4 |
+ Scan in user memory |
|
5 |
+ |
|
1 | 6 |
Fri Mar 9 22:39:36 GMT 2007 (njh) |
2 | 7 |
---------------------------------- |
3 | 8 |
* libclamav/pdf.c: When flatedecoder fails point out that the encoder |
... | ... |
@@ -71,10 +71,9 @@ static const char *cli_pmemstr(const char *haystack, size_t hs, const char *need |
71 | 71 |
int |
72 | 72 |
cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
73 | 73 |
{ |
74 |
- struct stat statb; |
|
75 | 74 |
off_t size; /* total number of bytes in the file */ |
76 | 75 |
long bytesleft, trailerlength; |
77 |
- char *buf; /* start of memory mapped area */ |
|
76 |
+ char *buf, *alloced; /* start of memory mapped area */ |
|
78 | 77 |
const char *p, *q, *trailerstart; |
79 | 78 |
const char *xrefstart; /* cross reference table */ |
80 | 79 |
/*size_t xreflength;*/ |
... | ... |
@@ -82,6 +81,7 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
82 | 82 |
struct table *md5table; |
83 | 83 |
int printed_predictor_message; |
84 | 84 |
int printed_embedded_font_message; |
85 |
+ struct stat statb; |
|
85 | 86 |
|
86 | 87 |
cli_dbgmsg("in cli_pdf(%s)\n", dir); |
87 | 88 |
|
... | ... |
@@ -100,20 +100,37 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
100 | 100 |
if(buf == MAP_FAILED) |
101 | 101 |
return CL_EMEM; |
102 | 102 |
|
103 |
+ alloced = cli_malloc(size); |
|
104 |
+ if(alloced) { |
|
105 |
+ /* |
|
106 |
+ * FIXME: now I have this, there's no need for the lack of |
|
107 |
+ * support on systems without mmap, e.g. cygwin |
|
108 |
+ */ |
|
109 |
+ memcpy(alloced, buf, size); |
|
110 |
+ munmap(buf, size); |
|
111 |
+ p = alloced; |
|
112 |
+ } |
|
113 |
+ |
|
103 | 114 |
cli_dbgmsg("cli_pdf: scanning %lu bytes\n", (unsigned long)size); |
104 | 115 |
|
105 | 116 |
/* Lines are terminated by \r, \n or both */ |
106 | 117 |
|
107 | 118 |
/* File Header */ |
108 | 119 |
if(memcmp(p, "%PDF-1.", 7) != 0) { |
109 |
- munmap(buf, size); |
|
120 |
+ if(alloced) |
|
121 |
+ free(alloced); |
|
122 |
+ else |
|
123 |
+ munmap(buf, size); |
|
110 | 124 |
return CL_EFORMAT; |
111 | 125 |
} |
112 | 126 |
|
113 | 127 |
#if 0 |
114 | 128 |
q = pdf_nextlinestart(&p[6], size - 6); |
115 | 129 |
if(q == NULL) { |
116 |
- munmap(buf, size); |
|
130 |
+ if(alloced) |
|
131 |
+ free(alloced); |
|
132 |
+ else |
|
133 |
+ munmap(buf, size); |
|
117 | 134 |
return CL_EFORMAT; |
118 | 135 |
} |
119 | 136 |
bytesleft = size - (long)(q - p); |
... | ... |
@@ -129,7 +146,10 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
129 | 129 |
break; |
130 | 130 |
|
131 | 131 |
if(q == p) { |
132 |
- munmap(buf, size); |
|
132 |
+ if(alloced) |
|
133 |
+ free(alloced); |
|
134 |
+ else |
|
135 |
+ munmap(buf, size); |
|
133 | 136 |
return CL_EFORMAT; |
134 | 137 |
} |
135 | 138 |
|
... | ... |
@@ -145,7 +165,10 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
145 | 145 |
/* |
146 | 146 |
* This tends to mean that the file is, in effect, read-only |
147 | 147 |
*/ |
148 |
- munmap(buf, size); |
|
148 |
+ if(alloced) |
|
149 |
+ free(alloced); |
|
150 |
+ else |
|
151 |
+ munmap(buf, size); |
|
149 | 152 |
cli_warnmsg("Encrypted PDF files not yet supported\n"); |
150 | 153 |
return CL_EFORMAT; |
151 | 154 |
} |
... | ... |
@@ -168,7 +191,10 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
168 | 168 |
break; |
169 | 169 |
|
170 | 170 |
if(xrefstart == p) { |
171 |
- munmap(buf, size); |
|
171 |
+ if(alloced) |
|
172 |
+ free(alloced); |
|
173 |
+ else |
|
174 |
+ munmap(buf, size); |
|
172 | 175 |
return CL_EFORMAT; |
173 | 176 |
} |
174 | 177 |
|
... | ... |
@@ -185,8 +211,7 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
185 | 185 |
* The body section consists of a sequence of indirect objects |
186 | 186 |
*/ |
187 | 187 |
while((p < xrefstart) && |
188 |
- ((q = pdf_nextobject(p, bytesleft)) != NULL) && |
|
189 |
- (rc == CL_CLEAN)) { |
|
188 |
+ ((q = pdf_nextobject(p, bytesleft)) != NULL)) { |
|
190 | 189 |
int is_ascii85decode, is_flatedecode, fout, len, has_cr; |
191 | 190 |
/*int object_number, generation_number;*/ |
192 | 191 |
const char *objstart, *objend, *streamstart, *streamend; |
... | ... |
@@ -274,8 +299,8 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
274 | 274 |
snprintf(b, sizeof(b), |
275 | 275 |
"%d 0 obj", length); |
276 | 276 |
length = strlen(b); |
277 |
- r = cli_pmemstr(buf, size, b, |
|
278 |
- length); |
|
277 |
+ r = cli_pmemstr(alloced ? alloced : buf, |
|
278 |
+ size, b, length); |
|
279 | 279 |
if(r) { |
280 | 280 |
r += length - 1; |
281 | 281 |
r = pdf_nextobject(r, bytesleft - (r - q)); |
... | ... |
@@ -393,6 +418,7 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
393 | 393 |
streamend++; |
394 | 394 |
|
395 | 395 |
if(streamend <= streamstart) { |
396 |
+ close(fout); |
|
396 | 397 |
cli_dbgmsg("Empty stream\n"); |
397 | 398 |
continue; |
398 | 399 |
} |
... | ... |
@@ -473,7 +499,10 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
473 | 473 |
cli_dbgmsg("cli_pdf: extracted to %s\n", fullname); |
474 | 474 |
} |
475 | 475 |
|
476 |
- munmap(buf, size); |
|
476 |
+ if(alloced) |
|
477 |
+ free(alloced); |
|
478 |
+ else |
|
479 |
+ munmap(buf, size); |
|
477 | 480 |
|
478 | 481 |
tableDestroy(md5table); |
479 | 482 |
|
... | ... |
@@ -498,7 +527,7 @@ try_flatedecode(unsigned char *buf, off_t real_len, off_t calculated_len, int fo |
498 | 498 |
return Z_OK; |
499 | 499 |
|
500 | 500 |
/* i.e. the PDF file is broken :-( */ |
501 |
- cli_warnmsg("cli_pdf: Bad uncompressed block length in flate stream\n"); |
|
501 |
+ cli_warnmsg("cli_pdf: Bad compressed block length in flate stream\n"); |
|
502 | 502 |
|
503 | 503 |
return ret; |
504 | 504 |
} |