git-svn: trunk@5026
Tomasz Kojm authored on 2009/04/07 05:01:09... | ... |
@@ -1,3 +1,8 @@ |
1 |
+Mon Apr 6 21:58:45 CEST 2009 (tk) |
|
2 |
+---------------------------------- |
|
3 |
+ * libclamav: fix handling of signature offsets in cli_scanbuff() (bb#1546) |
|
4 |
+ Reported by Christoph |
|
5 |
+ |
|
1 | 6 |
Mon Apr 6 12:32:44 EEST 2009 (edwin) |
2 | 7 |
------------------------------------- |
3 | 8 |
* docs/man/clamd.conf.5.in, etc/clamd.conf, shared/optparser.c: fix |
... | ... |
@@ -590,7 +590,7 @@ fileblobAddData(fileblob *fb, const unsigned char *data, size_t len) |
590 | 590 |
*ctx->scanned += (unsigned long)len / CL_COUNT_PRECISION; |
591 | 591 |
fb->bytes_scanned += (unsigned long)len; |
592 | 592 |
|
593 |
- if((len > 5) && cli_updatelimits(ctx, len)==CL_CLEAN && (cli_scanbuff(data, (unsigned int)len, ctx->virname, ctx->engine, CL_TYPE_BINARY_DATA, NULL) == CL_VIRUS)) { |
|
593 |
+ if((len > 5) && cli_updatelimits(ctx, len)==CL_CLEAN && (cli_scanbuff(data, (unsigned int)len, 0, ctx->virname, ctx->engine, CL_TYPE_BINARY_DATA, NULL) == CL_VIRUS)) { |
|
594 | 594 |
cli_dbgmsg("fileblobAddData: found %s\n", *ctx->virname); |
595 | 595 |
fb->isInfected = 1; |
596 | 596 |
} |
... | ... |
@@ -46,7 +46,7 @@ |
46 | 46 |
#include "default.h" |
47 | 47 |
|
48 | 48 |
|
49 |
-int cli_scanbuff(const unsigned char *buffer, uint32_t length, cli_ctx *ctx, cli_file_t ftype, struct cli_ac_data **acdata) |
|
49 |
+int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset, cli_ctx *ctx, cli_file_t ftype, struct cli_ac_data **acdata) |
|
50 | 50 |
{ |
51 | 51 |
int ret = CL_CLEAN; |
52 | 52 |
unsigned int i; |
... | ... |
@@ -76,8 +76,8 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, cli_ctx *ctx, cli |
76 | 76 |
if(!acdata && (ret = cli_ac_initdata(&mdata, troot->ac_partsigs, troot->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN))) |
77 | 77 |
return ret; |
78 | 78 |
|
79 |
- if(troot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, troot, 0, ftype, -1)) != CL_VIRUS) |
|
80 |
- ret = cli_ac_scanbuff(buffer, length, virname, NULL, NULL, troot, acdata ? (acdata[0]) : (&mdata), 0, ftype, -1, NULL, AC_SCAN_VIR, NULL); |
|
79 |
+ if(troot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, troot, offset, ftype, -1)) != CL_VIRUS) |
|
80 |
+ ret = cli_ac_scanbuff(buffer, length, virname, NULL, NULL, troot, acdata ? (acdata[0]) : (&mdata), offset, ftype, -1, NULL, AC_SCAN_VIR, NULL); |
|
81 | 81 |
|
82 | 82 |
if(!acdata) |
83 | 83 |
cli_ac_freedata(&mdata); |
... | ... |
@@ -89,8 +89,8 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, cli_ctx *ctx, cli |
89 | 89 |
if(!acdata && (ret = cli_ac_initdata(&mdata, groot->ac_partsigs, groot->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN))) |
90 | 90 |
return ret; |
91 | 91 |
|
92 |
- if(groot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, groot, 0, ftype, -1)) != CL_VIRUS) |
|
93 |
- ret = cli_ac_scanbuff(buffer, length, virname, NULL, NULL, groot, acdata ? (acdata[1]) : (&mdata), 0, ftype, -1, NULL, AC_SCAN_VIR, NULL); |
|
92 |
+ if(groot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, groot, offset, ftype, -1)) != CL_VIRUS) |
|
93 |
+ ret = cli_ac_scanbuff(buffer, length, virname, NULL, NULL, groot, acdata ? (acdata[1]) : (&mdata), offset, ftype, -1, NULL, AC_SCAN_VIR, NULL); |
|
94 | 94 |
|
95 | 95 |
if(!acdata) |
96 | 96 |
cli_ac_freedata(&mdata); |
... | ... |
@@ -108,6 +108,17 @@ off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_f |
108 | 108 |
|
109 | 109 |
*ret = 0; |
110 | 110 |
|
111 |
+ if((pt = strchr(offstr, ','))) |
|
112 |
+ *maxshift = atoi(++pt); |
|
113 |
+ |
|
114 |
+ if(isdigit(offstr[0])) |
|
115 |
+ return atoi(offstr); |
|
116 |
+ |
|
117 |
+ if(fd == -1) { |
|
118 |
+ *ret = -1; |
|
119 |
+ return 0; |
|
120 |
+ } |
|
121 |
+ |
|
111 | 122 |
if(!strncmp(offstr, "EP", 2) || offstr[0] == 'S') { |
112 | 123 |
|
113 | 124 |
if(info->status == -1) { |
... | ... |
@@ -140,13 +151,7 @@ off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, cli_f |
140 | 140 |
} |
141 | 141 |
} |
142 | 142 |
|
143 |
- if((pt = strchr(offstr, ','))) |
|
144 |
- *maxshift = atoi(++pt); |
|
145 |
- |
|
146 |
- if(isdigit(offstr[0])) { |
|
147 |
- return atoi(offstr); |
|
148 |
- |
|
149 |
- } else if(info->status == 1 && (!strncmp(offstr, "EP+", 3) || !strncmp(offstr, "EP-", 3))) { |
|
143 |
+ if(info->status == 1 && (!strncmp(offstr, "EP+", 3) || !strncmp(offstr, "EP-", 3))) { |
|
150 | 144 |
|
151 | 145 |
if(offstr[2] == '+') |
152 | 146 |
return info->exeinfo.ep + atoi(offstr + 3); |
... | ... |
@@ -229,13 +234,11 @@ int cli_validatesig(cli_file_t ftype, const char *offstr, off_t fileoff, struct |
229 | 229 |
unsigned int maxshift = 0; |
230 | 230 |
|
231 | 231 |
|
232 |
- if(offstr && desc != -1) { |
|
232 |
+ if(offstr) { |
|
233 | 233 |
offset = cli_caloff(offstr, info, desc, ftype, &ret, &maxshift); |
234 | 234 |
|
235 |
- if(ret == -1) { |
|
236 |
- cli_dbgmsg("cli_validatesig: Can't calculate offset for signature %s\n", virname); |
|
235 |
+ if(ret == -1) |
|
237 | 236 |
return 0; |
238 |
- } |
|
239 | 237 |
|
240 | 238 |
if(maxshift) { |
241 | 239 |
if((fileoff < offset) || (fileoff > offset + (off_t) maxshift)) { |
... | ... |
@@ -123,7 +123,7 @@ struct cli_target_info { |
123 | 123 |
int8_t status; /* 0 == not initialised, 1 == initialised OK, -1 == error */ |
124 | 124 |
}; |
125 | 125 |
|
126 |
-int cli_scanbuff(const unsigned char *buffer, uint32_t length, cli_ctx *ctx, cli_file_t ftype, struct cli_ac_data **acdata); |
|
126 |
+int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset, cli_ctx *ctx, cli_file_t ftype, struct cli_ac_data **acdata); |
|
127 | 127 |
|
128 | 128 |
int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode); |
129 | 129 |
|
... | ... |
@@ -1043,7 +1043,7 @@ save_text(cli_ctx *ctx, const char *dir, const char *start, size_t len) |
1043 | 1043 |
* in this way. It gets the "filetype" wrong and then |
1044 | 1044 |
* doesn't scan correctly |
1045 | 1045 |
*/ |
1046 |
- if(cli_scanbuff((char *)p, len, ctx, CL_TYPE_BINARY_DATA, NULL) == CL_VIRUS) { |
|
1046 |
+ if(cli_scanbuff((char *)p, len, 0, ctx, CL_TYPE_BINARY_DATA, NULL) == CL_VIRUS) { |
|
1047 | 1047 |
cli_dbgmsg("save_text: found %s\n", *ctx->virname); |
1048 | 1048 |
return CL_VIRUS; |
1049 | 1049 |
} |
... | ... |
@@ -780,7 +780,7 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U) |
780 | 780 |
/* cli_dbgmsg("Project content:\n%s", data); */ |
781 | 781 |
if(ctx->scanned) |
782 | 782 |
*ctx->scanned += data_len / CL_COUNT_PRECISION; |
783 |
- if(cli_scanbuff(data, data_len, ctx, CL_TYPE_MSOLE2, NULL) == CL_VIRUS) { |
|
783 |
+ if(cli_scanbuff(data, data_len, 0, ctx, CL_TYPE_MSOLE2, NULL) == CL_VIRUS) { |
|
784 | 784 |
free(data); |
785 | 785 |
ret = CL_VIRUS; |
786 | 786 |
break; |
... | ... |
@@ -838,7 +838,7 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U) |
838 | 838 |
cli_dbgmsg("Project content:\n%s", data); |
839 | 839 |
if(ctx->scanned) |
840 | 840 |
*ctx->scanned += vba_project->length[i] / CL_COUNT_PRECISION; |
841 |
- if(cli_scanbuff(data, vba_project->length[i], ctx, CL_TYPE_MSOLE2, NULL) == CL_VIRUS) { |
|
841 |
+ if(cli_scanbuff(data, vba_project->length[i], 0, ctx, CL_TYPE_MSOLE2, NULL) == CL_VIRUS) { |
|
842 | 842 |
free(data); |
843 | 843 |
ret = CL_VIRUS; |
844 | 844 |
break; |
... | ... |
@@ -1012,7 +1012,7 @@ static int cli_scanscript(int desc, cli_ctx *ctx) |
1012 | 1012 |
int ofd = -1, ret; |
1013 | 1013 |
ssize_t nread; |
1014 | 1014 |
const struct cli_matcher *troot = ctx->engine->root[7]; |
1015 |
- uint32_t maxpatlen = troot ? troot->maxpatlen : 0; |
|
1015 |
+ uint32_t maxpatlen = troot ? troot->maxpatlen : 0, offset = 0; |
|
1016 | 1016 |
struct cli_matcher *groot = ctx->engine->root[0]; |
1017 | 1017 |
struct cli_ac_data gmdata, tmdata; |
1018 | 1018 |
struct cli_ac_data *mdata[2]; |
... | ... |
@@ -1068,10 +1068,13 @@ static int cli_scanscript(int desc, cli_ctx *ctx) |
1068 | 1068 |
/* we can continue to scan in memory */ |
1069 | 1069 |
} |
1070 | 1070 |
/* when we flush the buffer also scan */ |
1071 |
- if(cli_scanbuff(state.out, state.out_pos, ctx, CL_TYPE_TEXT_ASCII, mdata) == CL_VIRUS) { |
|
1071 |
+ if(cli_scanbuff(state.out, state.out_pos, offset, ctx, CL_TYPE_TEXT_ASCII, mdata) == CL_VIRUS) { |
|
1072 | 1072 |
ret = CL_VIRUS; |
1073 | 1073 |
break; |
1074 | 1074 |
} |
1075 |
+ if(ctx->scanned) |
|
1076 |
+ *ctx->scanned += state.out_pos / CL_COUNT_PRECISION; |
|
1077 |
+ offset += state.out_pos; |
|
1075 | 1078 |
/* carry over maxpatlen from previous buffer */ |
1076 | 1079 |
if (state.out_pos > maxpatlen) |
1077 | 1080 |
memmove(state.out, state.out + state.out_pos - maxpatlen, maxpatlen); |