mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2026-05-18 21:40:17 -04:00
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:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)" : "");
|
||||
|
||||
Reference in New Issue
Block a user