Changeset 319 for clamav/trunk/libclamav/readdb.c
- Timestamp:
- Apr 19, 2011, 11:12:07 PM (14 years ago)
- Location:
- clamav/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
clamav/trunk ¶
-
Property svn:mergeinfo
set to
/clamav/vendor/0.97 merged eligible
-
Property svn:mergeinfo
set to
-
TabularUnified clamav/trunk/libclamav/readdb.c ¶
r191 r319 47 47 #include "matcher-ac.h" 48 48 #include "matcher-bm.h" 49 #include "matcher- md5.h"49 #include "matcher-hash.h" 50 50 #include "matcher.h" 51 51 #include "others.h" … … 399 399 dbio->bread += bread; 400 400 sha256_update(&dbio->sha256ctx, dbio->readpt, bread); 401 } 402 if(dbio->chkonly && dbio->bufpt) { 403 dbio->bufpt = NULL; 404 dbio->readsize = dbio->size < dbio->bufsize ? dbio->size : dbio->bufsize - 1; 405 continue; 401 406 } 402 407 nl = strchr(dbio->bufpt, '\n'); … … 1861 1866 #define MD5_FP 2 1862 1867 1863 static int cli_md5db_init(struct cl_engine *engine, unsigned int mode) 1864 { 1865 struct cli_matcher *bm = NULL; 1866 int ret; 1867 1868 1869 if(mode == MD5_HDB) { 1870 bm = engine->md5_hdb = (struct cli_matcher *) mpool_calloc(engine->mempool, sizeof(struct cli_matcher), 1); 1871 } else if(mode == MD5_MDB) { 1872 bm = engine->md5_mdb = (struct cli_matcher *) mpool_calloc(engine->mempool, sizeof(struct cli_matcher), 1); 1873 } else { 1874 bm = engine->md5_fp = (struct cli_matcher *) mpool_calloc(engine->mempool, sizeof(struct cli_matcher), 1); 1875 } 1876 1877 if(!bm) 1878 return CL_EMEM; 1879 #ifdef USE_MPOOL 1880 bm->mempool = engine->mempool; 1881 #endif 1882 if((ret = cli_md5m_init(bm))) { 1883 cli_errmsg("cli_md5db_init: Failed to initialize MD5 matcher\n"); 1884 return ret; 1885 } 1886 1887 return CL_SUCCESS; 1888 } 1889 1890 #define MD5_DB \ 1891 if(mode == MD5_HDB) \ 1892 db = engine->md5_hdb; \ 1893 else if(mode == MD5_MDB) \ 1894 db = engine->md5_mdb; \ 1895 else \ 1896 db = engine->md5_fp; 1897 1898 #define MD5_TOKENS 3 1899 static int cli_loadmd5(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int mode, unsigned int options, struct cli_dbio *dbio, const char *dbname) 1868 #define MD5_TOKENS 5 1869 static int cli_loadhash(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int mode, unsigned int options, struct cli_dbio *dbio, const char *dbname) 1900 1870 { 1901 1871 const char *tokens[MD5_TOKENS + 1]; 1902 1872 char buffer[FILEBUFF], *buffer_cpy = NULL; 1903 const char *pt; 1904 unsigned char *md5; 1873 const char *pt, *virname; 1905 1874 int ret = CL_SUCCESS; 1906 1875 unsigned int size_field = 1, md5_field = 0, line = 0, sigs = 0, tokens_count; 1907 struct cli_md5m_patt *new;1908 1876 struct cli_matcher *db = NULL; 1877 unsigned long size; 1909 1878 1910 1879 … … 1925 1894 1926 1895 tokens_count = cli_strtokenize(buffer, ':', MD5_TOKENS + 1, tokens); 1927 if(tokens_count != MD5_TOKENS) { 1928 ret = CL_EMALFDB; 1929 break; 1930 } 1931 if(!cli_isnumber(tokens[size_field])) { 1932 cli_errmsg("cli_loadmd5: Invalid value for the size field\n"); 1896 if(tokens_count < 3) { 1897 ret = CL_EMALFDB; 1898 break; 1899 } 1900 if(tokens_count > MD5_TOKENS - 2) { 1901 unsigned int req_fl = atoi(tokens[MD5_TOKENS - 2]); 1902 1903 if(tokens_count > MD5_TOKENS) { 1904 ret = CL_EMALFDB; 1905 break; 1906 } 1907 1908 if(cl_retflevel() < req_fl) 1909 continue; 1910 if(tokens_count == MD5_TOKENS) { 1911 req_fl = atoi(tokens[MD5_TOKENS - 1]); 1912 if(cl_retflevel() > req_fl) 1913 continue; 1914 } 1915 } 1916 1917 size = strtol(tokens[size_field], (char **)&pt, 10); 1918 if(*pt || !size || size >= 0xffffffff) { 1919 cli_errmsg("cli_loadhash: Invalid value for the size field\n"); 1933 1920 ret = CL_EMALFDB; 1934 1921 break; … … 1950 1937 dot++; 1951 1938 if(engine->cb_sigload(dot, pt, engine->cb_sigload_ctx)) { 1952 cli_dbgmsg("cli_load md5: skipping %s due to callback\n", pt);1939 cli_dbgmsg("cli_loadhash: skipping %s (%s) due to callback\n", pt, dot); 1953 1940 continue; 1954 1941 } 1955 1942 } 1956 1943 1957 new = (struct cli_md5m_patt *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_md5m_patt)); 1958 if(!new) { 1959 ret = CL_EMEM; 1960 break; 1961 } 1962 1963 pt = tokens[md5_field]; /* md5 */ 1964 if(strlen(pt) != 32 || !(md5 = (unsigned char *) cli_mpool_hex2str(engine->mempool, pt))) { 1965 cli_errmsg("cli_loadmd5: Malformed MD5 string at line %u\n", line); 1966 mpool_free(engine->mempool, new); 1967 ret = CL_EMALFDB; 1968 break; 1969 } 1970 memcpy(new->md5, md5, 16); 1971 mpool_free(engine->mempool, md5); 1972 1973 new->filesize = atoi(tokens[size_field]); 1974 1975 new->virname = cli_mpool_virname(engine->mempool, tokens[2], options & CL_DB_OFFICIAL); 1976 if(!new->virname) { 1977 mpool_free(engine->mempool, new); 1978 ret = CL_EMALFDB; 1979 break; 1980 } 1981 1982 MD5_DB; 1983 if(!db && (ret = cli_md5db_init(engine, mode))) { 1984 mpool_free(engine->mempool, new->virname); 1985 mpool_free(engine->mempool, new); 1986 break; 1987 } else { 1988 MD5_DB; 1989 } 1990 1991 if((ret = cli_md5m_addpatt(db, new))) { 1992 cli_errmsg("cli_loadmd5: Error adding BM pattern\n"); 1993 mpool_free(engine->mempool, new->virname); 1994 mpool_free(engine->mempool, new); 1995 break; 1996 } 1997 1998 if(mode == MD5_MDB) { /* section MD5 */ 1999 if(!db->md5_sizes_hs.capacity) { 2000 cli_hashset_init_pool(&db->md5_sizes_hs, 65536, 80, engine->mempool); 2001 } 2002 cli_hashset_addkey(&db->md5_sizes_hs, new->filesize); 1944 virname = cli_mpool_virname(engine->mempool, pt, options & CL_DB_OFFICIAL); 1945 if(!virname) { 1946 ret = CL_EMALFDB; 1947 break; 1948 } 1949 1950 if(mode == MD5_HDB) 1951 db = engine->hm_hdb; 1952 else if(mode == MD5_MDB) 1953 db = engine->hm_mdb; 1954 else 1955 db = engine->hm_fp; 1956 1957 if(!db) { 1958 if(!(db = mpool_calloc(engine->mempool, 1, sizeof(*db)))) { 1959 ret = CL_EMEM; 1960 break; 1961 } 1962 #ifdef USE_MPOOL 1963 db->mempool = engine->mempool; 1964 #endif 1965 if(mode == MD5_HDB) 1966 engine->hm_hdb = db; 1967 else if(mode == MD5_MDB) 1968 engine->hm_mdb = db; 1969 else 1970 engine->hm_fp = db; 1971 } 1972 1973 if((ret = hm_addhash(db, tokens[md5_field], size, virname))) { 1974 cli_errmsg("cli_loadhash: Malformed MD5 string at line %u\n", line); 1975 mpool_free(engine->mempool, (void *)virname); 1976 break; 2003 1977 } 2004 1978 … … 2009 1983 2010 1984 if(!line) { 2011 cli_errmsg("cli_load md5: Empty database file\n");1985 cli_errmsg("cli_loadhash: Empty database file\n"); 2012 1986 return CL_EMALFDB; 2013 1987 } 2014 1988 2015 1989 if(ret) { 2016 cli_errmsg("cli_load md5: Problem parsing database at line %u\n", line);1990 cli_errmsg("cli_loadhash: Problem parsing database at line %u\n", line); 2017 1991 return ret; 2018 1992 } … … 2361 2335 uint8_t skipped = 0; 2362 2336 const char *dbname; 2363 2337 char buff[FILEBUFF]; 2338 2339 2340 if(dbio && dbio->chkonly) { 2341 while(cli_dbgets(buff, FILEBUFF, NULL, dbio)); 2342 return CL_SUCCESS; 2343 } 2364 2344 2365 2345 if(!dbio && (fs = fopen(filename, "rb")) == NULL) { … … 2385 2365 2386 2366 } else if(cli_strbcasestr(dbname, ".cvd")) { 2387 ret = cli_cvdload(fs, engine, signo, options, 0, filename );2367 ret = cli_cvdload(fs, engine, signo, options, 0, filename, 0); 2388 2368 2389 2369 } else if(cli_strbcasestr(dbname, ".cld")) { 2390 ret = cli_cvdload(fs, engine, signo, options, 1, filename); 2391 2392 } else if(cli_strbcasestr(dbname, ".hdb")) { 2393 ret = cli_loadmd5(fs, engine, signo, MD5_HDB, options, dbio, dbname); 2394 2395 } else if(cli_strbcasestr(dbname, ".hdu")) { 2370 ret = cli_cvdload(fs, engine, signo, options, 1, filename, 0); 2371 2372 } else if(cli_strbcasestr(dbname, ".hdb") || cli_strbcasestr(dbname, ".hsb")) { 2373 ret = cli_loadhash(fs, engine, signo, MD5_HDB, options, dbio, dbname); 2374 } else if(cli_strbcasestr(dbname, ".hdu") || cli_strbcasestr(dbname, ".hsu")) { 2396 2375 if(options & CL_DB_PUA) 2397 ret = cli_load md5(fs, engine, signo, MD5_HDB, options | CL_DB_PUA_MODE, dbio, dbname);2376 ret = cli_loadhash(fs, engine, signo, MD5_HDB, options | CL_DB_PUA_MODE, dbio, dbname); 2398 2377 else 2399 2378 skipped = 1; 2400 2379 2401 } else if(cli_strbcasestr(dbname, ".fp")) { 2402 ret = cli_loadmd5(fs, engine, signo, MD5_FP, options, dbio, dbname); 2403 2404 } else if(cli_strbcasestr(dbname, ".mdb")) { 2405 ret = cli_loadmd5(fs, engine, signo, MD5_MDB, options, dbio, dbname); 2406 2407 } else if(cli_strbcasestr(dbname, ".mdu")) { 2380 } else if(cli_strbcasestr(dbname, ".fp") || cli_strbcasestr(dbname, ".sfp")) { 2381 ret = cli_loadhash(fs, engine, signo, MD5_FP, options, dbio, dbname); 2382 } else if(cli_strbcasestr(dbname, ".mdb") || cli_strbcasestr(dbname, ".msb")) { 2383 ret = cli_loadhash(fs, engine, signo, MD5_MDB, options, dbio, dbname); 2384 2385 } else if(cli_strbcasestr(dbname, ".mdu") || cli_strbcasestr(dbname, ".msu")) { 2408 2386 if(options & CL_DB_PUA) 2409 ret = cli_load md5(fs, engine, signo, MD5_MDB, options | CL_DB_PUA_MODE, dbio, dbname);2387 ret = cli_loadhash(fs, engine, signo, MD5_MDB, options | CL_DB_PUA_MODE, dbio, dbname); 2410 2388 else 2411 2389 skipped = 1; … … 2469 2447 } else if(cli_strbcasestr(dbname, ".cdb")) { 2470 2448 ret = cli_loadcdb(fs, engine, signo, options, dbio); 2471 2472 2449 } else { 2473 2450 cli_dbgmsg("cli_load: unknown extension - assuming old database format\n"); … … 2951 2928 } 2952 2929 2953 if((root = engine-> md5_hdb)) {2954 cli_md5m_free(root);2930 if((root = engine->hm_hdb)) { 2931 hm_free(root); 2955 2932 mpool_free(engine->mempool, root); 2956 2933 } 2957 2934 2958 if((root = engine->md5_mdb)) { 2959 cli_md5m_free(root); 2960 mpool_free(engine->mempool, root->soff); 2961 if(root->md5_sizes_hs.capacity) { 2962 cli_hashset_destroy(&root->md5_sizes_hs); 2963 } 2935 if((root = engine->hm_mdb)) { 2936 hm_free(root); 2964 2937 mpool_free(engine->mempool, root); 2965 2938 } 2966 2939 2967 if((root = engine-> md5_fp)) {2968 cli_md5m_free(root);2940 if((root = engine->hm_fp)) { 2941 hm_free(root); 2969 2942 mpool_free(engine->mempool, root); 2970 2943 } … … 3051 3024 } 3052 3025 3053 static void cli_md5db_build(struct cli_matcher* root)3054 {3055 if(root && root->md5_sizes_hs.capacity) {3056 /* TODO: use hashset directly, instead of the array when matching*/3057 cli_dbgmsg("Converting hashset to array: %u entries\n", root->md5_sizes_hs.count);3058 3059 #ifdef USE_MPOOL3060 {3061 uint32_t *mpoolht;3062 unsigned int mpoolhtsz = root->md5_sizes_hs.count * sizeof(*mpoolht);3063 root->soff = mpool_malloc(root->mempool, mpoolhtsz);3064 root->soff_len = cli_hashset_toarray(&root->md5_sizes_hs, &mpoolht);3065 memcpy(root->soff, mpoolht, mpoolhtsz);3066 free(mpoolht);3067 }3068 #else3069 root->soff_len = cli_hashset_toarray(&root->md5_sizes_hs, &root->soff);3070 #endif3071 cli_hashset_destroy(&root->md5_sizes_hs);3072 cli_qsort(root->soff, root->soff_len, sizeof(uint32_t), NULL);3073 }3074 }3075 3076 3026 int cl_engine_compile(struct cl_engine *engine) 3077 3027 { … … 3095 3045 } 3096 3046 } 3097 if(engine->md5_hdb) 3098 cli_dbgmsg("MD5 sigs (files): %u\n", engine->md5_hdb->md5_patterns); 3099 3100 if(engine->md5_mdb) 3101 cli_dbgmsg("MD5 sigs (PE sections): %u\n", engine->md5_mdb->md5_patterns); 3047 if(engine->hm_hdb) 3048 hm_flush(engine->hm_hdb); 3049 3050 if(engine->hm_mdb) 3051 hm_flush(engine->hm_mdb); 3052 3053 if(engine->hm_fp) 3054 hm_flush(engine->hm_fp); 3102 3055 3103 3056 if((ret = cli_build_regex_list(engine->whitelist_matcher))) { … … 3107 3060 return ret; 3108 3061 } 3109 cli_md5db_build(engine->md5_mdb);3110 3062 if(engine->ignored) { 3111 3063 cli_bm_free(engine->ignored);
Note:
See TracChangeset
for help on using the changeset viewer.