git-svn-id: file:///var/lib/svn/clamav-devel/branches/newlimits@3552 77e5149b-7576-45b1-b177-96237e5ba77b
aCaB authored on 2008/01/28 10:46:00... | ... |
@@ -161,15 +161,17 @@ void cab_free(struct cab_archive *cab) |
161 | 161 |
|
162 | 162 |
|
163 | 163 |
if(cab->state) { |
164 |
- switch(cab->state->cmethod & 0x000f) { |
|
165 |
- case 0x0001: |
|
166 |
- mszip_free(cab->state->stream); |
|
167 |
- break; |
|
168 |
- case 0x0002: |
|
169 |
- qtm_free(cab->state->stream); |
|
170 |
- break; |
|
171 |
- case 0x0003: |
|
172 |
- lzx_free(cab->state->stream); |
|
164 |
+ if(cab->state->stream) { |
|
165 |
+ switch(cab->state->cmethod & 0x000f) { |
|
166 |
+ case 0x0001: |
|
167 |
+ mszip_free(cab->state->stream); |
|
168 |
+ break; |
|
169 |
+ case 0x0002: |
|
170 |
+ qtm_free(cab->state->stream); |
|
171 |
+ break; |
|
172 |
+ case 0x0003: |
|
173 |
+ lzx_free(cab->state->stream); |
|
174 |
+ } |
|
173 | 175 |
} |
174 | 176 |
free(cab->state); |
175 | 177 |
} |
... | ... |
@@ -604,19 +606,21 @@ static int cab_unstore(struct cab_file *file, int bytes) |
604 | 604 |
#define CAB_CHGFOLDER \ |
605 | 605 |
if(!file->cab->actfol || (file->folder != file->cab->actfol)) { \ |
606 | 606 |
if(file->cab->state) { \ |
607 |
- switch(file->cab->state->cmethod & 0x000f) { \ |
|
608 |
- case 0x0001: \ |
|
609 |
- mszip_free(file->cab->state->stream); \ |
|
610 |
- break; \ |
|
611 |
- case 0x0002: \ |
|
612 |
- qtm_free(file->cab->state->stream); \ |
|
613 |
- break; \ |
|
614 |
- case 0x0003: \ |
|
615 |
- lzx_free(file->cab->state->stream); \ |
|
607 |
+ if(file->cab->state->stream) { \ |
|
608 |
+ switch(file->cab->state->cmethod & 0x000f) { \ |
|
609 |
+ case 0x0001: \ |
|
610 |
+ mszip_free(file->cab->state->stream); \ |
|
611 |
+ break; \ |
|
612 |
+ case 0x0002: \ |
|
613 |
+ qtm_free(file->cab->state->stream); \ |
|
614 |
+ break; \ |
|
615 |
+ case 0x0003: \ |
|
616 |
+ lzx_free(file->cab->state->stream); \ |
|
617 |
+ } \ |
|
616 | 618 |
} \ |
617 | 619 |
free(file->cab->state); \ |
620 |
+ file->cab->state = NULL; \ |
|
618 | 621 |
} \ |
619 |
- file->cab->actfol = file->folder; \ |
|
620 | 622 |
if(lseek(file->fd, file->folder->offset, SEEK_SET) == -1) { \ |
621 | 623 |
cli_dbgmsg("cab_extract: Can't lseek to %u\n", (unsigned int) file->folder->offset); \ |
622 | 624 |
return CL_EFORMAT; /* truncated file? */ \ |
... | ... |
@@ -638,10 +642,10 @@ static int cab_unstore(struct cab_file *file, int bytes) |
638 | 638 |
file->cab->state->stream = (struct lzx_stream *) lzx_init(file->fd, file->ofd, (int) (file->folder->cmethod >> 8) & 0x1f, 0, 4096, 0, file, &cab_read); \ |
639 | 639 |
} \ |
640 | 640 |
if((file->folder->cmethod & 0x000f) && !file->cab->state->stream) { \ |
641 |
- free(file->cab->state); \ |
|
642 | 641 |
close(file->ofd); \ |
643 | 642 |
return CL_EMSCAB; \ |
644 | 643 |
} \ |
644 |
+ file->cab->actfol = file->folder; \ |
|
645 | 645 |
} |
646 | 646 |
|
647 | 647 |
|
... | ... |
@@ -663,7 +667,6 @@ int cab_extract(struct cab_file *file, const char *name) |
663 | 663 |
file->ofd = open(name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU); |
664 | 664 |
if(file->ofd == -1) { |
665 | 665 |
cli_errmsg("cab_extract: Can't open file %s in write mode\n", name); |
666 |
- free(file->cab->state); |
|
667 | 666 |
return CL_EIO; |
668 | 667 |
} |
669 | 668 |
|
... | ... |
@@ -196,6 +196,49 @@ const char *cl_strerror(int clerror) |
196 | 196 |
} |
197 | 197 |
} |
198 | 198 |
|
199 |
+int cli_sizelimits(cli_ctx *ctx, unsigned long need1, unsigned long need2, unsigned long need3) { |
|
200 |
+ int ret = CL_SUCCESS; |
|
201 |
+ unsigned long needed; |
|
202 |
+ |
|
203 |
+ /* if called without limits, go on, unpack */ |
|
204 |
+ if(!ctx || !ctx->limits) return CL_SUCCESS; |
|
205 |
+ |
|
206 |
+ needed = (need1>need2)?need1:need2; |
|
207 |
+ needed = (needed>need3)?needed:need3; |
|
208 |
+ |
|
209 |
+ /* if we have global scan limits */ |
|
210 |
+ if(ctx->limits->maxscansize) { |
|
211 |
+ /* if the remaining scansize is too small... */ |
|
212 |
+ if(ctx->limits->maxscansize-ctx->scansize<needed) { |
|
213 |
+ cli_dbgmsg("cli_limits: scansize exceeded (initial: %u, remaining: %u, needed: %u)\n", ctx->limits->maxscansize, ctx->scansize, needed); |
|
214 |
+ /* ... we return INFECTED only upon request */ |
|
215 |
+ if(BLOCKMAX) { |
|
216 |
+ *ctx->virname = "Archive.ExceededScanSize"; |
|
217 |
+ return CL_VIRUS; |
|
218 |
+ } |
|
219 |
+ /* ... otherwise we tell the caller to skip this file */ |
|
220 |
+ ret = CL_BREAK; |
|
221 |
+ } else { |
|
222 |
+ /* if the remaining scanzise is big enough, we update it */ |
|
223 |
+ ctx->scansize+=needed; |
|
224 |
+ } |
|
225 |
+ } |
|
226 |
+ |
|
227 |
+ /* if we have per-file size limits, and we are overlimit... */ |
|
228 |
+ if(ctx->limits->maxfilesize && ctx->limits->maxfilesize<needed) { |
|
229 |
+ /* ... we return INFECTED only upon request */ |
|
230 |
+ if(BLOCKMAX) { |
|
231 |
+ *ctx->virname = "Archive.ExceededFileSize"; |
|
232 |
+ return CL_VIRUS; |
|
233 |
+ } |
|
234 |
+ /* ... otherwise we tell the caller to skip this file */ |
|
235 |
+ ret = CL_BREAK; |
|
236 |
+ } |
|
237 |
+ |
|
238 |
+ return ret; |
|
239 |
+ /* FIXME: set/check ctx->scanned in magic_scandesc */ |
|
240 |
+} |
|
241 |
+ |
|
199 | 242 |
unsigned char *cli_md5digest(int desc) |
200 | 243 |
{ |
201 | 244 |
unsigned char *digest; |
... | ... |
@@ -628,11 +671,7 @@ int cli_rmdirs(const char *dirname) |
628 | 628 |
return -1; |
629 | 629 |
} |
630 | 630 |
|
631 |
-#ifdef C_WINDOWS |
|
632 |
- sprintf(path, "%s\\%s", dirname, dent->d_name); |
|
633 |
-#else |
|
634 | 631 |
sprintf(path, "%s/%s", dirname, dent->d_name); |
635 |
-#endif |
|
636 | 632 |
|
637 | 633 |
/* stat the file */ |
638 | 634 |
if(lstat(path, &statbuf) != -1) { |
... | ... |
@@ -82,7 +82,8 @@ typedef struct { |
82 | 82 |
const struct cl_limits *limits; |
83 | 83 |
unsigned long scansize; |
84 | 84 |
unsigned int options; |
85 |
- unsigned int arec; |
|
85 |
+ unsigned int recursion; |
|
86 |
+ unsigned int scanned; |
|
86 | 87 |
unsigned int found_possibly_unwanted; |
87 | 88 |
struct cli_dconf *dconf; |
88 | 89 |
} cli_ctx; |
... | ... |
@@ -1969,16 +1969,18 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1969 | 1969 |
int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options) |
1970 | 1970 |
{ |
1971 | 1971 |
cli_ctx ctx; |
1972 |
+ cl_limits l_limits; |
|
1972 | 1973 |
int rc; |
1973 | 1974 |
|
1974 | 1975 |
memset(&ctx, '\0', sizeof(cli_ctx)); |
1975 | 1976 |
ctx.engine = engine; |
1976 | 1977 |
ctx.virname = virname; |
1977 |
- ctx.limits = limits; |
|
1978 |
+ ctx.limits = &l_limits; |
|
1978 | 1979 |
ctx.scanned = scanned; |
1979 | 1980 |
ctx.options = options; |
1980 | 1981 |
ctx.found_possibly_unwanted = 0; |
1981 | 1982 |
ctx.dconf = (struct cli_dconf *) engine->dconf; |
1983 |
+ memcpy(&l_limits, limits, sizeof(struct cl_limits)); |
|
1982 | 1984 |
|
1983 | 1985 |
rc = cli_magic_scandesc(desc, &ctx); |
1984 | 1986 |
if(rc == CL_CLEAN && ctx.found_possibly_unwanted) |