diff --git a/libclamav/clamav.h b/libclamav/clamav.h index 0564aeb04..542c238ea 100644 --- a/libclamav/clamav.h +++ b/libclamav/clamav.h @@ -104,80 +104,23 @@ extern "C" /* recommended scan settings */ #define CL_SCAN_STDOPT (CL_SCAN_ARCHIVE | CL_SCAN_MAIL | CL_SCAN_OLE2 | CL_SCAN_PDF | CL_SCAN_HTML | CL_SCAN_PE | CL_SCAN_ALGORITHMIC | CL_SCAN_ELF) -/* aliases for backward compatibility */ -#define CL_RAW CL_SCAN_RAW -#define CL_ARCHIVE CL_SCAN_ARCHIVE -#define CL_MAIL CL_SCAN_MAIL -#define CL_OLE2 CL_SCAN_OLE2 -#define CL_ENCRYPTED CL_SCAN_BLOCKENCRYPTED -#define cl_node cl_engine -#define cl_perror cl_strerror +struct cl_engine; -struct cl_engine { - unsigned int refcount; /* reference counter */ - unsigned short sdb; - unsigned int dboptions; - unsigned int dbversion[2]; - /* Roots table */ - void **root; +/* NEW API CALLS: */ - /* B-M matcher for standard MD5 sigs */ - void *md5_hdb; +#define CL_INIT_DEFAULT 0x0 +extern int cl_init(unsigned int options); - /* B-M matcher for MD5 sigs for PE sections */ - void *md5_mdb; +#define CL_ENGINE_DEFAULT 0x0 +extern struct cl_engine *cl_engine_new(unsigned int options); - /* B-M matcher for whitelist db */ - void *md5_fp; +extern int cl_engine_compile(struct cl_engine *engine); - /* Zip metadata */ - void *zip_mlist; +extern struct cl_engine *cl_engine_dup(struct cl_engine *engine); - /* RAR metadata */ - void *rar_mlist; +extern int cl_engine_free(struct cl_engine *engine); - /* Phishing .pdb and .wdb databases*/ - void *whitelist_matcher; - void *domainlist_matcher; - void *phishcheck; - - /* Dynamic configuration */ - void *dconf; - - /* Filetype definitions */ - void *ftypes; - - /* Ignored signatures */ - void *ignored; - - /* PUA categories (to be included or excluded) */ - char *pua_cats; - - /* Used for memory pools */ - void *mempool; -}; - -struct cl_limits { - unsigned long int maxscansize; /* during the scanning of archives this size - * will never be exceeded - */ - unsigned long int maxfilesize; /* compressed files will only be decompressed - * and scanned up to this size - */ - unsigned int maxreclevel; /* maximum recursion level for archives */ - unsigned int maxfiles; /* maximum number of files to be scanned - * within a single archive - */ - unsigned short archivememlim; /* limit memory usage for some unpackers */ - - /* This is for structured data detection. You can set the minimum - * number of occurences of an CC# or SSN before the system will - * generate a notification. - */ - unsigned int min_cc_count; - unsigned int min_ssn_count; -}; struct cl_stat { char *dir; @@ -198,18 +141,15 @@ struct cl_cvd { /* field no. */ }; /* file scanning */ -extern 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); +extern int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options); -extern int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options); +extern int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options); /* database handling */ extern int cl_load(const char *path, struct cl_engine **engine, unsigned int *signo, unsigned int options); extern const char *cl_retdbdir(void); /* engine handling */ -extern int cl_build(struct cl_engine *engine); -extern struct cl_engine *cl_dup(struct cl_engine *engine); -extern void cl_free(struct cl_engine *engine); /* CVD */ extern struct cl_cvd *cl_cvdhead(const char *file); diff --git a/libclamav/dconf.c b/libclamav/dconf.c index f03799171..79b0922b1 100644 --- a/libclamav/dconf.c +++ b/libclamav/dconf.c @@ -280,11 +280,6 @@ int cli_dconf_load(FILE *fs, struct cl_engine **engine, unsigned int options, st uint32_t val; - if((ret = cli_initengine(engine, options))) { - cl_free(*engine); - return ret; - } - dconf = (struct cli_dconf *) (*engine)->dconf; while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) { @@ -357,7 +352,7 @@ int cli_dconf_load(FILE *fs, struct cl_engine **engine, unsigned int options, st if(ret) { cli_errmsg("Problem parsing configuration file at line %u\n", line); - cl_free(*engine); + cl_engine_free(*engine); return ret; } diff --git a/libclamav/libclamav.map b/libclamav/libclamav.map index d29d08d1b..7aceffee9 100644 --- a/libclamav/libclamav.map +++ b/libclamav/libclamav.map @@ -1,16 +1,16 @@ CLAMAV_PUBLIC { global: - cl_build; cl_cvdfree; cl_cvdhead; cl_cvdparse; cl_cvdverify; cl_debug; - cl_dup; - cl_free; + cl_init; + cl_engine_new; + cl_engine_compile; + cl_engine_dup; + cl_engine_free; cl_load; - cl_loaddb; - cl_loaddbdir; cl_retdbdir; cl_retflevel; cl_retver; diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c index ec50dce60..d4e138584 100644 --- a/libclamav/matcher-ac.c +++ b/libclamav/matcher-ac.c @@ -841,7 +841,7 @@ inline static int ac_addtype(struct cli_matched_type **list, cli_file_t type, of if(type == CL_TYPE_ZIPSFX) { - if(*list && ctx && ctx->limits && ctx->limits->maxfiles && (*list)->cnt > ctx->limits->maxfiles) + if(*list && ctx && ctx->engine->maxfiles && (*list)->cnt > ctx->engine->maxfiles) return CL_SUCCESS; } else if(*list && (*list)->cnt >= MAX_EMBEDDED_OBJ) return CL_SUCCESS; diff --git a/libclamav/mbox.c b/libclamav/mbox.c index 429cf84c5..49063dc55 100644 --- a/libclamav/mbox.c +++ b/libclamav/mbox.c @@ -1990,30 +1990,29 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re message *mainMessage = messageIn; fileblob *fb; bool infected = FALSE; - const int doPhishingScan = mctx->ctx->engine->dboptions&CL_DB_PHISHING_URLS && (DCONF_PHISHING & PHISHING_CONF_ENGINE); - const struct cl_limits *limits = mctx->ctx->limits; + const struct cl_engine *engine = mctx->ctx->engine; + const int doPhishingScan = engine->dboptions&CL_DB_PHISHING_URLS && (DCONF_PHISHING & PHISHING_CONF_ENGINE); cli_dbgmsg("in parseEmailBody, %u files saved so far\n", mctx->files); - if(limits) { /* FIXMELIMITS: this should be better integrated */ - if(limits->maxreclevel) - /* - * This is approximate - */ - if(recursion_level > limits->maxreclevel) { + /* FIXMELIMITS: this should be better integrated */ + if(engine->maxreclevel) + /* + * This is approximate + */ + if(recursion_level > engine->maxreclevel) { cli_dbgmsg("parseEmailBody: hit maximum recursion level (%u)\n", recursion_level); return MAXREC; } - if(limits->maxfiles && (mctx->files >= limits->maxfiles)) { - /* - * FIXME: This is only approx - it may have already - * been exceeded - */ - cli_dbgmsg("parseEmailBody: number of files exceeded %u\n", limits->maxfiles); - return MAXFILES; - } + if(engine->maxfiles && (mctx->files >= engine->maxfiles)) { + /* + * FIXME: This is only approx - it may have already + * been exceeded + */ + cli_dbgmsg("parseEmailBody: number of files exceeded %u\n", engine->maxfiles); + return MAXFILES; } rc = OK; diff --git a/libclamav/ole2_extract.c b/libclamav/ole2_extract.c index e9fc731d8..248fea626 100644 --- a/libclamav/ole2_extract.c +++ b/libclamav/ole2_extract.c @@ -444,20 +444,19 @@ static int ole2_walk_property_tree(int fd, ole2_header_t *hdr, const char *dir, int32_t idx, current_block, i; char *dirname; int ret; - const struct cl_limits *limits = ctx ? ctx->limits : NULL; current_block = hdr->prop_start; if ((prop_index < 0) || (prop_index > (int32_t) hdr->max_block_no) || (rec_level > 100) || (*file_count > 100000)) { return CL_SUCCESS; } - if (limits && limits->maxfiles && (*file_count > limits->maxfiles)) { - cli_dbgmsg("OLE2: File limit reached (max: %d)\n", limits->maxfiles); + if (ctx && ctx->engine->maxfiles && (*file_count > ctx->engine->maxfiles)) { + cli_dbgmsg("OLE2: File limit reached (max: %d)\n", ctx->engine->maxfiles); return CL_SUCCESS; } - if (limits && limits->maxreclevel && (rec_level > limits->maxreclevel)) { - cli_dbgmsg("OLE2: Recursion limit reached (max: %d)\n", limits->maxreclevel); + if (ctx && ctx->engine->maxreclevel && (rec_level > ctx->engine->maxreclevel)) { + cli_dbgmsg("OLE2: Recursion limit reached (max: %d)\n", ctx->engine->maxreclevel); return CL_SUCCESS; } @@ -518,11 +517,11 @@ static int ole2_walk_property_tree(int fd, ole2_header_t *hdr, const char *dir, ) return ret; break; case 2: /* File */ - if (limits && limits->maxfiles && ctx->scannedfiles + *file_count > limits->maxfiles) { - cli_dbgmsg("OLE2: files limit reached (max: %u)\n", ctx->limits->maxfiles); + if (ctx && ctx->engine->maxfiles && ctx->scannedfiles + *file_count > ctx->engine->maxfiles) { + cli_dbgmsg("OLE2: files limit reached (max: %u)\n", ctx->engine->maxfiles); return CL_BREAK; } - if (!limits || !limits->maxfilesize || prop_block[idx].size <= limits->maxfilesize || prop_block[idx].size <= *scansize) { + if (!ctx || !ctx->engine->maxfilesize || prop_block[idx].size <= ctx->engine->maxfilesize || prop_block[idx].size <= *scansize) { (*file_count)++; *scansize-=prop_block[idx].size; if ((ret=handler(fd, hdr, &prop_block[idx], dir, ctx)) != CL_SUCCESS) @@ -897,9 +896,9 @@ int cli_ole2_extract(int fd, const char *dirname, cli_ctx *ctx, struct uniq **vb cli_dbgmsg("in cli_ole2_extract()\n"); - if (ctx && ctx->limits && ctx->limits->maxscansize) { - if (ctx->limits->maxscansize > ctx->scansize) - scansize = ctx->limits->maxscansize - ctx->scansize; + if (ctx && ctx->engine->maxscansize) { + if (ctx->engine->maxscansize > ctx->scansize) + scansize = ctx->engine->maxscansize - ctx->scansize; else return CL_EMAXSIZE; } else scansize = -1; diff --git a/libclamav/others.c b/libclamav/others.c index a1ac58e72..53a0f0797 100644 --- a/libclamav/others.c +++ b/libclamav/others.c @@ -197,35 +197,95 @@ const char *cl_strerror(int clerror) } } +int cl_init(unsigned int options) +{ + /* put dlopen() stuff here, etc. */ + return CL_SUCCESS; +} + +struct cl_engine *cl_engine_new(unsigned int options) +{ + struct cl_engine *new; + + + new = (struct cl_engine *) cli_calloc(1, sizeof(struct cl_engine)); + if(!new) { + cli_errmsg("cl_engine_new: Can't allocate memory for cl_engine\n"); + return NULL; + } + + /* Setup default limits */ + new->maxscansize = 104857600; + new->maxfilesize = 26214400; + new->maxreclevel = 16; + new->maxfiles = 10000; + new->min_cc_count = 3; + new->min_ssn_count = 3; + + new->refcount = 1; + +#ifdef USE_MPOOL + if(!(new->mempool = mp_create())) { + cli_errmsg("cl_engine_new: Can't allocate memory for memory pool\n"); + free(new); + return NULL; + } +#endif + + new->root = mp_calloc(new->mempool, CLI_MTARGETS, sizeof(struct cli_matcher *)); + if(!new->root) { + cli_errmsg("cl_engine_new: Can't allocate memory for roots\n"); +#ifdef USE_MPOOL + mp_destroy(new->mempool); +#endif + free(new); + return NULL; + } + + new->dconf = cli_mp_dconf_init(new->mempool); + if(!new->dconf) { + cli_errmsg("cl_engine_new: Can't initialize dynamic configuration\n"); + mp_free(new->mempool, new->root); +#ifdef USE_MPOOL + mp_destroy(new->mempool); +#endif + free(new); + return NULL; + } + + cli_dbgmsg("Initialized %s engine\n", cl_retver()); + return new; +} + int cli_checklimits(const char *who, cli_ctx *ctx, unsigned long need1, unsigned long need2, unsigned long need3) { int ret = CL_SUCCESS; unsigned long needed; /* if called without limits, go on, unpack, scan */ - if(!ctx || !ctx->limits) return CL_CLEAN; + if(!ctx) return CL_CLEAN; needed = (need1>need2)?need1:need2; needed = (needed>need3)?needed:need3; /* if we have global scan limits */ - if(needed && ctx->limits->maxscansize) { + if(needed && ctx->engine->maxscansize) { /* if the remaining scansize is too small... */ - if(ctx->limits->maxscansize-ctx->scansizeengine->maxscansize-ctx->scansizelimits->maxscansize, ctx->scansize, needed); + cli_dbgmsg("%s: scansize exceeded (initial: %lu, remaining: %lu, needed: %lu)\n", who, ctx->engine->maxscansize, ctx->scansize, needed); ret = CL_EMAXSIZE; } } /* if we have per-file size limits, and we are overlimit... */ - if(needed && ctx->limits->maxfilesize && ctx->limits->maxfilesizeengine->maxfilesize && ctx->engine->maxfilesizelimits->maxfilesize, needed); + cli_dbgmsg("%s: filesize exceeded (allowed: %lu, needed: %lu)\n", who, ctx->engine->maxfilesize, needed); ret = CL_EMAXSIZE; } - if(ctx->limits->maxfiles && ctx->scannedfiles>=ctx->limits->maxfiles) { - cli_dbgmsg("%s: files limit reached (max: %u)\n", who, ctx->limits->maxfiles); + if(ctx->engine->maxfiles && ctx->scannedfiles>=ctx->engine->maxfiles) { + cli_dbgmsg("%s: files limit reached (max: %u)\n", who, ctx->engine->maxfiles); return CL_EMAXFILES; } return ret; @@ -237,8 +297,8 @@ int cli_updatelimits(cli_ctx *ctx, unsigned long needed) { if (ret != CL_CLEAN) return ret; ctx->scannedfiles++; ctx->scansize+=needed; - if(ctx->scansize > ctx->limits->maxscansize) - ctx->scansize = ctx->limits->maxscansize; + if(ctx->scansize > ctx->engine->maxscansize) + ctx->scansize = ctx->engine->maxscansize; return CL_CLEAN; } diff --git a/libclamav/others.h b/libclamav/others.h index a3610addc..55534aae0 100644 --- a/libclamav/others.h +++ b/libclamav/others.h @@ -18,6 +18,8 @@ * MA 02110-1301, USA. */ +#include "matcher.h" + #ifndef __OTHERS_H_LC #define __OTHERS_H_LC @@ -81,7 +83,6 @@ typedef struct { unsigned long int *scanned; const struct cli_matcher *root; const struct cl_engine *engine; - const struct cl_limits *limits; unsigned long scansize; unsigned int options; unsigned int recursion; @@ -90,6 +91,69 @@ typedef struct { struct cli_dconf *dconf; } cli_ctx; +struct cl_engine { + uint32_t refcount; /* reference counter */ + uint32_t sdb; + uint32_t dboptions; + uint32_t dbversion[2]; + + /* Limits */ + uint64_t maxscansize; /* during the scanning of archives this size + * will never be exceeded + */ + uint64_t maxfilesize; /* compressed files will only be decompressed + * and scanned up to this size + */ + uint32_t maxreclevel; /* maximum recursion level for archives */ + uint32_t maxfiles; /* maximum number of files to be scanned + * within a single archive + */ + /* This is for structured data detection. You can set the minimum + * number of occurences of an CC# or SSN before the system will + * generate a notification. + */ + uint32_t min_cc_count; + uint32_t min_ssn_count; + + /* Roots table */ + struct cli_matcher **root; + + /* B-M matcher for standard MD5 sigs */ + struct cli_matcher *md5_hdb; + + /* B-M matcher for MD5 sigs for PE sections */ + struct cli_matcher *md5_mdb; + + /* B-M matcher for whitelist db */ + struct cli_matcher *md5_fp; + + /* Zip metadata */ + struct cli_meta_node *zip_mlist; + + /* RAR metadata */ + struct cli_meta_node *rar_mlist; + + /* Phishing .pdb and .wdb databases*/ + struct regex_matcher *whitelist_matcher; + struct regex_matcher *domainlist_matcher; + struct phishcheck *phishcheck; + + /* Dynamic configuration */ + struct cli_dconf *dconf; + + /* Filetype definitions */ + struct cli_ftype *ftypes; + + /* Ignored signatures */ + struct cli_ignored *ignored; + + /* PUA categories (to be included or excluded) */ + char *pua_cats; + + /* Used for memory pools */ + mp_t *mempool; +}; + #define SCAN_ARCHIVE (ctx->options & CL_SCAN_ARCHIVE) #define SCAN_MAIL (ctx->options & CL_SCAN_MAIL) #define SCAN_OLE2 (ctx->options & CL_SCAN_OLE2) diff --git a/libclamav/readdb.c b/libclamav/readdb.c index ada8be873..22de4579e 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -303,49 +303,6 @@ int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hex return CL_SUCCESS; } -int cli_initengine(struct cl_engine **engine, unsigned int options) -{ - int ret; - - - if(!*engine) { - cli_dbgmsg("Initializing the engine (%s)\n", cl_retver()); - - *engine = (struct cl_engine *) cli_calloc(1, sizeof(struct cl_engine)); - if(!*engine) { - cli_errmsg("Can't allocate memory for the engine structure!\n"); - return CL_EMEM; - } - - (*engine)->refcount = 1; - -#ifdef USE_MPOOL - if(!((*engine)->mempool = mp_create())) { - cli_errmsg("Can't allocate memory for memory pool!\n"); - return CL_EMEM; - } -#endif - (*engine)->root = mp_calloc((*engine)->mempool, CLI_MTARGETS, sizeof(struct cli_matcher *)); - if(!(*engine)->root) { - /* no need to free previously allocated memory here */ - cli_errmsg("Can't allocate memory for roots!\n"); - return CL_EMEM; - } - - (*engine)->dconf = cli_mp_dconf_init((*engine)->mempool); - if(!(*engine)->dconf) { - cli_errmsg("Can't initialize dynamic configuration\n"); - return CL_EMEM; - } - - if((options & CL_DB_PHISHING_URLS) && (((struct cli_dconf*) (*engine)->dconf)->phishing & PHISHING_CONF_ENGINE)) - if((ret = phishing_init(*engine))) - return ret; - } - - return CL_SUCCESS; -} - static int cli_initroots(struct cl_engine *engine, unsigned int options) { int i, ret; @@ -478,7 +435,7 @@ static int cli_loaddb(FILE *fs, struct cl_engine **engine, unsigned int *signo, if((ret = cli_initroots(*engine, options))) { - cl_free(*engine); + cl_engine_free(*engine); return ret; } @@ -512,13 +469,13 @@ static int cli_loaddb(FILE *fs, struct cl_engine **engine, unsigned int *signo, if(!line) { cli_errmsg("Empty database file\n"); - cl_free(*engine); + cl_engine_free(*engine); return CL_EMALFDB; } if(ret) { cli_errmsg("Problem parsing database at line %d\n", line); - cl_free(*engine); + cl_engine_free(*engine); return ret; } @@ -539,14 +496,14 @@ static int cli_loadwdb(FILE *fs, struct cl_engine **engine, unsigned int options if(!(*engine)->whitelist_matcher) { if((ret = init_whitelist(*engine))) { phishing_done(*engine); - cl_free(*engine); + cl_engine_free(*engine); return ret; } } if((ret = load_regex_matcher((*engine)->whitelist_matcher, fs, options, 1, dbio))) { phishing_done(*engine); - cl_free(*engine); + cl_engine_free(*engine); return ret; } @@ -564,14 +521,14 @@ static int cli_loadpdb(FILE *fs, struct cl_engine **engine, unsigned int options if(!(*engine)->domainlist_matcher) { if((ret = init_domainlist(*engine))) { phishing_done(*engine); - cl_free(*engine); + cl_engine_free(*engine); return ret; } } if((ret = load_regex_matcher((*engine)->domainlist_matcher, fs, options, 0, dbio))) { phishing_done(*engine); - cl_free(*engine); + cl_engine_free(*engine); return ret; } @@ -591,7 +548,7 @@ static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo, if((ret = cli_initroots(*engine, options))) { - cl_free(*engine); + cl_engine_free(*engine); return ret; } @@ -680,13 +637,13 @@ static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo, if(!line) { cli_errmsg("Empty database file\n"); - cl_free(*engine); + cl_engine_free(*engine); return CL_EMALFDB; } if(ret) { cli_errmsg("Problem parsing database at line %d\n", line); - cl_free(*engine); + cl_engine_free(*engine); return ret; } @@ -876,7 +833,7 @@ static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, if((ret = cli_initroots(*engine, options))) { - cl_free(*engine); + cl_engine_free(*engine); return ret; } @@ -1020,13 +977,13 @@ static int cli_loadldb(FILE *fs, struct cl_engine **engine, unsigned int *signo, if(!line) { cli_errmsg("Empty database file\n"); - cl_free(*engine); + cl_engine_free(*engine); return CL_EMALFDB; } if(ret) { cli_errmsg("Problem parsing database at line %u\n", line); - cl_free(*engine); + cl_engine_free(*engine); return ret; } @@ -1048,7 +1005,7 @@ static int cli_loadftm(FILE *fs, struct cl_engine **engine, unsigned int options if((ret = cli_initroots(*engine, options))) { - cl_free(*engine); + cl_engine_free(*engine); return ret; } @@ -1136,13 +1093,13 @@ static int cli_loadftm(FILE *fs, struct cl_engine **engine, unsigned int options if(ret) { cli_errmsg("Problem parsing %s filetype database at line %u\n", internal ? "built-in" : "external", line); - cl_free(*engine); + cl_engine_free(*engine); return ret; } if(!sigs) { cli_errmsg("Empty %s filetype database\n", internal ? "built-in" : "external"); - cl_free(*engine); + cl_engine_free(*engine); return CL_EMALFDB; } @@ -1164,7 +1121,7 @@ static int cli_loadign(FILE *fs, struct cl_engine **engine, unsigned int options if(!(ignored = (*engine)->ignored)) { ignored = (*engine)->ignored = (struct cli_ignored *) cli_calloc(sizeof(struct cli_ignored), 1); if(!ignored || hashset_init(&ignored->hs, 64, 50)) { - cl_free(*engine); + cl_engine_free(*engine); return CL_EMEM; } } @@ -1207,7 +1164,7 @@ static int cli_loadign(FILE *fs, struct cl_engine **engine, unsigned int options if(ret) { cli_errmsg("cli_loadign: Problem parsing database at line %u\n", line); - cl_free(*engine); + cl_engine_free(*engine); return ret; } @@ -1378,13 +1335,13 @@ static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo, if(!line) { cli_errmsg("cli_loadmd5: Empty database file\n"); - cl_free(*engine); + cl_engine_free(*engine); return CL_EMALFDB; } if(ret) { cli_errmsg("cli_loadmd5: Problem parsing database at line %u\n", line); - cl_free(*engine); + cl_engine_free(*engine); return ret; } @@ -1494,13 +1451,13 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, if(!line) { cli_errmsg("Empty database file\n"); - cl_free(*engine); + cl_engine_free(*engine); return CL_EMALFDB; } if(ret) { cli_errmsg("Problem parsing database at line %d\n", line); - cl_free(*engine); + cl_engine_free(*engine); return ret; } @@ -1632,16 +1589,6 @@ int cli_load(const char *filename, struct cl_engine **engine, unsigned int *sign return ret; } -int cl_loaddb(const char *filename, struct cl_engine **engine, unsigned int *signo) { - int ret; - - if((ret = cli_initengine(engine, CL_DB_STDOPT))) { - cl_free(*engine); - return ret; - } - return cli_load(filename, engine, signo, CL_DB_STDOPT, NULL); -} - static int cli_loaddbdir(const char *dirname, struct cl_engine **engine, unsigned int *signo, unsigned int options) { DIR *dd; @@ -1736,31 +1683,24 @@ static int cli_loaddbdir(const char *dirname, struct cl_engine **engine, unsigne return ret; } -int cl_loaddbdir(const char *dirname, struct cl_engine **engine, unsigned int *signo) { - int ret; - - if((ret = cli_initengine(engine, CL_DB_STDOPT))) { - cl_free(*engine); - return ret; - } - return cli_loaddbdir(dirname, engine, signo, CL_DB_STDOPT); -} - int cl_load(const char *path, struct cl_engine **engine, unsigned int *signo, unsigned int options) { struct stat sb; int ret; + if(!*engine) { + cli_errmsg("cl_load: engine == NULL\n"); + return CL_ENULLARG; + } if(stat(path, &sb) == -1) { cli_errmsg("cl_load(): Can't get status of %s\n", path); return CL_EIO; } - if((ret = cli_initengine(engine, options))) { - cl_free(*engine); - return ret; - } + if((options & CL_DB_PHISHING_URLS) && !(*engine)->phishcheck && (((struct cli_dconf *) (*engine)->dconf)->phishing & PHISHING_CONF_ENGINE)) + if((ret = phishing_init(*engine))) + return ret; (*engine)->dboptions = options; @@ -1984,7 +1924,7 @@ int cl_statfree(struct cl_stat *dbstat) return CL_SUCCESS; } -void cl_free(struct cl_engine *engine) +int cl_engine_free(struct cl_engine *engine) { unsigned int i, j; struct cli_meta_node *metapt, *metah; @@ -1993,7 +1933,7 @@ void cl_free(struct cl_engine *engine) if(!engine) { cli_errmsg("cl_free: engine == NULL\n"); - return; + return CL_ENULLARG; } #ifdef CL_THREAD_SAFE @@ -2007,7 +1947,7 @@ void cl_free(struct cl_engine *engine) #ifdef CL_THREAD_SAFE pthread_mutex_unlock(&cli_ref_mutex); #endif - return; + return CL_SUCCESS; } #ifdef CL_THREAD_SAFE @@ -2086,6 +2026,7 @@ void cl_free(struct cl_engine *engine) if(engine->mempool) mp_destroy(engine->mempool); #endif free(engine); + return CL_SUCCESS; } static void cli_md5db_build(struct cli_matcher* root) @@ -2111,8 +2052,7 @@ static void cli_md5db_build(struct cli_matcher* root) } } - -int cl_build(struct cl_engine *engine) +int cl_engine_compile(struct cl_engine *engine) { unsigned int i; int ret; @@ -2148,10 +2088,10 @@ int cl_build(struct cl_engine *engine) return CL_SUCCESS; } -struct cl_engine *cl_dup(struct cl_engine *engine) +struct cl_engine *cl_engine_dup(struct cl_engine *engine) { if(!engine) { - cli_errmsg("cl_dup: engine == NULL\n"); + cli_errmsg("cl_engine_dup: engine == NULL\n"); return NULL; } diff --git a/libclamav/readdb.h b/libclamav/readdb.h index 0dd9dc64e..e33cb70b3 100644 --- a/libclamav/readdb.h +++ b/libclamav/readdb.h @@ -57,8 +57,6 @@ char *cli_virname(char *virname, unsigned int official); int cli_parse_add(struct cli_matcher *root, const char *virname, const char *hexsig, uint16_t rtype, uint16_t type, const char *offset, uint8_t target, const uint32_t *lsigid, unsigned int options); -int cli_initengine(struct cl_engine **engine, unsigned int options); - int cli_load(const char *filename, struct cl_engine **engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio); char *cli_dbgets(char *buff, unsigned int size, FILE *fs, struct cli_dbio *dbio); diff --git a/libclamav/scanners.c b/libclamav/scanners.c index d251fc9ef..925e340ec 100644 --- a/libclamav/scanners.c +++ b/libclamav/scanners.c @@ -565,7 +565,6 @@ static int cli_scanbzip(int desc, cli_ctx *ctx) { static int cli_scanbzip(int desc, cli_ctx *ctx) { int fd, bytes, ret = CL_CLEAN, bzerror = 0; - short memlim = 0; unsigned long int size = 0; char *buff; FILE *fs; @@ -578,11 +577,7 @@ static int cli_scanbzip(int desc, cli_ctx *ctx) return CL_EBZIP; } - if(ctx->limits) - if(ctx->limits->archivememlim) - memlim = 1; - - if((bfd = BZ2_bzReadOpen(&bzerror, fs, 0, memlim, NULL, 0)) == NULL) { + if((bfd = BZ2_bzReadOpen(&bzerror, fs, 0, 0, NULL, 0)) == NULL) { cli_dbgmsg("Bzip: Can't initialize bzip2 library (descriptor: %d).\n", desc); fclose(fs); return CL_EBZIP; @@ -1140,7 +1135,7 @@ static int cli_scanole2(int desc, cli_ctx *ctx) cli_dbgmsg("in cli_scanole2()\n"); - if(ctx->limits && ctx->limits->maxreclevel && ctx->recursion >= ctx->limits->maxreclevel) + if(ctx->engine->maxreclevel && ctx->recursion >= ctx->engine->maxreclevel) return CL_EMAXREC; /* generate the temporary directory */ @@ -1550,17 +1545,14 @@ static int cli_scan_structured(int desc, cli_ctx *ctx) unsigned int cc_count = 0; unsigned int ssn_count = 0; int done = 0; - const struct cl_limits *lim = NULL; int (*ccfunc)(const unsigned char *buffer, int length); int (*ssnfunc)(const unsigned char *buffer, int length); - if(ctx == NULL || ctx->limits == NULL) + if(ctx == NULL) return CL_ENULLARG; - lim = ctx->limits; - - if(lim->min_cc_count == 1) + if(ctx->engine->min_cc_count == 1) ccfunc = dlp_has_cc; else ccfunc = dlp_get_cc_count; @@ -1568,21 +1560,21 @@ static int cli_scan_structured(int desc, cli_ctx *ctx) switch((ctx->options & CL_SCAN_STRUCTURED_SSN_NORMAL) | (ctx->options & CL_SCAN_STRUCTURED_SSN_STRIPPED)) { case (CL_SCAN_STRUCTURED_SSN_NORMAL | CL_SCAN_STRUCTURED_SSN_STRIPPED): - if(lim->min_ssn_count == 1) + if(ctx->engine->min_ssn_count == 1) ssnfunc = dlp_has_ssn; else ssnfunc = dlp_get_ssn_count; break; case CL_SCAN_STRUCTURED_SSN_NORMAL: - if(lim->min_ssn_count == 1) + if(ctx->engine->min_ssn_count == 1) ssnfunc = dlp_has_normal_ssn; else ssnfunc = dlp_get_normal_ssn_count; break; case CL_SCAN_STRUCTURED_SSN_STRIPPED: - if(lim->min_ssn_count == 1) + if(ctx->engine->min_ssn_count == 1) ssnfunc = dlp_has_stripped_ssn; else ssnfunc = dlp_get_stripped_ssn_count; @@ -1593,20 +1585,20 @@ static int cli_scan_structured(int desc, cli_ctx *ctx) } while(!done && ((result = cli_readn(desc, buf, 8191)) > 0)) { - if((cc_count += ccfunc((const unsigned char *)buf, result)) >= lim->min_cc_count) + if((cc_count += ccfunc((const unsigned char *)buf, result)) >= ctx->engine->min_cc_count) done = 1; - if(ssnfunc && ((ssn_count += ssnfunc((const unsigned char *)buf, result)) >= lim->min_ssn_count)) + if(ssnfunc && ((ssn_count += ssnfunc((const unsigned char *)buf, result)) >= ctx->engine->min_ssn_count)) done = 1; } - if(cc_count != 0 && cc_count >= lim->min_cc_count) { + if(cc_count != 0 && cc_count >= ctx->engine->min_cc_count) { cli_dbgmsg("cli_scan_structured: %u credit card numbers detected\n", cc_count); *ctx->virname = "Structured.CreditCardNumber"; return CL_VIRUS; } - if(ssn_count != 0 && ssn_count >= lim->min_ssn_count) { + if(ssn_count != 0 && ssn_count >= ctx->engine->min_ssn_count) { cli_dbgmsg("cli_scan_structured: %u social security numbers detected\n", ssn_count); *ctx->virname = "Structured.SSN"; return CL_VIRUS; @@ -1875,7 +1867,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) if(cli_updatelimits(ctx, sb.st_size)!=CL_CLEAN) return CL_CLEAN; - if((SCAN_MAIL || SCAN_ARCHIVE) && ctx->limits && ctx->limits->maxreclevel && ctx->recursion > ctx->limits->maxreclevel) { + if((SCAN_MAIL || SCAN_ARCHIVE) && ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) { cli_dbgmsg("Archive recursion limit exceeded (level = %u).\n", ctx->recursion); return CL_CLEAN; } @@ -2112,16 +2104,11 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) } } -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) +int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options) { cli_ctx ctx; - struct cl_limits l_limits; int rc; - if(!limits) { - cli_errmsg("cl_scandesc: limits == NULL\n"); - return CL_ENULLARG; - } memset(&ctx, '\0', sizeof(cli_ctx)); ctx.engine = engine; ctx.virname = virname; @@ -2129,8 +2116,6 @@ int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, cons ctx.options = options; ctx.found_possibly_unwanted = 0; ctx.dconf = (struct cli_dconf *) engine->dconf; - ctx.limits = &l_limits; - memcpy(&l_limits, limits, sizeof(struct cl_limits)); rc = cli_magic_scandesc(desc, &ctx); if(rc == CL_CLEAN && ctx.found_possibly_unwanted) @@ -2173,7 +2158,7 @@ static int cli_scanfile(const char *filename, cli_ctx *ctx) return ret; } -int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options) +int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int options) { int fd, ret; @@ -2181,7 +2166,7 @@ int cl_scanfile(const char *filename, const char **virname, unsigned long int *s if((fd = open(filename, O_RDONLY|O_BINARY)) == -1) return CL_EOPEN; - ret = cl_scandesc(fd, virname, scanned, engine, limits, options); + ret = cl_scandesc(fd, virname, scanned, engine, options); close(fd); return ret; diff --git a/libclamav/spin.c b/libclamav/spin.c index e0e40c944..62b1251ea 100644 --- a/libclamav/spin.c +++ b/libclamav/spin.c @@ -375,12 +375,12 @@ int unspin(char *src, int ssize, struct cli_exe_section *sections, int sectcnt, bitman = bitmap; /* FIXMELIMITS: possibly rewrite to use the limits api */ - if(ctx->limits && ctx->limits->maxfilesize) { + if(ctx->engine->maxfilesize) { unsigned long int filesize = 0; for (j=0; j ctx->limits->maxfilesize || sections[j].vsz > ctx->limits->maxfilesize - filesize ) return 2; + if ( filesize > ctx->engine->maxfilesize || sections[j].vsz > ctx->engine->maxfilesize - filesize ) return 2; filesize += sections[j].vsz; } bitmap>>=1; diff --git a/libclamav/unzip.c b/libclamav/unzip.c index 60600822e..2b3fbee44 100644 --- a/libclamav/unzip.c +++ b/libclamav/unzip.c @@ -105,9 +105,9 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui else break; } if(res==1) { - if(ctx->limits && ctx->limits->maxfilesize && csize > ctx->limits->maxfilesize) { - cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->limits->maxfilesize); - csize = ctx->limits->maxfilesize; + if(ctx->engine->maxfilesize && csize > ctx->engine->maxfilesize) { + cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->engine->maxfilesize); + csize = ctx->engine->maxfilesize; } if(cli_writen(of, src, csize)!=(int)csize) ret = CL_EIO; else res=0; @@ -166,8 +166,8 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui while((res = unz_unz(&strm, Z_NO_FLUSH))==Z_OK) {}; if(*avail_out!=sizeof(obuf)) { written+=sizeof(obuf)-(*avail_out); - if(ctx->limits && ctx->limits->maxfilesize && written > ctx->limits->maxfilesize) { - cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->limits->maxfilesize); + if(ctx->engine->maxfilesize && written > ctx->engine->maxfilesize) { + cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->engine->maxfilesize); res = Z_STREAM_END; break; } @@ -210,8 +210,8 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui while((res = BZ2_bzDecompress(&strm))==BZ_OK || res==BZ_STREAM_END) { if(strm.avail_out!=sizeof(obuf)) { written+=sizeof(obuf)-strm.avail_out; - if(ctx->limits && ctx->limits->maxfilesize && written > ctx->limits->maxfilesize) { - cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->limits->maxfilesize); + if(ctx->engine->maxfilesize && written > ctx->engine->maxfilesize) { + cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->engine->maxfilesize); res = BZ_STREAM_END; break; } @@ -247,8 +247,8 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui while((res = explode(&strm))==EXPLODE_OK) { if(strm.avail_out!=sizeof(obuf)) { written+=sizeof(obuf)-strm.avail_out; - if(ctx->limits && ctx->limits->maxfilesize && written > ctx->limits->maxfilesize) { - cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->limits->maxfilesize); + if(ctx->engine->maxfilesize && written > ctx->engine->maxfilesize) { + cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->engine->maxfilesize); res = 0; break; } @@ -537,8 +537,8 @@ int cli_unzip(int f, cli_ctx *ctx) { cli_dbgmsg("cli_unzip: central @%x\n", coff); while(ret==CL_CLEAN && (coff=chdr(map, coff, fsize, &fu, fc+1, &ret, ctx, tmpd))) { fc++; - if (ctx->limits && ctx->limits->maxfiles && fu>=ctx->limits->maxfiles) { - cli_dbgmsg("cli_unzip: Files limit reached (max: %u)\n", ctx->limits->maxfiles); + if (ctx->engine->maxfiles && fu>=ctx->engine->maxfiles) { + cli_dbgmsg("cli_unzip: Files limit reached (max: %u)\n", ctx->engine->maxfiles); ret=CL_EMAXFILES; } } @@ -548,8 +548,8 @@ int cli_unzip(int f, cli_ctx *ctx) { while (ret==CL_CLEAN && lhofflimits && ctx->limits->maxfiles && fu>=ctx->limits->maxfiles) { - cli_dbgmsg("cli_unzip: Files limit reached (max: %u)\n", ctx->limits->maxfiles); + if (ctx->engine->maxfiles && fu>=ctx->engine->maxfiles) { + cli_dbgmsg("cli_unzip: Files limit reached (max: %u)\n", ctx->engine->maxfiles); ret=CL_EMAXFILES; } }