CVE-2018-1000085 (C, published 2018-03-13T15:29Z)
Description: value: ClamAV version version 0.99.3 contains a Out of bounds heap memory read vulnerability in XAR parser, function xar_hash_check() that can result in Leaking of memory, may help in developing exploit chains.. This attack appear to be exploitable via The victim must scan a crafted XAR file. This vulnerability appears to have been fixed in after commit d96a6b8bcc7439fa7e3876207aa0a8e79c8451b6.
Severity: MEDIUM (CVSS v3 base score: 5.5)
Weakness: CWE-125 \u2014 Out-of-bounds Read
The product reads data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/Cisco-Talos/clamav-devel
Files changed:
libclamav/xar.c
Commit message: bb11588 - fix out of bounds read.


Vulnerable code:
static int xar_get_numeric_from_xml_element(xmlTextReaderPtr reader, long * value)
            *value = atol((const char *)numstr);
            if (*value < 0) {
            *cksum = xmlStrdup(xmlval); 
            cli_dbgmsg("cli_scanxar: checksum value is %s.\n", *cksum);
static int xar_get_toc_data_values(xmlTextReaderPtr reader, long *length, long *offset, long *size, int *encoding,
        len = SHA1_HASH_SIZE;
        len = CLI_HASH_MD5;
    long length, offset, size, at;
        cli_dbgmsg("cli_scanxar: decompress into temp file:\n%s, size %li,\n"
                   "from xar heap offset %li length %li\n",
                unsigned long in_remaining = length;
                
                    cli_dbgmsg("cli_scanxar: Can't read %li bytes @ %li, errno:%s.\n",
                               length, at, errbuff);
                                   length, at, errbuff);
                unsigned long write_len;
                
                    write_len = MIN((size_t)(ctx->engine->maxfilesize), (size_t)length);
                else
                    write_len = length;
                if (!(blockp = (void*)fmap_need_off_once(map, at, length))) {
                    cli_dbgmsg("cli_scanxar: Can't read %li bytes @ %li, errno:%s.\n",
                               length, at, errbuff);
                    xar_hash_update(a_hash_ctx, blockp, length, a_hash);
                if (cli_writen(fd, blockp, write_len) < 0) {
                    cli_dbgmsg("cli_scanxar: cli_writen error %li bytes @ %li.\n", length, at);
        }
        cli_warnmsg("cli_scanxar: %u checksum errors and %u extraction errors, use --debug for more info.\n",

Fixed code:
static int xar_get_numeric_from_xml_element(xmlTextReaderPtr reader, size_t * value)
    ssize_t numval;

            numval = atol((const char *)numstr);
            if (numval < 0) {
            *value = numval;
            cli_dbgmsg("cli_scanxar: checksum value is %s.\n", xmlval);
            if (*hash == XAR_CKSUM_SHA1 && xmlStrlen(xmlval) == 2 * CLI_HASHLEN_SHA1 ||
                *hash == XAR_CKSUM_MD5 && xmlStrlen(xmlval) == 2 * CLI_HASHLEN_MD5)
                {
                    *cksum = xmlStrdup(xmlval); 
                } 
            else
                {
                    cli_dbgmsg("cli_scanxar: checksum type is unknown or length is invalid.\n");
                    *hash = XAR_CKSUM_OTHER;
                    *cksum = NULL;
                }
static int xar_get_toc_data_values(xmlTextReaderPtr reader, size_t *length, size_t *offset, size_t *size, int *encoding,
        len = CLI_HASHLEN_SHA1;
        len = CLI_HASHLEN_MD5;
    size_t length, offset, size, at;
    if (hdr.toc_length_decompressed != strm.total_out) {
        cli_dbgmsg("TOC decompress length %" PRIu64 " does not match amount decompressed %lu\n",
                   hdr.toc_length_decompressed, strm.total_out);
        toc[strm.total_out] = '\0';
        hdr.toc_length_decompressed = strm.total_out;
    }

        cli_dbgmsg("cli_scanxar: decompress into temp file:\n%s, size %zu,\n"
                   "from xar heap offset %zu length %zu\n",
                unsigned long in_remaining = MIN(length, map->len - at);

                if (length > in_remaining)
                    length = in_remaining;

                    cli_dbgmsg("cli_scanxar: Can't read %i bytes @ %li, errno:%s.\n",
                               CLI_LZMA_HDR_SIZE, at, errbuff);
                                   lz.avail_in, at, errbuff);
                size_t writelen = MIN(map->len - at, length);

                    writelen = MIN((size_t)(ctx->engine->maxfilesize), writelen);
                if (!(blockp = (void*)fmap_need_off_once(map, at, writelen))) {
                    cli_dbgmsg("cli_scanxar: Can't read %zu bytes @ %zu, errno:%s.\n",
                               writelen, at, errbuff);
                    xar_hash_update(a_hash_ctx, blockp, writelen, a_hash);
                if (cli_writen(fd, blockp, writelen) < 0) {
                    cli_dbgmsg("cli_scanxar: cli_writen error %zu bytes @ %li.\n", writelen, at);
        } /* end of switch */
        cli_dbgmsg("cli_scanxar: %u checksum errors and %u extraction errors.\n",