pcre: enforced content match trigger

matcher-pcre: renamed old functions to be unconditonal pcres
remotes/push_mirror/swebb/clamyara^2
Kevin Lin 11 years ago
parent 538e71a190
commit a84ef0ccd8
  1. 24
      libclamav/matcher-pcre.c
  2. 8
      libclamav/matcher-pcre.h
  3. 6
      libclamav/matcher.c
  4. 63
      libclamav/readdb.c

@ -36,7 +36,7 @@
//int pcre_add_pattern(struct pcre_matcher *matcher, const char *pattern, int options)
/* TODO - memory cleanup on error */
int cli_pcre_addpatt(struct cli_matcher *root, const char *pattern, const uint32_t *lsigid)
int cli_pcre_adducondpatt(struct cli_matcher *root, const char *pattern, const uint32_t *lsigid)
{
struct cli_pcre_data **newdata, *pd;
struct cli_pcre_refentry **newreftable, *refe;
@ -44,7 +44,7 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *pattern, const uint32
int ret = CL_SUCCESS;
if (!root || !pattern) {
cli_errmsg("pcre_add_pattern: NULL root or NULL pattern\n");
cli_errmsg("pcre_adducondpatt: NULL root or NULL pattern\n");
return CL_ENULLARG;
}
@ -54,7 +54,7 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *pattern, const uint32
/* allocating entries */
pd = (struct cli_pcre_data *)mpool_calloc(root->mempool, 1, sizeof(*pd));
if (!pd) {
cli_errmsg("cli_pcre_addpatt: Unable to allocate memory\n");
cli_errmsg("cli_pcre_adducondpatt: Unable to allocate memory\n");
return CL_EMEM;
}
@ -62,7 +62,7 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *pattern, const uint32
refe = (struct cli_pcre_refentry *)cli_calloc(1, sizeof(struct cli_pcre_refentry));
if (!refe) {
cli_errmsg("cli_pcre_addpatt: failed to allocate space\n");
cli_errmsg("cli_pcre_adducondpatt: failed to allocate space\n");
return CL_EMEM;
}
@ -76,18 +76,18 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *pattern, const uint32
newdata = (struct cli_pcre_data **)mpool_realloc(root->mempool, root->all_pcres,
new_numpcres * sizeof(struct cli_pcre_data *));
if (!newdata) {
cli_errmsg("cli_pcre_addpatt: Unable to allocate memory\n");
cli_errmsg("cli_pcre_adducondpatt: Unable to allocate memory\n");
return CL_EMEM;
}
newreftable = (struct cli_pcre_refentry **)mpool_realloc(root->mempool, root->pcre_reftable,
new_numpcres * sizeof(struct cli_pcre_refentry *));
if (!newreftable) {
cli_errmsg("cli_pcre_addpatt: Unable to allocate memory\n");
cli_errmsg("cli_pcre_adducondpatt: Unable to allocate memory\n");
return CL_EMEM;
}
cli_dbgmsg("cli_pcre_addpatt: Adding /%s/ for subsig %d on engine->root[%d]\n",
cli_dbgmsg("cli_pcre_adducondpatt: Adding /%s/ as subsig %d for lsigid %d\n",
pattern, refe->lsigid[1], refe->lsigid[0]);
newdata[new_numpcres-1] = pd;
@ -100,7 +100,7 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *pattern, const uint32
return CL_SUCCESS;
}
int cli_pcre_build(struct cli_matcher *root, long long unsigned match_limit, long long unsigned recmatch_limit, unsigned int options)
int cli_pcre_ucondbuild(struct cli_matcher *root, long long unsigned match_limit, long long unsigned recmatch_limit, unsigned int options)
{
int i, ret;
struct cli_pcre_data *pd;
@ -108,10 +108,10 @@ int cli_pcre_build(struct cli_matcher *root, long long unsigned match_limit, lon
for (i = 0; i < root->num_pcres; ++i) {
pd = root->all_pcres[i];
cli_dbgmsg("cli_pcre_build: Compiling regex: %s\n", pd->expression);
cli_dbgmsg("cli_pcre_ucondbuild: Compiling regex: %s\n", pd->expression);
/* parse the regex - TODO: set start_offset */
if ((ret = cli_pcre_compile(pd, match_limit, recmatch_limit, options)) != CL_SUCCESS) {
cli_errmsg("cli_pcre_build: failed to parse pcre regex\n");
cli_errmsg("cli_pcre_ucondbuild: failed to parse pcre regex\n");
return ret;
}
}
@ -168,7 +168,7 @@ static inline void lsig_sub_matched(const struct cli_matcher *root, struct cli_a
}
}
int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const struct cli_matcher *root, struct cli_ac_data *mdata, cli_ctx *ctx)
int cli_pcre_ucondscanbuf(const unsigned char *buffer, uint32_t length, const struct cli_matcher *root, struct cli_ac_data *mdata, cli_ctx *ctx)
{
struct cli_pcre_data **data = root->all_pcres, *pd;
struct cli_pcre_refentry **reftable = root->pcre_reftable, *refe;
@ -205,7 +205,7 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const struct
return CL_SUCCESS;
}
void cli_pcre_free(struct cli_matcher *root)
void cli_pcre_ucondfree(struct cli_matcher *root)
{
uint32_t i;
struct cli_pcre_data *pd;

@ -41,9 +41,9 @@ struct cli_pcre_refentry {
struct cli_pcre_refentry *next;
};
int cli_pcre_addpatt(struct cli_matcher *root, const char *pattern, const uint32_t *lsigid);
int cli_pcre_build(struct cli_matcher *root, long long unsigned match_limit, long long unsigned recmatch_limit, unsigned int options);
int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const struct cli_matcher *root, struct cli_ac_data *mdata, cli_ctx *ctx);
void cli_pcre_free(struct cli_matcher *root);
int cli_pcre_adducondpatt(struct cli_matcher *root, const char *pattern, const uint32_t *lsigid);
int cli_pcre_uncondbuild(struct cli_matcher *root, long long unsigned match_limit, long long unsigned recmatch_limit, unsigned int options);
int cli_pcre_ucondscanbuf(const unsigned char *buffer, uint32_t length, const struct cli_matcher *root, struct cli_ac_data *mdata, cli_ctx *ctx);
void cli_pcre_ucondfree(struct cli_matcher *root);
#endif /* HAVE_PCRE */
#endif /*__MATCHER_PCRE_H*/

@ -868,11 +868,11 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
}
}
/* **temporary** TODO - find way to save pcre state over separated buffers */
/* cannot save pcre execution state without possible evasion; must scan entire buffer */
#if HAVE_PCRE
if((buff = fmap_need_off_once(map, offset, map->len))) {
if (!ftonly) {
ret = cli_pcre_scanbuf(buff, map->len, groot, &gdata, ctx);
ret = cli_pcre_ucondscanbuf(buff, map->len, groot, &gdata, ctx);
if((ret == CL_VIRUS && !SCAN_ALL) || ret == CL_EMEM) {
cli_ac_freedata(&gdata);
cli_ac_freedata(&tdata);
@ -890,7 +890,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
}
}
if (troot) {
ret = cli_pcre_scanbuf(buff, map->len, troot, &tdata, ctx);
ret = cli_pcre_ucondscanbuf(buff, map->len, troot, &tdata, ctx);
if((ret == CL_VIRUS && !SCAN_ALL) || ret == CL_EMEM) {
if(!ftonly)
cli_ac_freedata(&gdata);

@ -167,21 +167,24 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex
}
if ((wild = strchr(hexsig, '/'))) {
#if HAVE_PCRE
char *trigger, *regex;
size_t tlen = wild-hexsig;
size_t rlen = hexlen-tlen-2;
/* ^offset:content-match/regex/options$ */
char *trigger, *regex, *regex_end;
size_t tlen = wild-hexsig, rlen;
if (hexsig[hexlen-1] != '/') {
cli_errmsg("cli_parseadd(): missing terminator /\n");
/* check for trigger */
if (!tlen) {
cli_dbgmsg("cli_parseadd(): cannot add pcre without content match trigger\n");
return CL_EMALFDB;
}
if (!tlen) {
cli_dbgmsg("cli_parseadd(): no trigger statement\n");
/* kill sig on lack of trigger? */
}
/* locate end of regex for options start, TODO: options */
if ((regex_end = strchr(wild+1, '/')) == NULL) {
cli_errmsg("cli_parseadd(): missing terminator /\n");
return CL_EMALFDB;
}
rlen = regex_end-wild-1;
/* TODO: get the trigger statement and parse */
/* get the trigger statement */
trigger = cli_calloc(tlen+1, sizeof(char));
if (!trigger) {
cli_errmsg("cli_parseadd(): cannot allocate memory\n");
@ -190,27 +193,29 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex
strncpy(trigger, hexsig, tlen);
trigger[tlen] = '\0';
if (strncmp(trigger, PCRE_BYPASS, tlen)) {
cli_errmsg("cli_parseadd(): cannot handle trigger statement atm\n");
return CL_EMALFDB;
}
/* if trigger is PCRE_BYPASS, add to unconditionally run pcres */
if (!strncmp(trigger, PCRE_BYPASS, tlen)) {
cli_dbgmsg("unconditional pcre regex detected: %s\n", wild);
free(trigger);
cli_dbgmsg("pcre regex detected: %s on trigger: %s\n", wild, trigger);
free(trigger);
regex = cli_calloc(rlen+1, sizeof(char));
if (!regex) {
cli_errmsg("cli_parseadd(): cannot allocate memory\n");
return CL_EMEM;
}
strncpy(regex, hexsig+tlen+1, rlen);
regex[rlen] = '\0';
/* TODO: add the regex to the regex struct */
regex = cli_calloc(rlen+1, sizeof(char));
if (!regex) {
cli_errmsg("cli_parseadd(): cannot allocate memory\n");
return CL_EMEM;
ret = cli_pcre_adducondpatt(root, regex, lsigid);
free(regex);
return ret;
}
strncpy(regex, hexsig+tlen+1, rlen);
regex[rlen] = '\0';
ret = cli_pcre_addpatt(root, regex, lsigid);
free(regex);
/* normal trigger */
cli_dbgmsg("pcre regex detected: %s on trigger: %s\n", wild, trigger);
return ret;
exit(0);
#else
cli_errmsg("cli_parseadd(): cannot parse PCRE subsig ithout PCRE support\n");
return CL_EPARSE;
@ -223,7 +228,7 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex
return CL_EMEM;
strncpy(hexcpy, hexsig, wild - hexsig);
for(i = 0; i < (unsigned int) range; i++)
strcat(hexcpy, "??");
strcat(hexcpy, "??");
if(!(wild = strchr(wild, '}'))) {
cli_errmsg("cli_parse_add(): Problem adding signature: missing bracket\n");
free(hexcpy);
@ -3362,7 +3367,7 @@ int cl_engine_free(struct cl_engine *engine)
mpool_free(engine->mempool, root->ac_lsigtable);
}
#if HAVE_PCRE
cli_pcre_free(root);
cli_pcre_ucondfree(root);
#endif /* HAVE_PCRE */
mpool_free(engine->mempool, root);
}
@ -3489,7 +3494,7 @@ int cl_engine_compile(struct cl_engine *engine)
if((ret = cli_ac_buildtrie(root)))
return ret;
#if HAVE_PCRE
if((ret = cli_pcre_build(root, engine->pcre_match_limit, engine->pcre_recmatch_limit, 0)))
if((ret = cli_pcre_ucondbuild(root, engine->pcre_match_limit, engine->pcre_recmatch_limit, 0)))
return ret;
cli_dbgmsg("Matcher[%u]: %s: AC sigs: %u (reloff: %u, absoff: %u) BM sigs: %u (reloff: %u, absoff: %u) maxpatlen %u PCREs: %u %s\n", i, cli_mtargets[i].name, root->ac_patterns, root->ac_reloff_num, root->ac_absoff_num, root->bm_patterns, root->bm_reloff_num, root->bm_absoff_num, root->maxpatlen, root->num_pcres, root->ac_only ? "(ac_only mode)" : "");

Loading…
Cancel
Save