~ubuntu-branches/ubuntu/hardy/clamav/hardy-backports

« back to all changes in this revision

Viewing changes to libclamav/matcher.c

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman
  • Date: 2011-09-12 13:44:34 UTC
  • mfrom: (0.5.43 natty-proposed)
  • Revision ID: package-import@ubuntu.com-20110912134434-2fpiteaw9ww94l7w
Tags: 0.97.2+dfsg-1ubuntu1.11.04~hardy1
* Source backport for hardy (LP: #848117):
  - Build without llvm support on lpia to fix FTBFS (not a regression as
    llvm has never built on hardy lpia)
  - Drop -T -W from apparmor_parser calls in clamav-daemon and freshclam
    postinsts since it is not supported in Hardy's apparmor
  - Drop deny rule in freshclam apparmor profile since deny is not
    supported in Hardy's apparmor
  - Drop dh_lintian from debian/rules and adjust version of debhelper
    build-dep
  - Drop build-dep and libclamav-dev depends on non-existent libtommath-dev
  - Changed Section to 'utils' for clamav-dbg package
  - Ignore test suite errors on hppa
  - Build-depend on libltdl3-dev instead of libltdl-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
#include "others.h"
35
35
#include "matcher-ac.h"
36
36
#include "matcher-bm.h"
37
 
#include "matcher-md5.h"
38
37
#include "md5.h"
 
38
#include "sha1.h"
 
39
#include "sha256.h"
39
40
#include "filetypes.h"
40
41
#include "matcher.h"
41
42
#include "pe.h"
54
55
#include "perflogging.h"
55
56
#include "bytecode_priv.h"
56
57
#include "bytecode_api_impl.h"
57
 
 
58
 
#ifdef HAVE__INTERNAL__SHA_COLLECT
59
58
#include "sha256.h"
60
59
#include "sha1.h"
61
 
#endif
62
60
 
63
61
#ifdef CLI_PERF_LOGGING
64
62
 
382
380
        char md5[33];
383
381
        unsigned int i;
384
382
        const char *virname;
 
383
        SHA1Context sha1;
 
384
        SHA256_CTX sha256;
 
385
        fmap_t *map;
 
386
        char *ptr;
 
387
        uint8_t shash1[SHA1_HASH_SIZE*2+1];
 
388
        uint8_t shash256[SHA256_HASH_SIZE*2+1];
 
389
        int have_sha1, have_sha256;
385
390
 
386
 
    if(ctx->engine->md5_fp && cli_md5m_scan(digest, size, &virname, ctx->engine->md5_fp) == CL_VIRUS) {
387
 
        cli_dbgmsg("cli_checkfp(): Found false positive detection (fp sig: %s)\n", virname);
 
391
    if(cli_hm_scan(digest, size, &virname, ctx->engine->hm_fp, CLI_HASH_MD5) == CL_VIRUS) {
 
392
        cli_dbgmsg("cli_checkfp(md5): Found false positive detection (fp sig: %s)\n", virname);
388
393
        return CL_CLEAN;
389
394
    }
 
395
 
390
396
    for(i = 0; i < 16; i++)
391
397
        sprintf(md5 + i * 2, "%02x", digest[i]);
392
398
    md5[32] = 0;
393
399
    cli_dbgmsg("FP SIGNATURE: %s:%u:%s\n", md5, (unsigned int) size, *ctx->virname ? *ctx->virname : "Name");
394
400
 
 
401
    map = *ctx->fmap;
 
402
    have_sha1 = cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, size);
 
403
    have_sha256 = cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA256, size);
 
404
    if(have_sha1 || have_sha256) {
 
405
        if((ptr = fmap_need_off_once(map, 0, size))) {
 
406
            if(have_sha1) {
 
407
                SHA1Init(&sha1);
 
408
                SHA1Update(&sha1, ptr, size);
 
409
                SHA1Final(&sha1, &shash1[SHA1_HASH_SIZE]);
 
410
                if(cli_hm_scan(&shash1[SHA1_HASH_SIZE], size, &virname, ctx->engine->hm_fp, CLI_HASH_SHA1) == CL_VIRUS){
 
411
                    cli_dbgmsg("cli_checkfp(sha1): Found false positive detection (fp sig: %s)\n", virname);
 
412
                    return CL_CLEAN;
 
413
                }
 
414
            }
 
415
            if(have_sha256) {
 
416
                sha256_init(&sha256);
 
417
                sha256_update(&sha256, ptr, size);
 
418
                sha256_final(&sha256, &shash256[SHA256_HASH_SIZE]);
 
419
                if(cli_hm_scan(&shash256[SHA256_HASH_SIZE], size, &virname, ctx->engine->hm_fp, CLI_HASH_SHA256) == CL_VIRUS){
 
420
                    cli_dbgmsg("cli_checkfp(sha256): Found false positive detection (fp sig: %s)\n", virname);
 
421
                    return CL_CLEAN;
 
422
                }
 
423
            }
 
424
        }
 
425
    }
395
426
#ifdef HAVE__INTERNAL__SHA_COLLECT
396
427
    if((ctx->options & CL_SCAN_INTERNAL_COLLECT_SHA) && ctx->sha_collect>0) {
397
 
        SHA1Context sha1;
398
 
        SHA256_CTX sha256;
399
 
        fmap_t *map = *ctx->fmap;
400
 
        char *ptr;
401
 
        uint8_t shash1[SHA1_HASH_SIZE*2+1];
402
 
        uint8_t shash256[SHA256_HASH_SIZE*2+1];
403
 
 
404
428
        if((ptr = fmap_need_off_once(map, 0, size))) {
405
 
            sha256_init(&sha256);
406
 
            sha256_update(&sha256, ptr, size);
407
 
            sha256_final(&sha256, &shash256[SHA256_HASH_SIZE]);
 
429
            if(!have_sha256) {
 
430
                sha256_init(&sha256);
 
431
                sha256_update(&sha256, ptr, size);
 
432
                sha256_final(&sha256, &shash256[SHA256_HASH_SIZE]);
 
433
            }
408
434
            for(i=0; i<SHA256_HASH_SIZE; i++)
409
435
                sprintf((char *)shash256+i*2, "%02x", shash256[SHA256_HASH_SIZE+i]);
410
436
 
411
 
            SHA1Init(&sha1);
412
 
            SHA1Update(&sha1, ptr, size);
413
 
            SHA1Final(&sha1, &shash1[SHA1_HASH_SIZE]);
 
437
            if(!have_sha1) {
 
438
                SHA1Init(&sha1);
 
439
                SHA1Update(&sha1, ptr, size);
 
440
                SHA1Final(&sha1, &shash1[SHA1_HASH_SIZE]);
 
441
            }
414
442
            for(i=0; i<SHA1_HASH_SIZE; i++)
415
443
                sprintf((char *)shash1+i*2, "%02x", shash1[SHA1_HASH_SIZE+i]);
416
444
 
502
530
    return ret;
503
531
}
504
532
 
505
 
int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info)
 
533
int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info, const char *hash)
506
534
{
507
535
        unsigned int i, evalcnt;
508
536
        uint64_t evalids;
527
555
                    continue;
528
556
            }
529
557
 
530
 
            if(root->ac_lsigtable[i]->tdb.handlertype) {
531
 
                ctx->recursion++;
532
 
                if(cli_magic_scandesc_type(map->fd, ctx, root->ac_lsigtable[i]->tdb.handlertype[0]) == CL_VIRUS) {
 
558
            if(hash && root->ac_lsigtable[i]->tdb.handlertype) {
 
559
                if(memcmp(ctx->handlertype_hash, hash, 16)) {
 
560
                    ctx->recursion++;
 
561
                    memcpy(ctx->handlertype_hash, hash, 16);
 
562
                    if(cli_magic_scandesc_type(map->fd, ctx, root->ac_lsigtable[i]->tdb.handlertype[0]) == CL_VIRUS) {
 
563
                        ctx->recursion--;
 
564
                        return CL_VIRUS;
 
565
                    }
533
566
                    ctx->recursion--;
534
 
                    return CL_VIRUS;
 
567
                    continue;
535
568
                }
536
 
                ctx->recursion--;
537
 
                continue;
538
569
            }
539
570
 
540
571
            if(root->ac_lsigtable[i]->tdb.icongrp1 || root->ac_lsigtable[i]->tdb.icongrp2) {
545
576
                        if(ctx->virname)
546
577
                            *ctx->virname = root->ac_lsigtable[i]->virname;
547
578
                        return CL_VIRUS;
548
 
                    } else if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, ctx->virname, acdata->lsigcnt[i], acdata->lsigsuboff[i], map) == CL_VIRUS) {
 
579
                    } else if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, ctx->virname, acdata->lsigcnt[i], acdata->lsigsuboff_first[i], map) == CL_VIRUS) {
549
580
                        return CL_VIRUS;
550
581
                    }
551
582
                }
556
587
                    *ctx->virname = root->ac_lsigtable[i]->virname;
557
588
                return CL_VIRUS;
558
589
            }
559
 
            if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, ctx->virname, acdata->lsigcnt[i], acdata->lsigsuboff[i], map) == CL_VIRUS) {
 
590
            if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, ctx->virname, acdata->lsigcnt[i], acdata->lsigsuboff_first[i], map) == CL_VIRUS) {
560
591
                return CL_VIRUS;
561
592
            }
562
593
        }
567
598
int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, struct cli_ac_result **acres, unsigned char *refhash)
568
599
{
569
600
        unsigned char *buff;
570
 
        int ret = CL_CLEAN, type = CL_CLEAN, bytes;
 
601
        int ret = CL_CLEAN, type = CL_CLEAN, bytes, compute_hash[CLI_HASH_AVAIL_TYPES];
571
602
        unsigned int i = 0, bm_offmode = 0;
572
603
        uint32_t maxpatlen, offset = 0;
573
604
        struct cli_ac_data gdata, tdata;
574
605
        struct cli_bm_off toff;
575
606
        cli_md5_ctx md5ctx;
576
 
        unsigned char digest[16];
 
607
        SHA256_CTX sha256ctx;
 
608
        SHA1Context sha1ctx;
 
609
        unsigned char digest[CLI_HASH_AVAIL_TYPES][32];
577
610
        struct cli_matcher *groot = NULL, *troot = NULL;
578
611
        struct cli_target_info info;
579
612
        fmap_t *map = *ctx->fmap;
 
613
        struct cli_matcher *hdb, *fp;
580
614
 
581
615
    if(!ctx->engine) {
582
616
        cli_errmsg("cli_scandesc: engine == NULL\n");
642
676
        }
643
677
    }
644
678
 
645
 
    if(!refhash && !ftonly && ctx->engine->md5_hdb)
646
 
        cli_md5_init(&md5ctx);
 
679
    hdb = ctx->engine->hm_hdb;
 
680
    fp = ctx->engine->hm_fp;
 
681
 
 
682
    if(!ftonly && hdb) {
 
683
        if(!refhash) {
 
684
            if(cli_hm_have_size(hdb, CLI_HASH_MD5, map->len) || cli_hm_have_size(fp, CLI_HASH_MD5, map->len)) {
 
685
                cli_md5_init(&md5ctx);
 
686
                compute_hash[CLI_HASH_MD5] = 1;
 
687
            } else
 
688
                compute_hash[CLI_HASH_MD5] = 0;
 
689
        } else {
 
690
            compute_hash[CLI_HASH_MD5] = 0;
 
691
            memcpy(digest[CLI_HASH_MD5], refhash, 16);
 
692
        }
 
693
 
 
694
        if(cli_hm_have_size(hdb, CLI_HASH_SHA1, map->len) || cli_hm_have_size(fp, CLI_HASH_SHA1, map->len)) {
 
695
            SHA1Init(&sha1ctx);
 
696
            compute_hash[CLI_HASH_SHA1] = 1;
 
697
        } else
 
698
            compute_hash[CLI_HASH_SHA1] = 0;
 
699
 
 
700
        if(cli_hm_have_size(hdb, CLI_HASH_SHA256, map->len) || cli_hm_have_size(fp, CLI_HASH_SHA256, map->len)) {
 
701
            sha256_init(&sha256ctx);
 
702
            compute_hash[CLI_HASH_SHA256] = 1;
 
703
        } else
 
704
            compute_hash[CLI_HASH_SHA256] = 0;
 
705
    }
647
706
 
648
707
    while(offset < map->len) {
649
708
        bytes = MIN(map->len - offset, SCANBUFF);
687
746
                    type = ret;
688
747
            }
689
748
 
690
 
            if(!refhash && ctx->engine->md5_hdb)
691
 
                cli_md5_update(&md5ctx, buff + maxpatlen * (offset!=0), bytes - maxpatlen * (offset!=0));
 
749
            if(hdb) {
 
750
                void *data = buff + maxpatlen * (offset!=0);
 
751
                uint32_t data_len = bytes - maxpatlen * (offset!=0);
 
752
 
 
753
                if(compute_hash[CLI_HASH_MD5])
 
754
                    cli_md5_update(&md5ctx, data, data_len);
 
755
                if(compute_hash[CLI_HASH_SHA1])
 
756
                    SHA1Update(&sha1ctx, data, data_len);
 
757
                if(compute_hash[CLI_HASH_SHA256])
 
758
                    sha256_update(&sha256ctx, data, data_len);
 
759
            }
692
760
        }
693
761
 
694
762
        if(bytes < SCANBUFF) break;
695
763
        offset += bytes - maxpatlen;
696
764
    }
697
765
 
 
766
    if(!ftonly && hdb) {
 
767
        enum CLI_HASH_TYPE hashtype;
 
768
 
 
769
        if(compute_hash[CLI_HASH_MD5])
 
770
            cli_md5_final(digest[CLI_HASH_MD5], &md5ctx);
 
771
        if(refhash)
 
772
            compute_hash[CLI_HASH_MD5] = 1;
 
773
        if(compute_hash[CLI_HASH_SHA1])
 
774
            SHA1Final(&sha1ctx, digest[CLI_HASH_SHA1]);
 
775
        if(compute_hash[CLI_HASH_SHA256])
 
776
            sha256_final(&sha256ctx, digest[CLI_HASH_SHA256]);
 
777
 
 
778
        for(hashtype = CLI_HASH_MD5; hashtype < CLI_HASH_AVAIL_TYPES; hashtype++) {
 
779
            if(compute_hash[hashtype] && (ret = cli_hm_scan(digest[hashtype], map->len, ctx->virname, hdb, hashtype)) == CL_VIRUS)
 
780
                break;
 
781
        }
 
782
 
 
783
        if(ret == CL_VIRUS && fp) {
 
784
            for(hashtype = CLI_HASH_MD5; hashtype < CLI_HASH_AVAIL_TYPES; hashtype++) {
 
785
                if(compute_hash[hashtype] && cli_hm_scan(digest[hashtype], map->len, ctx->virname, fp, hashtype) == CL_VIRUS) {
 
786
                    ret = CL_CLEAN;
 
787
                    break;
 
788
                }
 
789
            }
 
790
        }
 
791
    }
 
792
 
698
793
    if(troot) {
699
 
        ret = cli_lsig_eval(ctx, troot, &tdata, &info);
 
794
        if(ret != CL_VIRUS)
 
795
            ret = cli_lsig_eval(ctx, troot, &tdata, &info, refhash);
700
796
        cli_ac_freedata(&tdata);
701
797
        if(bm_offmode)
702
798
            cli_bm_freeoff(&toff);
704
800
 
705
801
    if(groot) {
706
802
        if(ret != CL_VIRUS)
707
 
            ret = cli_lsig_eval(ctx, groot, &gdata, &info);
 
803
            ret = cli_lsig_eval(ctx, groot, &gdata, &info, refhash);
708
804
        cli_ac_freedata(&gdata);
709
805
    }
710
806
 
715
811
    if(ret == CL_VIRUS)
716
812
        return CL_VIRUS;
717
813
 
718
 
    if(!ftonly && ctx->engine->md5_hdb) {
719
 
        if(!refhash) {
720
 
            cli_md5_final(digest, &md5ctx);
721
 
            refhash = digest;
722
 
        }
723
 
        if(cli_md5m_scan(refhash, map->len, ctx->virname, ctx->engine->md5_hdb) == CL_VIRUS && cli_md5m_scan(refhash, map->len, NULL, ctx->engine->md5_fp) != CL_VIRUS)
724
 
            return CL_VIRUS;
725
 
    }
726
 
 
727
814
    return (acmode & AC_SCAN_FT) ? type : CL_CLEAN;
728
815
}
729
816
 
730
 
int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, int filepos, int res1, void *res2)
 
817
int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, unsigned int filepos, int res1, void *res2)
731
818
{
732
819
        const struct cli_cdb *cdb;
733
820