pcre: added disabling mechanism to metas and matcher

dconf: added field specific for pcre features
dconf: added overall support dconf for pcre
This commit is contained in:
Kevin Lin
2014-09-15 18:10:11 -04:00
parent effb4f51fc
commit 82fa5ba043
6 changed files with 77 additions and 14 deletions

View File

@@ -136,6 +136,8 @@ static struct dconf_module modules[] = {
{ "STATS", "DISABLED", DCONF_STATS_DISABLED, 0 },
{ "STATS", "PESECTION DISABLED", DCONF_STATS_PE_SECTION_DISABLED, 0 },
{ "PCRE", "SUPPORT", PCRE_CONF_SUPPORT, 1 },
{ NULL, NULL, 0, 0 }
};
@@ -189,6 +191,9 @@ struct cli_dconf *cli_dconf_init(void)
} else if (!strcmp(modules[i].mname, "STATS")) {
if (modules[i].state)
dconf->stats |= modules[i].bflag;
} else if (!strcmp(modules[i].mname, "PCRE")) {
if (modules[i].state)
dconf->pcre |= modules[i].bflag;
}
}
@@ -198,7 +203,7 @@ struct cli_dconf *cli_dconf_init(void)
void cli_dconf_print(struct cli_dconf *dconf)
{
unsigned int pe = 0, elf = 0, macho = 0, arch = 0, doc = 0, mail = 0;
unsigned int other = 0, phishing = 0, i, bytecode=0, stats=0;
unsigned int other = 0, phishing = 0, i, bytecode=0, stats=0, pcre=0;
cli_dbgmsg("Dynamic engine configuration settings:\n");
@@ -292,7 +297,17 @@ void cli_dconf_print(struct cli_dconf *dconf)
}
if (dconf->stats)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->stats & modules[i].bflag) ? "On" : "** Off **");
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->stats & modules[i].bflag) ? "On" : "** Off **");
else
continue;
} else if (!strcmp(modules[i].mname, "PCRE")) {
if (!pcre) {
cli_dbgmsg("Module PCRE %s\n", dconf->pcre ? "On" : "Off");
stats = 1;
}
if (dconf->pcre)
cli_dbgmsg(" * Submodule %10s:\t%s\n", modules[i].sname, (dconf->pcre & modules[i].bflag) ? "On" : "** Off **");
else
continue;
}
@@ -437,6 +452,15 @@ int cli_dconf_load(FILE *fs, struct cl_engine *engine, unsigned int options, str
break;
}
}
if(!strncmp(buffer, "PCRE:", 5) && chkflevel(buffer, 2)) {
if(sscanf(buffer + 5, "0x%x", &val) == 1) {
engine->dconf->pcre = val;
} else {
ret = CL_EMALFDB;
break;
}
}
}
if(ret) {

View File

@@ -42,6 +42,7 @@ struct cli_dconf {
uint32_t phishing;
uint32_t bytecode;
uint32_t stats;
uint32_t pcre;
};
/* PE flags */
@@ -129,6 +130,9 @@ struct cli_dconf {
#define DCONF_STATS_DISABLED 0x1
#define DCONF_STATS_PE_SECTION_DISABLED 0x2
/* PCRE flags */
#define PCRE_CONF_SUPPORT 0x1
#define BYTECODE_ENGINE_MASK (BYTECODE_INTERPRETER | BYTECODE_JIT_X86 | BYTECODE_JIT_PPC | BYTECODE_JIT_ARM)
#ifdef USE_MPOOL

View File

@@ -29,6 +29,7 @@
#if HAVE_PCRE
#include "clamav.h"
#include "cltypes.h"
#include "dconf.h"
#include "others.h"
#include "matcher.h"
#include "matcher-pcre.h"
@@ -142,7 +143,8 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *trigger, const char *
}
opt++;
}
/* TODO - better debug? */
/*
cli_dbgmsg("PCRE_CASELESS %08x\n", PCRE_CASELESS);
cli_dbgmsg("PCRE_DOTALL %08x\n", PCRE_DOTALL);
cli_dbgmsg("PCRE_MULTILINE %08x\n", PCRE_MULTILINE);
@@ -153,6 +155,7 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *trigger, const char *
cli_dbgmsg("PCRE_UNGREEDY %08x\n", PCRE_UNGREEDY);
cli_dbgmsg("PCRE_OPTIONS %08x\n", pm->pdata.options);
*/
}
/* add pcre data to root after reallocation */
@@ -181,15 +184,27 @@ int cli_pcre_addpatt(struct cli_matcher *root, const char *trigger, const char *
return CL_SUCCESS;
}
int cli_pcre_build(struct cli_matcher *root, long long unsigned match_limit, long long unsigned recmatch_limit)
int cli_pcre_build(struct cli_matcher *root, long long unsigned match_limit, long long unsigned recmatch_limit, const struct cli_dconf *dconf)
{
unsigned int i;
int ret;
struct cli_pcre_meta *pm = NULL;
int disable_all = !(dconf->pcre & PCRE_CONF_SUPPORT);
for (i = 0; i < root->pcre_metas; ++i) {
pm = root->pcre_metatable[i];
/* for safety, disable all pcre */
if (disable_all) {
pm->flags |= CLI_PCRE_DISABLED;
continue;
}
if (pm->flags & CLI_PCRE_DISABLED) {
cli_dbgmsg("cli_pcre_build: Skip compiling regex: %s (disabled)\n", pm->pdata.expression);
continue;
}
if (!pm) {
cli_errmsg("cli_pcre_build: metadata for pcre %d is missing\n", i);
return CL_ENULLARG;
@@ -204,7 +219,8 @@ int cli_pcre_build(struct cli_matcher *root, long long unsigned match_limit, lon
/* parse the regex, no options override *wink* */
if ((ret = cli_pcre_compile(&(pm->pdata), match_limit, recmatch_limit, 0, 0)) != CL_SUCCESS) {
cli_errmsg("cli_pcre_build: failed to parse pcre regex\n");
cli_errmsg("cli_pcre_build: failed to build pcre regex\n");
pm->flags |= CLI_PCRE_DISABLED; /* disable the pcre */
return ret;
}
}
@@ -212,7 +228,7 @@ int cli_pcre_build(struct cli_matcher *root, long long unsigned match_limit, lon
return CL_SUCCESS;
}
int cli_pcre_recaloff(struct cli_matcher *root, struct cli_pcre_off *data, struct cli_target_info *info)
int cli_pcre_recaloff(struct cli_matcher *root, struct cli_pcre_off *data, struct cli_target_info *info, cli_ctx *ctx)
{
/* TANGENT: maintain relative offset data in cli_ac_data? */
int ret;
@@ -223,7 +239,8 @@ int cli_pcre_recaloff(struct cli_matcher *root, struct cli_pcre_off *data, struc
if (!data) {
return CL_ENULLARG;
}
if (!root || !root->pcre_metatable || !info) {
if (!(ctx->dconf->pcre & PCRE_CONF_SUPPORT) || !root || !root->pcre_metatable || !info) {
data->shift = NULL;
data->offset = NULL;
return CL_SUCCESS;
@@ -246,6 +263,13 @@ int cli_pcre_recaloff(struct cli_matcher *root, struct cli_pcre_off *data, struc
for (i = 0; i < root->pcre_metas; ++i) {
pm = root->pcre_metatable[i];
/* skip broken pcres, not getting executed always */
if (pm->flags & CLI_PCRE_DISABLED) {
data->offset[i] = CLI_OFF_NONE;
data->shift[i] = CLI_OFF_NONE;
continue;
}
if (pm->offdata[0] == CLI_OFF_ANY) {
data->offset[i] = 0;
data->shift[i] = 0;
@@ -269,6 +293,8 @@ int cli_pcre_recaloff(struct cli_matcher *root, struct cli_pcre_off *data, struc
data->shift[i] = endoff-(data->offset[i]);
}
/* TODO: better debug? */
/*
cli_dbgmsg("info->fsize: %lu\n", (long unsigned)info->fsize);
if (pm->offdata[0]>9)
cli_dbgmsg("offdata[0] type: %x\n", pm->offdata[0]);
@@ -279,7 +305,7 @@ int cli_pcre_recaloff(struct cli_matcher *root, struct cli_pcre_off *data, struc
cli_dbgmsg("offdata[3] section: %u\n", pm->offdata[3]);
cli_dbgmsg("offset_min: %u\n", pm->offset_min);
cli_dbgmsg("offset_max: %u\n", pm->offset_max);
*/
}
for (i = 0; i < root->pcre_metas; ++i) {
@@ -360,7 +386,7 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const struct
uint32_t global, encompass;
int rc, offset, ovector[OVECCOUNT];
if (!root->pcre_metatable) {
if (!(ctx->dconf->pcre & PCRE_CONF_SUPPORT) || (!root->pcre_metatable)) {
return CL_SUCCESS;
}
@@ -368,6 +394,12 @@ int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const struct
pm = root->pcre_metatable[i];
pd = &(pm->pdata);
/* skip checking and running disabled pcres */
if (pm->flags & CLI_PCRE_DISABLED) {
cli_dbgmsg("cli_pcre_scanbuf: skipping disabled regex /%s/\n", pd->expression);
continue;
}
/* check the evaluation of the trigger */
if (pm->lsigid[0]) {
cli_dbgmsg("cli_pcre_scanbuf: checking %s; running regex /%s/\n", pm->trigger, pd->expression);

View File

@@ -33,6 +33,7 @@
#include <sys/types.h>
#include "cltypes.h"
#include "dconf.h"
#include "mpool.h"
#include "regex_pcre.h"
@@ -40,6 +41,8 @@
#define CLI_PCRE_GLOBAL 0x00000001 /* g */
#define CLI_PCRE_ENCOMPASS 0x00000002 /* e */
#define CLI_PCRE_DISABLED 0x80000000 /* used for dconf or fail to build */
struct cli_pcre_meta {
char *trigger;
uint32_t lsigid[3]; /* 0=valid, 1=lsigid, 2=subsigid */
@@ -57,8 +60,8 @@ struct cli_pcre_off {
};
int cli_pcre_addpatt(struct cli_matcher *root, const char *trigger, const char *pattern, const char *cflags, const char *offset, const uint32_t *lsigid);
int cli_pcre_build(struct cli_matcher *root, long long unsigned match_limit, long long unsigned recmatch_limit);
int cli_pcre_recaloff(struct cli_matcher *root, struct cli_pcre_off *data, struct cli_target_info *info);
int cli_pcre_build(struct cli_matcher *root, long long unsigned match_limit, long long unsigned recmatch_limit, const struct cli_dconf *dconf);
int cli_pcre_recaloff(struct cli_matcher *root, struct cli_pcre_off *data, struct cli_target_info *info, cli_ctx *ctx);
void cli_pcre_freeoff(struct cli_pcre_off *data);
int cli_pcre_scanbuf(const unsigned char *buffer, uint32_t length, const struct cli_matcher *root, struct cli_ac_data *mdata, struct cli_ac_result **res, const struct cli_pcre_off *data, cli_ctx *ctx);
void cli_pcre_freemeta(struct cli_pcre_meta *pm);

View File

@@ -967,7 +967,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
struct cli_pcre_off poff;
/* calculate the relative offsets */
ret = cli_pcre_recaloff(groot, &poff, &info);
ret = cli_pcre_recaloff(groot, &poff, &info, ctx);
if (ret != CL_SUCCESS) {
cli_ac_freedata(&gdata);
cli_ac_freedata(&tdata);
@@ -1009,7 +1009,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
struct cli_pcre_off poff;
/* calculate the relative offsets */
ret = cli_pcre_recaloff(troot, &poff, &info);
ret = cli_pcre_recaloff(troot, &poff, &info, ctx);
if (ret != CL_SUCCESS) {
cli_ac_freedata(&gdata);
cli_ac_freedata(&tdata);

View File

@@ -3505,7 +3505,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)))
if((ret = cli_pcre_build(root, engine->pcre_match_limit, engine->pcre_recmatch_limit, engine->dconf)))
return ret;
cli_dbgmsg("Matcher[%u]: %s: AC sigs: %u (reloff: %u, absoff: %u) BM sigs: %u (reloff: %u, absoff: %u) PCREs: %u (reloff: %u, absoff: %u) maxpatlen %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->pcre_metas, root->pcre_reloff_num, root->pcre_absoff_num, root->maxpatlen, root->ac_only ? "(ac_only mode)" : "");