~ubuntu-branches/ubuntu/precise/clamav/precise-updates

« back to all changes in this revision

Viewing changes to libclamav/ooxml.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2015-01-30 09:01:52 UTC
  • mfrom: (118.1.5 precise-security)
  • Revision ID: package-import@ubuntu.com-20150130090152-es6oz6eg0wsa4r40
Tags: 0.98.6+dfsg-0ubuntu0.12.04.1
* Updated to 0.98.6 to fix security issues, including CVE-2014-9328.
* Removed upstreamed patches:
  - d/p/0002-Add-an-additional-n-after-the-number-in-the-pidfile.patch
  - d/p/0017-Bump-.so-version-number.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
78
78
    return 1;
79
79
}
80
80
 
 
81
static int ooxml_add_parse_error(json_object *wrkptr, const xmlChar *errstr)
 
82
{
 
83
    json_object *perr;
 
84
 
 
85
    if (!wrkptr)
 
86
        return CL_ENULLARG;
 
87
 
 
88
    perr = cli_jsonarray(wrkptr, "ParseErrors");
 
89
    if (perr == NULL) {
 
90
        return CL_EMEM;
 
91
    }
 
92
 
 
93
    return cli_jsonstr(perr, NULL, errstr);
 
94
}
 
95
 
81
96
static int ooxml_parse_value(json_object *wrkptr, const char *arrname, const xmlChar *node_value)
82
97
{
83
98
    json_object *newobj, *arrobj;
84
99
    int val;
85
100
 
 
101
    if (!wrkptr)
 
102
        return CL_ENULLARG;
 
103
 
86
104
    arrobj = cli_jsonarray(wrkptr, arrname);
87
105
    if (arrobj == NULL) {
88
106
        return CL_EMEM;
247
265
 
248
266
    if (node_type != XML_READER_TYPE_ELEMENT) {
249
267
        cli_dbgmsg("ooxml_parse_element: first node typed %d, not %d\n", node_type, XML_READER_TYPE_ELEMENT);
250
 
        return CL_EPARSE; /* first type is not an element */
 
268
        return CL_EFORMAT; /* first type is not an element */
251
269
    }
252
270
 
253
271
    node_name = xmlTextReaderConstLocalName(reader);
267
285
    /* generate json object */
268
286
    thisjobj = cli_jsonobj(wrkptr, element_tag);
269
287
    if (!thisjobj) {
270
 
        return CL_EPARSE;
 
288
        return CL_EMEM;
271
289
    }
272
290
    cli_dbgmsg("ooxml_parse_element: generated json object [%s]\n", element_tag);
273
291
 
386
404
    return CL_SUCCESS;
387
405
}
388
406
 
 
407
static int ooxml_updatelimits(int fd, cli_ctx *ctx)
 
408
{
 
409
    STATBUF sb;
 
410
    if (FSTAT(fd, &sb) == -1) {
 
411
        cli_errmsg("ooxml_updatelimits: Can't fstat descriptor %d\n", fd);
 
412
        return CL_ESTAT;
 
413
    }
 
414
 
 
415
    return cli_updatelimits(ctx, sb.st_size);
 
416
}
 
417
 
389
418
static int ooxml_parse_document(int fd, cli_ctx *ctx)
390
419
{
391
420
    int ret = CL_SUCCESS;
393
422
 
394
423
    cli_dbgmsg("in ooxml_parse_document\n");
395
424
 
 
425
    /* perform engine limit checks in temporary tracking session */
 
426
    ret = ooxml_updatelimits(fd, ctx);
 
427
    if (ret != CL_CLEAN)
 
428
        return ret;
 
429
 
396
430
    reader = xmlReaderForFd(fd, "properties.xml", NULL, CLAMAV_MIN_XMLREADER_FLAGS);
397
431
    if (reader == NULL) {
398
432
        cli_dbgmsg("ooxml_parse_document: xmlReaderForFd error\n");
406
440
 
407
441
    ret = ooxml_parse_element(ctx, reader, ctx->wrkproperty, 0, NULL);
408
442
 
409
 
    if (ret != CL_SUCCESS && ret != CL_ETIMEOUT && ret != CL_BREAK) {
 
443
    if (ret != CL_SUCCESS && ret != CL_ETIMEOUT && ret != CL_BREAK)
410
444
        cli_warnmsg("ooxml_parse_document: encountered issue in parsing properties document\n");
411
 
        cli_jsonbool(ctx->wrkproperty, "ParseError", 1);
412
 
    }
413
445
 
414
446
    xmlTextReaderClose(reader);
415
447
    xmlFreeTextReader(reader);
418
450
 
419
451
static int ooxml_core_cb(int fd, cli_ctx *ctx)
420
452
{
 
453
    int ret;
 
454
 
421
455
    cli_dbgmsg("in ooxml_core_cb\n");
422
 
    return ooxml_parse_document(fd, ctx);
423
 
    //return ooxml_basic_json(fd, ctx, "CoreProperties");
 
456
    ret = ooxml_parse_document(fd, ctx);
 
457
    if (ret == CL_EPARSE)
 
458
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_CORE_XMLPARSER");
 
459
    else if (ret == CL_EFORMAT)
 
460
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_CORE_MALFORMED");
 
461
 
 
462
    return ret;
424
463
}
425
464
 
426
465
static int ooxml_extn_cb(int fd, cli_ctx *ctx)
427
466
{
 
467
    int ret;
 
468
 
428
469
    cli_dbgmsg("in ooxml_extn_cb\n");
429
 
    return ooxml_parse_document(fd, ctx);
430
 
    //return ooxml_basic_json(fd, ctx, "ExtendedProperties");
 
470
    ret = ooxml_parse_document(fd, ctx);
 
471
    if (ret == CL_EPARSE)
 
472
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_EXTN_XMLPARSER");
 
473
    else if (ret == CL_EFORMAT)
 
474
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_EXTN_MALFORMED");
 
475
 
 
476
    return ret;
431
477
}
432
478
 
433
479
static int ooxml_content_cb(int fd, cli_ctx *ctx)
434
480
{
435
 
    int ret = CL_SUCCESS, tmp, toval = 0;
 
481
    int ret = CL_SUCCESS, tmp, toval = 0, state;
436
482
    int core=0, extn=0, cust=0, dsig=0;
437
483
    int mcore=0, mextn=0, mcust=0;
438
484
    const xmlChar *name, *value, *CT, *PN;
439
485
    xmlTextReaderPtr reader = NULL;
440
486
    uint32_t loff;
441
487
 
 
488
    unsigned long sav_scansize = ctx->scansize;
 
489
    unsigned int sav_scannedfiles = ctx->scannedfiles;
 
490
 
442
491
    cli_dbgmsg("in ooxml_content_cb\n");
443
492
 
 
493
    /* perform engine limit checks in temporary tracking session */
 
494
    ret = ooxml_updatelimits(fd, ctx);
 
495
    if (ret != CL_CLEAN)
 
496
        return ret;
 
497
 
 
498
    /* apply a reader to the document */
444
499
    reader = xmlReaderForFd(fd, "[Content_Types].xml", NULL, CLAMAV_MIN_XMLREADER_FLAGS);
445
500
    if (reader == NULL) {
446
501
        cli_dbgmsg("ooxml_content_cb: xmlReaderForFd error for ""[Content_Types].xml""\n");
 
502
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_XML_READER_FD");
 
503
 
 
504
        ctx->scansize = sav_scansize;
 
505
        ctx->scannedfiles = sav_scannedfiles;
447
506
        return CL_SUCCESS; // libxml2 failed!
448
507
    }
449
508
 
450
 
    /* locate core-properties, extended-properties, and custom-properties (optional)  */
451
 
    while (xmlTextReaderRead(reader) == 1) {
 
509
    /* locate core-properties, extended-properties, and custom-properties (optional) */
 
510
    while ((state = xmlTextReaderRead(reader)) == 1) {
452
511
        if (cli_json_timeout_cycle_check(ctx, &toval) != CL_SUCCESS) {
453
512
            ret = CL_ETIMEOUT;
454
513
            goto ooxml_content_exit;
480
539
        if (!CT && !PN) continue;
481
540
 
482
541
        if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-package.core-properties+xml")) {
483
 
            if (!core) {
484
 
                /* default: /docProps/core.xml*/
485
 
                tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
486
 
                if (tmp == CL_ETIMEOUT) {
487
 
                    ret = tmp;
488
 
                }
489
 
                else if (tmp != CL_VIRUS) {
490
 
                    cli_dbgmsg("cli_process_ooxml: failed to find core properties file \"%s\"!\n", PN);
491
 
                    mcore++;
492
 
                }
493
 
                else {
494
 
                    cli_dbgmsg("ooxml_content_cb: found core properties file \"%s\" @ %x\n", PN, loff);
495
 
                    ret = unzip_single_internal(ctx, loff, ooxml_core_cb);
496
 
                    core++;
497
 
                }
 
542
            /* default: /docProps/core.xml*/
 
543
            tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
 
544
            if (tmp == CL_ETIMEOUT) {
 
545
                ret = tmp;
 
546
            }
 
547
            else if (tmp != CL_VIRUS) {
 
548
                cli_dbgmsg("cli_process_ooxml: failed to find core properties file \"%s\"!\n", PN);
 
549
                mcore++;
 
550
            }
 
551
            else {
 
552
                cli_dbgmsg("ooxml_content_cb: found core properties file \"%s\" @ %x\n", PN, loff);
 
553
                if (!core) {
 
554
                    tmp = unzip_single_internal(ctx, loff, ooxml_core_cb);
 
555
                    if (tmp == CL_ETIMEOUT || tmp == CL_EMEM) {
 
556
                        ret = tmp;
 
557
                    }
 
558
                }
 
559
                core++;
498
560
            }
499
561
        }
500
562
        else if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-officedocument.extended-properties+xml")) {
501
 
            if (!extn) {
502
 
                /* default: /docProps/app.xml */
503
 
                tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
504
 
                if (tmp == CL_ETIMEOUT) {
505
 
                    ret = tmp;
506
 
                }
507
 
                else if (tmp != CL_VIRUS) {
508
 
                    cli_dbgmsg("cli_process_ooxml: failed to find extended properties file \"%s\"!\n", PN);
509
 
                    mextn++;
510
 
                }
511
 
                else {
512
 
                    cli_dbgmsg("ooxml_content_cb: found extended properties file \"%s\" @ %x\n", PN, loff);
513
 
                    ret = unzip_single_internal(ctx, loff, ooxml_extn_cb);
514
 
                    extn++;
515
 
                }
 
563
            /* default: /docProps/app.xml */
 
564
            tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
 
565
            if (tmp == CL_ETIMEOUT) {
 
566
                ret = tmp;
 
567
            }
 
568
            else if (tmp != CL_VIRUS) {
 
569
                cli_dbgmsg("cli_process_ooxml: failed to find extended properties file \"%s\"!\n", PN);
 
570
                mextn++;
 
571
            }
 
572
            else {
 
573
                cli_dbgmsg("ooxml_content_cb: found extended properties file \"%s\" @ %x\n", PN, loff);
 
574
                if (!extn) {
 
575
                    tmp = unzip_single_internal(ctx, loff, ooxml_extn_cb);
 
576
                    if (tmp == CL_ETIMEOUT || tmp == CL_EMEM) {
 
577
                        ret = tmp;
 
578
                    }
 
579
                }
 
580
                extn++;
516
581
            }
517
582
        }
518
583
        else if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-officedocument.custom-properties+xml")) {
519
 
            if (!cust) {
520
 
                /* default: /docProps/custom.xml */
521
 
                tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
522
 
                if (tmp == CL_ETIMEOUT) {
523
 
                    ret = tmp;
524
 
                }
525
 
                else if (tmp != CL_VIRUS) {
526
 
                    cli_dbgmsg("cli_process_ooxml: failed to find custom properties file \"%s\"!\n", PN);
527
 
                    mcust++;
528
 
                }
529
 
                else {
530
 
                    cli_dbgmsg("ooxml_content_cb: found custom properties file \"%s\" @ %x\n", PN, loff);
531
 
                    cust++;
532
 
                    //ret = unzip_single_internal(ctx, loff, ooxml_cust_cb);
533
 
                }
 
584
            /* default: /docProps/custom.xml */
 
585
            tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
 
586
            if (tmp == CL_ETIMEOUT) {
 
587
                ret = tmp;
 
588
            }
 
589
            else if (tmp != CL_VIRUS) {
 
590
                cli_dbgmsg("cli_process_ooxml: failed to find custom properties file \"%s\"!\n", PN);
 
591
                mcust++;
 
592
            }
 
593
            else {
 
594
                cli_dbgmsg("ooxml_content_cb: found custom properties file \"%s\" @ %x\n", PN, loff);
 
595
                /* custom properties are not parsed */
 
596
                cust++;
534
597
            }
535
598
        }
536
599
        else if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml")) {
537
600
            dsig++;
538
601
        }
539
602
 
540
 
        if (ret != CL_BREAK && ret != CL_SUCCESS)
 
603
        if (ret != CL_SUCCESS)
541
604
            goto ooxml_content_exit;
542
605
    }
543
606
 
544
607
 ooxml_content_exit:
545
 
    if (core)
 
608
    if (core) {
546
609
        cli_jsonint(ctx->wrkproperty, "CorePropertiesFileCount", core);
 
610
        if (core > 1)
 
611
            ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_MULTIPLE_CORE_PROPFILES");
 
612
    }
547
613
    else if (!mcore)
548
614
        cli_dbgmsg("cli_process_ooxml: file does not contain core properties file\n");
549
 
    if (mcore)
550
 
        cli_jsonint(ctx->wrkproperty, "CorePropertiesMissingFileCount", core);
 
615
    if (mcore) {
 
616
        cli_jsonint(ctx->wrkproperty, "CorePropertiesMissingFileCount", mcore);
 
617
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_MISSING_CORE_PROPFILES");
 
618
    }
551
619
 
552
 
    if (extn)
 
620
    if (extn) {
553
621
        cli_jsonint(ctx->wrkproperty, "ExtendedPropertiesFileCount", extn);
 
622
        if (extn > 1)
 
623
            ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_MULTIPLE_EXTN_PROPFILES");
 
624
    }
554
625
    else if (!mextn)
555
626
        cli_dbgmsg("cli_process_ooxml: file does not contain extended properties file\n");
556
 
    if (mextn)
557
 
        cli_jsonint(ctx->wrkproperty, "ExtendedPropertiesMissingFileCount", extn);
 
627
    if (mextn) {
 
628
        cli_jsonint(ctx->wrkproperty, "ExtendedPropertiesMissingFileCount", mextn);
 
629
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_MISSING_EXTN_PROPFILES");
 
630
    }
558
631
 
559
 
    if (cust)
 
632
    if (cust) {
560
633
        cli_jsonint(ctx->wrkproperty, "CustomPropertiesFileCount", cust);
 
634
        if (cust > 1)
 
635
            ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_MULTIPLE_CUSTOM_PROPFILES");
 
636
    }
561
637
    else if (!mcust)
562
638
        cli_dbgmsg("cli_process_ooxml: file does not contain custom properties file\n");
563
 
    if (mcust)
564
 
        cli_jsonint(ctx->wrkproperty, "CustomPropertiesMissingFileCount", cust);
 
639
    if (mcust) {
 
640
        cli_jsonint(ctx->wrkproperty, "CustomPropertiesMissingFileCount", mcust);
 
641
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_MISSING_CUST_PROPFILES");
 
642
    }
565
643
 
566
644
    if (dsig) {
567
645
        cli_jsonint(ctx->wrkproperty, "DigitalSignaturesCount", dsig);
568
646
    }
569
647
 
 
648
    /* restore the engine tracking limits; resets session limit tracking */
 
649
    ctx->scansize = sav_scansize;
 
650
    ctx->scannedfiles = sav_scannedfiles;
 
651
 
570
652
    xmlTextReaderClose(reader);
571
653
    xmlFreeTextReader(reader);
572
654
    return ret;
620
702
    /* find "[Content Types].xml" */
621
703
    tmp = unzip_search_single(ctx, "[Content_Types].xml", 18, &loff);
622
704
    if (tmp == CL_ETIMEOUT) {
 
705
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_TIMEOUT");
623
706
        return CL_ETIMEOUT;
624
707
    }
625
708
    else if (tmp != CL_VIRUS) {
626
709
        cli_dbgmsg("cli_process_ooxml: failed to find ""[Content_Types].xml""!\n");
 
710
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_NO_CONTENT_TYPES");
627
711
        return CL_EFORMAT;
628
712
    }
629
713
    cli_dbgmsg("cli_process_ooxml: found ""[Content_Types].xml"" @ %x\n", loff);
630
714
 
631
 
    return unzip_single_internal(ctx, loff, ooxml_content_cb);
 
715
    tmp = unzip_single_internal(ctx, loff, ooxml_content_cb);
 
716
    if (tmp == CL_ETIMEOUT)
 
717
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_TIMEOUT");
 
718
    else if (tmp == CL_EMEM)
 
719
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_OUTOFMEM");
 
720
    else if (tmp == CL_EMAXSIZE)
 
721
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_EMAXSIZE");
 
722
    else if (tmp == CL_EMAXFILES)
 
723
        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_EMAXFILES");
 
724
 
 
725
    return tmp;
632
726
#else
633
727
    UNUSEDPARAM(ctx);
634
728
    cli_dbgmsg("in cli_processooxml\n");