~ubuntu-branches/ubuntu/jaunty/clamav/jaunty-backports

« back to all changes in this revision

Viewing changes to libclamav/scanners.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-10-02 15:36:00 UTC
  • mfrom: (10.1.6 sid)
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20101002153600-2tx3vki1u55cdrjy
Tags: 0.96.3+dfsg-2ubuntu0.10.04.1
Microversion update to 0.96.3 for Lucid (LP: #653738)

Show diffs side-by-side

added added

removed removed

Lines of Context:
185
185
    if(DETECT_ENCRYPTED && metadata->encrypted) {
186
186
        cli_dbgmsg("RAR: Encrypted files found in archive.\n");
187
187
        lseek(desc, 0, SEEK_SET);
188
 
        ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR);
 
188
        ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL);
189
189
        if(ret != CL_VIRUS) {
190
190
            *ctx->virname = "Heuristics.Encrypted.RAR";
191
191
            return CL_VIRUS;
227
227
            cli_dbgmsg("RAR: Encrypted main header\n");
228
228
            if(DETECT_ENCRYPTED) {
229
229
                lseek(desc, 0, SEEK_SET);
230
 
                ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR);
 
230
                ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL);
231
231
                if(ret != CL_VIRUS)
232
232
                    *ctx->virname = "Heuristics.Encrypted.RAR";
233
233
                return CL_VIRUS;
705
705
        unsigned int files = 0;
706
706
        struct cab_archive cab;
707
707
        struct cab_file *file;
 
708
        unsigned int corrupted_input;
708
709
 
709
710
 
710
711
    cli_dbgmsg("in cli_scanmscab()\n");
733
734
        if(ctx->engine->maxscansize && ctx->scansize + ctx->engine->maxfilesize >= ctx->engine->maxscansize)
734
735
            file->max_size = ctx->engine->maxscansize - ctx->scansize;
735
736
        else
736
 
            file->max_size = ctx->engine->maxfilesize;
 
737
            file->max_size = ctx->engine->maxfilesize ? ctx->engine->maxfilesize : 0xffffffff;
737
738
 
738
739
        cli_dbgmsg("CAB: Extracting file %s to %s, size %u, max_size: %u\n", file->name, tempname, file->length, (unsigned int) file->max_size);
739
740
        file->written_size = 0;
740
741
        if((ret = cab_extract(file, tempname))) {
741
742
            cli_dbgmsg("CAB: Failed to extract file: %s\n", cl_strerror(ret));
742
743
        } else {
743
 
            if(file->length != file->written_size)
 
744
            corrupted_input = ctx->corrupted_input;
 
745
            if(file->length != file->written_size) {
744
746
                cli_dbgmsg("CAB: Length from header %u but wrote %u bytes\n", (unsigned int) file->length, (unsigned int) file->written_size);
745
 
 
 
747
                ctx->corrupted_input = 1;
 
748
            }
746
749
            ret = cli_scanfile(tempname, ctx);
 
750
            ctx->corrupted_input = corrupted_input;
747
751
        }
748
752
        if(!ctx->engine->keeptmp) {
749
 
            if (cli_unlink(tempname)) {
 
753
            if (!access(tempname, R_OK) && cli_unlink(tempname)) {
750
754
                free(tempname);
751
755
                ret = CL_EUNLINK;
752
756
                break;
976
980
    snprintf(fullname, 1024, "%s"PATHSEP"nocomment.html", tempname);
977
981
    fd = open(fullname, O_RDONLY|O_BINARY);
978
982
    if (fd >= 0) {
979
 
            ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR);
 
983
            ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL);
980
984
            close(fd);
981
985
    }
982
986
 
986
990
            snprintf(fullname, 1024, "%s"PATHSEP"notags.html", tempname);
987
991
            fd = open(fullname, O_RDONLY|O_BINARY);
988
992
            if(fd >= 0) {
989
 
                    ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR);
 
993
                    ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL);
990
994
                    close(fd);
991
995
            }
992
996
    }
995
999
            snprintf(fullname, 1024, "%s"PATHSEP"javascript", tempname);
996
1000
            fd = open(fullname, O_RDONLY|O_BINARY);
997
1001
            if(fd >= 0) {
998
 
                    ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR);
 
1002
                    ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL);
999
1003
                    if (ret == CL_CLEAN) {
1000
1004
                            lseek(fd, 0, SEEK_SET);
1001
 
                            ret = cli_scandesc(fd, ctx, CL_TYPE_TEXT_ASCII, 0, NULL, AC_SCAN_VIR);
 
1005
                            ret = cli_scandesc(fd, ctx, CL_TYPE_TEXT_ASCII, 0, NULL, AC_SCAN_VIR, NULL);
1002
1006
                    }
1003
1007
                    close(fd);
1004
1008
            }
1023
1027
        struct text_norm_state state;
1024
1028
        char *tmpname = NULL;
1025
1029
        int ofd = -1, ret;
1026
 
        const struct cli_matcher *troot = ctx->engine->root[7];
 
1030
        struct cli_matcher *troot = ctx->engine->root[7];
1027
1031
        uint32_t maxpatlen = troot ? troot->maxpatlen : 0, offset = 0;
1028
1032
        struct cli_matcher *groot = ctx->engine->root[0];
1029
1033
        struct cli_ac_data gmdata, tmdata;
1045
1049
                        cli_dbgmsg("cli_scanscript: Can't generate temporary file/descriptor\n");
1046
1050
                        return ret;
1047
1051
                }
 
1052
                cli_dbgmsg("cli_scanscript: saving normalized file to %s\n", tmpname);
1048
1053
        }
1049
1054
 
1050
1055
        if(!(normalized = cli_malloc(SCANBUFF + maxpatlen))) {
1096
1101
                cli_dbgmsg("cli_scanscript: short read during normalizing\n");
1097
1102
            }
1098
1103
        }
 
1104
        if(ctx->engine->keeptmp) {
 
1105
                free(tmpname);
 
1106
                close(ofd);
 
1107
        }
 
1108
        free(normalized);
 
1109
        if(ret != CL_VIRUS) {
 
1110
            ret = cli_lsig_eval(ctx, troot, &tmdata, NULL);
 
1111
            if(ret != CL_VIRUS)
 
1112
                ret = cli_lsig_eval(ctx, groot, &gmdata, NULL);
 
1113
        }
1099
1114
        cli_ac_freedata(&tmdata);
1100
1115
        cli_ac_freedata(&gmdata);
1101
 
        if(ctx->engine->keeptmp) {
1102
 
                free(tmpname);
1103
 
                close(ofd);
1104
 
        }
1105
 
        free(normalized);
1106
1116
 
1107
1117
        return ret;
1108
1118
}
1619
1629
    return CL_CLEAN;
1620
1630
}
1621
1631
 
1622
 
static int cli_scanembpe(int desc, cli_ctx *ctx)
 
1632
static int cli_scanembpe(cli_ctx *ctx, off_t offset)
1623
1633
{
1624
1634
        int fd, bytes, ret = CL_CLEAN;
1625
 
        unsigned long int size = 0;
1626
 
        char buff[512];
 
1635
        unsigned long int size = 0, todo;
 
1636
        char *buff;
1627
1637
        char *tmpname;
 
1638
        fmap_t *map = *ctx->fmap;
1628
1639
 
1629
1640
    tmpname = cli_gentemp(ctx->engine->tmpdir);
1630
1641
    if(!tmpname)
1636
1647
        return CL_ECREAT;
1637
1648
    }
1638
1649
 
1639
 
    while((bytes = read(desc, buff, sizeof(buff))) > 0) {
 
1650
    todo = map->len - offset;
 
1651
    while(1) {
 
1652
        bytes = MIN(todo, map->pgsz);
 
1653
        if(!bytes)
 
1654
            break;
 
1655
 
 
1656
        if(!(buff = fmap_need_off_once(map, offset + size, bytes))) {
 
1657
            close(fd);
 
1658
            if(!ctx->engine->keeptmp) {
 
1659
                if (cli_unlink(tmpname)) {
 
1660
                    free(tmpname);
 
1661
                    return CL_EUNLINK;
 
1662
                }
 
1663
            }
 
1664
            free(tmpname);
 
1665
            return CL_EREAD;
 
1666
        }
1640
1667
        size += bytes;
 
1668
        todo -= bytes;
1641
1669
 
1642
 
        if(cli_checklimits("cli_scanembpe", ctx, size + sizeof(buff), 0, 0)!=CL_CLEAN)
 
1670
        if(cli_checklimits("cli_scanembpe", ctx, size, 0, 0)!=CL_CLEAN)
1643
1671
            break;
1644
1672
 
1645
1673
        if(cli_writen(fd, buff, bytes) != bytes) {
1651
1679
                    return CL_EUNLINK;
1652
1680
                }
1653
1681
            }
1654
 
            free(tmpname);      
 
1682
            free(tmpname);
1655
1683
            return CL_EWRITE;
1656
1684
        }
1657
1685
    }
1703
1731
    if(typercg)
1704
1732
        acmode |= AC_SCAN_FT;
1705
1733
 
1706
 
    ret = cli_fmap_scandesc(ctx, type == CL_TYPE_TEXT_ASCII ? 0 : type, 0, &ftoffset, acmode, refhash);
 
1734
    ret = cli_fmap_scandesc(ctx, type == CL_TYPE_TEXT_ASCII ? 0 : type, 0, &ftoffset, acmode, NULL, refhash);
1707
1735
 
1708
1736
    if(ret >= CL_TYPENO) {
1709
1737
        ctx->recursion++;
1710
 
 
1711
 
/*
1712
 
        if(type == CL_TYPE_TEXT_ASCII) {
1713
 
            lseek(desc, 0, SEEK_SET);
1714
 
 
1715
 
            nret = cli_scandesc(desc, ctx, 0, ret, 1, NULL);
1716
 
            if(nret == CL_VIRUS)
1717
 
                cli_dbgmsg("%s found in descriptor %d when scanning file type %u\n", *ctx->virname, desc, ret);
1718
 
        }
1719
 
*/
1720
 
 
1721
1738
        if(nret != CL_VIRUS) {
1722
1739
            lastzip = lastrar = 0xdeadbeef;
1723
1740
            fpt = ftoffset;
1772
1789
                            ctx->container_type = CL_TYPE_AUTOIT;
1773
1790
                            ctx->container_size = map->len - fpt->offset; /* not precise */
1774
1791
                            cli_dbgmsg("AUTOIT signature found at %u\n", (unsigned int) fpt->offset);
1775
 
                            nret = cli_scanautoit(map->fd, ctx, fpt->offset + 23);
 
1792
                            nret = cli_scanautoit(ctx, fpt->offset + 23);
1776
1793
                        }
1777
1794
                        break;
1778
1795
 
1802
1819
                            ctx->container_size = map->len - fpt->offset; /* not precise */
1803
1820
                            memset(&peinfo, 0, sizeof(struct cli_exe_info));
1804
1821
                            peinfo.offset = fpt->offset;
1805
 
                            lseek(map->fd, fpt->offset, SEEK_SET);
1806
1822
                            if(cli_peheader(map, &peinfo) == 0) {
1807
1823
                                cli_dbgmsg("*** Detected embedded PE file at %u ***\n", (unsigned int) fpt->offset);
1808
1824
                                if(peinfo.section)
1809
1825
                                    free(peinfo.section);
1810
1826
 
1811
 
                                lseek(map->fd, fpt->offset, SEEK_SET);
1812
 
                                nret = cli_scanembpe(map->fd, ctx);
 
1827
                                nret = cli_scanembpe(ctx, fpt->offset);
1813
1828
                                break_loop = 1; /* we can stop here and other
1814
1829
                                                 * embedded executables will
1815
1830
                                                 * be found recursively
1884
1899
#define LINESTR(x) #x
1885
1900
#define LINESTR2(x) LINESTR(x)
1886
1901
#define __AT__  " at line "LINESTR2(__LINE__)
1887
 
#define ret_from_magicscan(retcode) do {                                        \
1888
 
    cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__);       \
1889
 
    return retcode;                                                     \
 
1902
#define ret_from_magicscan(retcode) do {                                                        \
 
1903
    cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__);                       \
 
1904
    if(ctx->engine->cb_post_scan) {                                                             \
 
1905
        switch(ctx->engine->cb_post_scan(desc, retcode, retcode == CL_VIRUS && ctx->virname ? *ctx->virname : NULL, ctx->cb_ctx)) {             \
 
1906
        case CL_BREAK:                                                                          \
 
1907
            cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n");                   \
 
1908
            return CL_CLEAN;                                                                    \
 
1909
        case CL_VIRUS:                                                                          \
 
1910
            cli_dbgmsg("cli_magic_scandesc: file blacklisted by callback\n");                   \
 
1911
            if(ctx->virname)                                                                    \
 
1912
                *ctx->virname = "Detected.By.Callback";                                         \
 
1913
            return CL_VIRUS;                                                                    \
 
1914
        case CL_CLEAN:                                                                          \
 
1915
            break;                                                                              \
 
1916
        default:                                                                                \
 
1917
            cli_warnmsg("cli_magic_scandesc: ignoring bad return code from callback\n");        \
 
1918
        }                                                                                       \
 
1919
    }                                                                                           \
 
1920
    return retcode;                                                                             \
1890
1921
    } while(0)
1891
1922
 
1892
 
int cli_magic_scandesc(int desc, cli_ctx *ctx)
 
1923
static int magic_scandesc(int desc, cli_ctx *ctx, cli_file_t type)
1893
1924
{
1894
1925
        int ret = CL_CLEAN;
1895
 
        cli_file_t type, dettype = 0;
 
1926
        cli_file_t dettype = 0;
1896
1927
        struct stat sb;
1897
1928
        uint8_t typercg = 1;
1898
1929
        cli_file_t current_container_type = ctx->container_type;
1900
1931
        unsigned char hash[16];
1901
1932
        bitset_t *old_hook_lsig_matches;
1902
1933
 
 
1934
#ifdef HAVE__INTERNAL__SHA_COLLECT
 
1935
    if(ctx->sha_collect>0) ctx->sha_collect = 0;
 
1936
#endif
 
1937
 
1903
1938
    cli_dbgmsg("in cli_magic_scandesc (reclevel: %u/%u)\n", ctx->recursion, ctx->engine->maxreclevel);
1904
1939
    if(ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) {
1905
1940
        cli_dbgmsg("cli_magic_scandesc: Archive recursion limit exceeded (%u, max: %u)\n", ctx->recursion, ctx->engine->maxreclevel);
1939
1974
        ret_from_magicscan(CL_EMEM);
1940
1975
    }
1941
1976
 
 
1977
    if(ctx->engine->cb_pre_scan) {
 
1978
        switch(ctx->engine->cb_pre_scan(desc, ctx->cb_ctx)) {
 
1979
        case CL_BREAK:
 
1980
            cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n");
 
1981
            funmap(*ctx->fmap);
 
1982
            ctx->fmap--;
 
1983
            ret_from_magicscan(CL_CLEAN);
 
1984
        case CL_VIRUS:
 
1985
            cli_dbgmsg("cli_magic_scandesc: file blacklisted by callback\n");
 
1986
            if(ctx->virname)
 
1987
                *ctx->virname = "Detected.By.Callback";
 
1988
            funmap(*ctx->fmap);
 
1989
            ctx->fmap--;
 
1990
            ret_from_magicscan(CL_VIRUS);
 
1991
        case CL_CLEAN:
 
1992
            break;
 
1993
        default:
 
1994
            cli_warnmsg("cli_magic_scandesc: ignoring bad return code from callback\n");
 
1995
        }
 
1996
    }
 
1997
 
1942
1998
    if(cache_check(hash, ctx) == CL_CLEAN) {
1943
1999
        funmap(*ctx->fmap);
1944
2000
        ctx->fmap--;
1954
2010
        else
1955
2011
            cli_dbgmsg("Raw mode: No support for special files\n");
1956
2012
 
1957
 
        if((ret = cli_fmap_scandesc(ctx, 0, 0, NULL, AC_SCAN_VIR, hash)) == CL_VIRUS)
 
2013
        if((ret = cli_fmap_scandesc(ctx, 0, 0, NULL, AC_SCAN_VIR, NULL, hash)) == CL_VIRUS)
1958
2014
            cli_dbgmsg("%s found in descriptor %d\n", *ctx->virname, desc);
1959
2015
        else if(ret == CL_CLEAN) {
1960
2016
            if(ctx->recursion != ctx->engine->maxreclevel)
1969
2025
        ret_from_magicscan(ret);
1970
2026
    }
1971
2027
 
1972
 
    type = cli_filetype2(*ctx->fmap, ctx->engine); /* FIXMEFMAP: port to fmap */
 
2028
    if(type == CL_TYPE_ANY)
 
2029
        type = cli_filetype2(*ctx->fmap, ctx->engine); /* FIXMEFMAP: port to fmap */
1973
2030
    if(type == CL_TYPE_ERROR) {
1974
2031
        cli_dbgmsg("cli_magic_scandesc: cli_filetype2 returned CL_TYPE_ERROR\n");
1975
2032
        funmap(*ctx->fmap);
1977
2034
        ctx->hook_lsig_matches = old_hook_lsig_matches;
1978
2035
        ret_from_magicscan(CL_EREAD);
1979
2036
    }
 
2037
 
 
2038
#ifdef HAVE__INTERNAL__SHA_COLLECT
 
2039
    if(!ctx->sha_collect && type==CL_TYPE_MSEXE) ctx->sha_collect = 1;
 
2040
#endif
1980
2041
    lseek(desc, 0, SEEK_SET); /* FIXMEFMAP: remove ? */
1981
2042
 
1982
2043
    ctx->hook_lsig_matches = cli_bitset_init();
1983
2044
    if (!ctx->hook_lsig_matches) {
1984
2045
        ctx->hook_lsig_matches = old_hook_lsig_matches;
 
2046
        ctx->fmap--;
1985
2047
        ret_from_magicscan(CL_EMEM);
1986
2048
    }
1987
2049
 
2044
2106
            ctx->container_type = CL_TYPE_AUTOIT;
2045
2107
            ctx->container_size = sb.st_size;
2046
2108
            if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_AUTOIT))
2047
 
                ret = cli_scanautoit(desc, ctx, 23);
 
2109
                ret = cli_scanautoit(ctx, 23);
2048
2110
            break;
2049
2111
 
2050
2112
        case CL_TYPE_MSSZDD:
2276
2338
                ret = cli_scanscript(ctx);
2277
2339
            if(ret != CL_VIRUS && ctx->container_type == CL_TYPE_MAIL) {
2278
2340
                lseek(desc, 0, SEEK_SET);
2279
 
                ret = cli_scandesc(desc, ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR);
 
2341
                ret = cli_scandesc(desc, ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR, NULL);
2280
2342
            }
2281
2343
            break;
2282
2344
        /* Due to performance reasons all executables were first scanned
2284
2346
         */
2285
2347
        case CL_TYPE_MSEXE:
2286
2348
            if(SCAN_PE && ctx->dconf->pe)
2287
 
                ret = cli_scanpe(ctx, NULL);
 
2349
                ret = cli_scanpe(ctx);
2288
2350
            break;
2289
2351
        default:
2290
2352
            break;
2312
2374
    }
2313
2375
}
2314
2376
 
 
2377
int cli_magic_scandesc(int desc, cli_ctx *ctx)
 
2378
{
 
2379
    return magic_scandesc(desc, ctx, CL_TYPE_ANY);
 
2380
}
 
2381
 
 
2382
int cli_magic_scandesc_type(int desc, cli_ctx *ctx, cli_file_t type)
 
2383
{
 
2384
    return magic_scandesc(desc, ctx, type);
 
2385
}
 
2386
 
 
2387
int cli_scandesc_stats(int desc, const char **virname, char *virhash, unsigned int *virsize, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions)
 
2388
{
 
2389
    cli_ctx ctx;
 
2390
    int rc;
 
2391
 
 
2392
    memset(&ctx, '\0', sizeof(cli_ctx));
 
2393
    ctx.engine = engine;
 
2394
    ctx.virname = virname;
 
2395
    if(virsize) {
 
2396
        *virsize = 0;
 
2397
        ctx.virsize = virsize;
 
2398
        ctx.virhash = virhash;
 
2399
    }
 
2400
    ctx.scanned = scanned;
 
2401
    ctx.options = scanoptions;
 
2402
    ctx.found_possibly_unwanted = 0;
 
2403
    ctx.container_type = CL_TYPE_ANY;
 
2404
    ctx.container_size = 0;
 
2405
    ctx.dconf = (struct cli_dconf *) engine->dconf;
 
2406
    ctx.fmap = cli_calloc(sizeof(fmap_t *), ctx.engine->maxreclevel + 2);
 
2407
    if(!ctx.fmap)
 
2408
        return CL_EMEM;
 
2409
    if (!(ctx.hook_lsig_matches = cli_bitset_init())) {
 
2410
        free(ctx.fmap);
 
2411
        return CL_EMEM;
 
2412
    }
 
2413
 
 
2414
#ifdef HAVE__INTERNAL__SHA_COLLECT
 
2415
    if(scanoptions & CL_SCAN_INTERNAL_COLLECT_SHA) {
 
2416
        char link[32];
 
2417
        ssize_t linksz;
 
2418
 
 
2419
        snprintf(link, sizeof(link), "/proc/self/fd/%u", desc);
 
2420
        link[sizeof(link)-1]='\0';
 
2421
        if((linksz=readlink(link, ctx.entry_filename, sizeof(ctx.entry_filename)))==-1) {
 
2422
            cli_errmsg("failed to resolve filename for descriptor %d (%s)\n", desc, link);
 
2423
            strcpy(ctx.entry_filename, "NO_IDEA");
 
2424
        } else
 
2425
            ctx.entry_filename[linksz]='\0';
 
2426
    } while(0);
 
2427
#endif
 
2428
 
 
2429
    rc = cli_magic_scandesc(desc, &ctx);
 
2430
 
 
2431
    cli_bitset_free(ctx.hook_lsig_matches);
 
2432
    free(ctx.fmap);
 
2433
    if(rc == CL_CLEAN && ctx.found_possibly_unwanted)
 
2434
        rc = CL_VIRUS;
 
2435
    return rc;
 
2436
}
 
2437
 
2315
2438
int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions)
2316
2439
{
 
2440
    return cli_scandesc_stats(desc, virname, NULL, NULL, scanned, engine, scanoptions);
 
2441
}
 
2442
 
 
2443
 
 
2444
int cl_scandesc_callback(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions, void *context)
 
2445
{
2317
2446
    cli_ctx ctx;
2318
2447
    int rc;
2319
2448
 
2326
2455
    ctx.container_type = CL_TYPE_ANY;
2327
2456
    ctx.container_size = 0;
2328
2457
    ctx.dconf = (struct cli_dconf *) engine->dconf;
 
2458
    ctx.cb_ctx = context;
2329
2459
    ctx.fmap = cli_calloc(sizeof(fmap_t *), ctx.engine->maxreclevel + 2);
2330
2460
    if(!ctx.fmap)
2331
2461
        return CL_EMEM;
2332
 
    ctx.hook_lsig_matches = cli_bitset_init();
 
2462
    if (!(ctx.hook_lsig_matches = cli_bitset_init())) {
 
2463
        free(ctx.fmap);
 
2464
        return CL_EMEM;
 
2465
    }
 
2466
 
 
2467
#ifdef HAVE__INTERNAL__SHA_COLLECT
 
2468
    if(scanoptions & CL_SCAN_INTERNAL_COLLECT_SHA) {
 
2469
        char link[32];
 
2470
        ssize_t linksz;
 
2471
 
 
2472
        snprintf(link, sizeof(link), "/proc/self/fd/%u", desc);
 
2473
        link[sizeof(link)-1]='\0';
 
2474
        if((linksz=readlink(link, ctx.entry_filename, sizeof(ctx.entry_filename)))==-1) {
 
2475
            cli_errmsg("failed to resolve filename for descriptor %d (%s)\n", desc, link);
 
2476
            strcpy(ctx.entry_filename, "NO_IDEA");
 
2477
        } else
 
2478
            ctx.entry_filename[linksz]='\0';
 
2479
    } while(0);
 
2480
#endif
2333
2481
 
2334
2482
    rc = cli_magic_scandesc(desc, &ctx);
2335
2483
 
2389
2537
    return ret;
2390
2538
}
2391
2539
 
 
2540
int cli_scanfile_stats(const char *filename, const char **virname, char *virhash, unsigned int *virsize, unsigned long int *scanned, const struct cl_engine *engine, unsigned int scanoptions)
 
2541
{
 
2542
        int fd, ret;
 
2543
 
 
2544
    if((fd = safe_open(filename, O_RDONLY|O_BINARY)) == -1)
 
2545
        return CL_EOPEN;
 
2546
 
 
2547
    ret = cli_scandesc_stats(fd, virname, virhash, virsize, scanned, engine, scanoptions);
 
2548
    close(fd);
 
2549
 
 
2550
    return ret;
 
2551
}
 
2552
 
2392
2553
/*
2393
2554
Local Variables:
2394
2555
   c-basic-offset: 4