db-d2/primevul-codebert-embeddings huggingface dataset:
Commit message: None
CVE: CVE-2014-9766
CWE: CWE-189
Vulnerability description: Integer overflow in the create_bits function in pixman-bits-image.c in Pixman before 0.32.6 allows remote attackers to cause a denial of service (application crash) or possibly execute arbitrary code via large height and stride values.

Project: pixman

create_bits (pixman_format_code_t format,
             int                  width,
             int                  height,
             int *		  rowstride_bytes,
	     pixman_bool_t	  clear)
{
    int stride;
    size_t buf_size;
    int bpp;

    /* what follows is a long-winded way, avoiding any possibility of integer
     * overflows, of saying:
     * stride = ((width * bpp + 0x1f) >> 5) * sizeof (uint32_t);
     */

    bpp = PIXMAN_FORMAT_BPP (format);
    if (_pixman_multiply_overflows_int (width, bpp))
	return NULL;

    stride = width * bpp;
    if (_pixman_addition_overflows_int (stride, 0x1f))
	return NULL;

    stride += 0x1f;
    stride >>= 5;

    stride *= sizeof (uint32_t);

     if (_pixman_multiply_overflows_size (height, stride))
 	return NULL;
 
    buf_size = (size_t)height * stride;
 
     if (rowstride_bytes)
 	*rowstride_bytes = stride;

    if (clear)
	return calloc (buf_size, 1);
    else
	return malloc (buf_size);
}
Commit message: vmxnet3: validate interrupt indices read on migration

CVE-2013-4544

Signed-off-by: Dmitry Fleytman <dmitry@daynix.com>
Reported-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Message-id: 1396604722-11902-4-git-send-email-dmitry@daynix.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
CVE: CVE-2013-4544
CWE: CWE-20
Vulnerability description: hw/net/vmxnet3.c in QEMU 2.0.0-rc0, 1.7.1, and earlier allows local guest users to cause a denial of service or possibly execute arbitrary code via vectors related to (1) RX or (2) TX queue numbers or (3) interrupt indices.  NOTE: some of these details are obtained from third party information.

Project: qemu
File: vmxnet3.c

static int vmxnet3_post_load(void *opaque, int version_id)
{
    VMXNET3State *s = opaque;
    PCIDevice *d = PCI_DEVICE(s);

    vmxnet_tx_pkt_init(&s->tx_pkt, s->max_tx_frags, s->peer_has_vhdr);
    vmxnet_rx_pkt_init(&s->rx_pkt, s->peer_has_vhdr);

    if (s->msix_used) {
        if  (!vmxnet3_use_msix_vectors(s, VMXNET3_MAX_INTRS)) {
            VMW_WRPRN("Failed to re-use MSI-X vectors");
            msix_uninit(d, &s->msix_bar, &s->msix_bar);
            s->msix_used = false;
            return -1;
         }
     }
 
    vmxnet3_validate_interrupts(s);

     return 0;
 }
Commit message: tsc210x: fix buffer overrun on invalid state load

CVE-2013-4539

s->precision, nextprecision, function and nextfunction
come from wire and are used
as idx into resolution[] in TSC_CUT_RESOLUTION.

Validate after load to avoid buffer overrun.

Cc: Andreas Färber <afaerber@suse.de>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
CVE: CVE-2013-4539
CWE: CWE-119
Vulnerability description: Multiple buffer overflows in the tsc210x_load function in hw/input/tsc210x.c in QEMU before 1.7.2 might allow remote attackers to execute arbitrary code via a crafted (1) precision, (2) nextprecision, (3) function, or (4) nextfunction value in a savevm image.

Project: qemu

static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
{
    TSC210xState *s = (TSC210xState *) opaque;
    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    int i;

    s->x = qemu_get_be16(f);
    s->y = qemu_get_be16(f);
    s->pressure = qemu_get_byte(f);

    s->state = qemu_get_byte(f);
    s->page = qemu_get_byte(f);
    s->offset = qemu_get_byte(f);
    s->command = qemu_get_byte(f);

    s->irq = qemu_get_byte(f);
    qemu_get_be16s(f, &s->dav);

    timer_get(f, s->timer);
     s->enabled = qemu_get_byte(f);
     s->host_mode = qemu_get_byte(f);
     s->function = qemu_get_byte(f);
    if (s->function < 0 || s->function >= ARRAY_SIZE(mode_regs)) {
        return -EINVAL;
    }
     s->nextfunction = qemu_get_byte(f);
    if (s->nextfunction < 0 || s->nextfunction >= ARRAY_SIZE(mode_regs)) {
        return -EINVAL;
    }
     s->precision = qemu_get_byte(f);
    if (s->precision < 0 || s->precision >= ARRAY_SIZE(resolution)) {
        return -EINVAL;
    }
     s->nextprecision = qemu_get_byte(f);
    if (s->nextprecision < 0 || s->nextprecision >= ARRAY_SIZE(resolution)) {
        return -EINVAL;
    }
     s->filter = qemu_get_byte(f);
     s->pin_func = qemu_get_byte(f);
     s->ref = qemu_get_byte(f);
    qemu_get_be16s(f, &s->dac_power);

    for (i = 0; i < 0x14; i ++)
        qemu_get_be16s(f, &s->filter_data[i]);

    s->busy = timer_pending(s->timer);
    qemu_set_irq(s->pint, !s->irq);
    qemu_set_irq(s->davint, !s->dav);

    return 0;
}
Commit message: ssd0323: fix buffer overun on invalid state load

CVE-2013-4538

s->cmd_len used as index in ssd0323_transfer() to store 32-bit field.
Possible this field might then be supplied by guest to overwrite a
return addr somewhere. Same for row/col fields, which are indicies into
framebuffer array.

To fix validate after load.

Additionally, validate that the row/col_start/end are within bounds;
otherwise the guest can provoke an overrun by either setting the _end
field so large that the row++ increments just walk off the end of the
array, or by setting the _start value to something bogus and then
letting the "we hit end of row" logic reset row to row_start.

For completeness, validate mode as well.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Juan Quintela <quintela@redhat.com>
CVE: CVE-2013-4538
CWE: CWE-119
Vulnerability description: Multiple buffer overflows in the ssd0323_load function in hw/display/ssd0323.c in QEMU before 1.7.2 allow remote attackers to cause a denial of service (memory corruption) or possibly execute arbitrary code via crafted (1) cmd_len, (2) row, or (3) col values; (4) row_start and row_end values; or (5) col_star and col_end values in a savevm image.

Project: qemu

static int ssd0323_load(QEMUFile *f, void *opaque, int version_id)
{
    SSISlave *ss = SSI_SLAVE(opaque);
    ssd0323_state *s = (ssd0323_state *)opaque;
    int i;

    if (version_id != 1)
         return -EINVAL;
 
     s->cmd_len = qemu_get_be32(f);
    if (s->cmd_len < 0 || s->cmd_len > ARRAY_SIZE(s->cmd_data)) {
        return -EINVAL;
    }
     s->cmd = qemu_get_be32(f);
     for (i = 0; i < 8; i++)
         s->cmd_data[i] = qemu_get_be32(f);
     s->row = qemu_get_be32(f);
    if (s->row < 0 || s->row >= 80) {
        return -EINVAL;
    }
     s->row_start = qemu_get_be32(f);
    if (s->row_start < 0 || s->row_start >= 80) {
        return -EINVAL;
    }
     s->row_end = qemu_get_be32(f);
    if (s->row_end < 0 || s->row_end >= 80) {
        return -EINVAL;
    }
     s->col = qemu_get_be32(f);
    if (s->col < 0 || s->col >= 64) {
        return -EINVAL;
    }
     s->col_start = qemu_get_be32(f);
    if (s->col_start < 0 || s->col_start >= 64) {
        return -EINVAL;
    }
     s->col_end = qemu_get_be32(f);
    if (s->col_end < 0 || s->col_end >= 64) {
        return -EINVAL;
    }
     s->redraw = qemu_get_be32(f);
     s->remap = qemu_get_be32(f);
     s->mode = qemu_get_be32(f);
    if (s->mode != SSD0323_CMD && s->mode != SSD0323_DATA) {
        return -EINVAL;
    }
     qemu_get_buffer(f, s->framebuffer, sizeof(s->framebuffer));
 
     ss->cs = qemu_get_be32(f);
}
Commit message: ssi-sd: fix buffer overrun on invalid state load

CVE-2013-4537

s->arglen is taken from wire and used as idx
in ssi_sd_transfer().

Validate it before access.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
CVE: CVE-2013-4537
CWE: CWE-94
Vulnerability description: The ssi_sd_transfer function in hw/sd/ssi-sd.c in QEMU before 1.7.2 allows remote attackers to execute arbitrary code via a crafted arglen value in a savevm image.

Project: qemu

static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id)
{
    SSISlave *ss = SSI_SLAVE(opaque);
    ssi_sd_state *s = (ssi_sd_state *)opaque;
    int i;

    if (version_id != 1)
        return -EINVAL;

    s->mode = qemu_get_be32(f);
    s->cmd = qemu_get_be32(f);
    for (i = 0; i < 4; i++)
        s->cmdarg[i] = qemu_get_be32(f);
     for (i = 0; i < 5; i++)
         s->response[i] = qemu_get_be32(f);
     s->arglen = qemu_get_be32(f);
    if (s->mode == SSI_SD_CMDARG &&
        (s->arglen < 0 || s->arglen >= ARRAY_SIZE(s->cmdarg))) {
        return -EINVAL;
    }
     s->response_pos = qemu_get_be32(f);
     s->stopping = qemu_get_be32(f);
    if (s->mode == SSI_SD_RESPONSE &&
        (s->response_pos < 0 || s->response_pos >= ARRAY_SIZE(s->response) ||
        (!s->stopping && s->arglen > ARRAY_SIZE(s->response)))) {
        return -EINVAL;
    }
 
     ss->cs = qemu_get_be32(f);
    s->mode = SSI_SD_CMD;
    dinfo = drive_get_next(IF_SD);
    s->sd = sd_init(dinfo ? dinfo->bdrv : NULL, true);
    if (s->sd == NULL) {
        return -1;
    }
    register_savevm(dev, "ssi_sd", -1, 1, ssi_sd_save, ssi_sd_load, s);
    return 0;
}
Commit message: vmstate: fix buffer overflow in target-arm/machine.c

CVE-2013-4531

cpreg_vmstate_indexes is a VARRAY_INT32. A negative value for
cpreg_vmstate_array_len will cause a buffer overflow.

VMSTATE_INT32_LE was supposed to protect against this
but doesn't because it doesn't validate that input is
non-negative.

Fix this macro to valide the value appropriately.

The only other user of VMSTATE_INT32_LE doesn't
ever use negative numbers so it doesn't care.

Reported-by: Anthony Liguori <anthony@codemonkey.ws>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
CVE: CVE-2013-4531
CWE: CWE-119
Vulnerability description: Buffer overflow in target-arm/machine.c in QEMU before 1.7.2 allows remote attackers to cause a denial of service and possibly execute arbitrary code via a negative value in cpreg_vmstate_array_len in a savevm image.

Project: qemu

 static int get_int32_le(QEMUFile *f, void *pv, size_t size)
 {
    int32_t loaded;
     int32_t loaded;
     qemu_get_sbe32s(f, &loaded);
 
    if (loaded >= 0 && loaded <= *cur) {
         *cur = loaded;
         return 0;
     }
}
Commit message: virtio-net: out-of-bounds buffer write on load

CVE-2013-4149 QEMU 1.3.0 out-of-bounds buffer write in
virtio_net_load()@hw/net/virtio-net.c

>         } else if (n->mac_table.in_use) {
>             uint8_t *buf = g_malloc0(n->mac_table.in_use);

We are allocating buffer of size n->mac_table.in_use

>             qemu_get_buffer(f, buf, n->mac_table.in_use * ETH_ALEN);

and read to the n->mac_table.in_use size buffer n->mac_table.in_use *
ETH_ALEN bytes, corrupting memory.

If adversary controls state then memory written there is controlled
by adversary.

Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
CVE: CVE-2013-4149
CWE: CWE-119
Vulnerability description: Buffer overflow in virtio_net_load function in net/virtio-net.c in QEMU 1.3.0 through 1.7.x before 1.7.2 might allow remote attackers to execute arbitrary code via a large MAC table.

Project: qemu

static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
{
    VirtIONet *n = opaque;
    VirtIODevice *vdev = VIRTIO_DEVICE(n);
    int ret, i, link_down;

    if (version_id < 2 || version_id > VIRTIO_NET_VM_VERSION)
        return -EINVAL;

    ret = virtio_load(vdev, f);
    if (ret) {
        return ret;
    }

    qemu_get_buffer(f, n->mac, ETH_ALEN);
    n->vqs[0].tx_waiting = qemu_get_be32(f);

    virtio_net_set_mrg_rx_bufs(n, qemu_get_be32(f));

    if (version_id >= 3)
        n->status = qemu_get_be16(f);

    if (version_id >= 4) {
        if (version_id < 8) {
            n->promisc = qemu_get_be32(f);
            n->allmulti = qemu_get_be32(f);
        } else {
            n->promisc = qemu_get_byte(f);
            n->allmulti = qemu_get_byte(f);
        }
    }

    if (version_id >= 5) {
        n->mac_table.in_use = qemu_get_be32(f);
        /* MAC_TABLE_ENTRIES may be different from the saved image */
         if (n->mac_table.in_use <= MAC_TABLE_ENTRIES) {
             qemu_get_buffer(f, n->mac_table.macs,
                             n->mac_table.in_use * ETH_ALEN);
        } else {
            int64_t i;

            /* Overflow detected - can happen if source has a larger MAC table.
             * We simply set overflow flag so there's no need to maintain the
             * table of addresses, discard them all.
             * Note: 64 bit math to avoid integer overflow.
             */
            for (i = 0; i < (int64_t)n->mac_table.in_use * ETH_ALEN; ++i) {
                qemu_get_byte(f);
            }
             n->mac_table.multi_overflow = n->mac_table.uni_overflow = 1;
             n->mac_table.in_use = 0;
         }
            error_report("virtio-net: saved image requires vnet_hdr=on");
            return -1;
        }
    }
Commit message: None
CVE: CVE-2017-18238
CWE: CWE-835
Vulnerability description: An issue was discovered in Exempi before 2.4.4. The TradQT_Manager::ParseCachedBoxes function in XMPFiles/source/FormatSupport/QuickTime_Support.cpp allows remote attackers to cause a denial of service (infinite loop) via crafted XMP data in a .qt file.

Project: exempi

bool TradQT_Manager::ParseCachedBoxes ( const MOOV_Manager & moovMgr )
{
	MOOV_Manager::BoxInfo udtaInfo;
	MOOV_Manager::BoxRef  udtaRef = moovMgr.GetBox ( "moov/udta", &udtaInfo );
	if ( udtaRef == 0 ) return false;

	for ( XMP_Uns32 i = 0; i < udtaInfo.childCount; ++i ) {

		MOOV_Manager::BoxInfo currInfo;
		MOOV_Manager::BoxRef  currRef = moovMgr.GetNthChild ( udtaRef, i, &currInfo );
		if ( currRef == 0 ) break;	// Sanity check, should not happen.
		if ( (currInfo.boxType >> 24) != 0xA9 ) continue;
		if ( currInfo.contentSize < 2+2+1 ) continue;	// Want enough for a non-empty value.
		
		InfoMapPos newInfo = this->parsedBoxes.insert ( this->parsedBoxes.end(),
														InfoMap::value_type ( currInfo.boxType, ParsedBoxInfo ( currInfo.boxType ) ) );
		std::vector<ValueInfo> * newValues = &newInfo->second.values;
		
		XMP_Uns8 * boxPtr = (XMP_Uns8*) currInfo.content;
		XMP_Uns8 * boxEnd = boxPtr + currInfo.contentSize;
		XMP_Uns16 miniLen, macLang;

		for ( ; boxPtr < boxEnd-4; boxPtr += miniLen ) {
 
 			miniLen = 4 + GetUns16BE ( boxPtr );	// ! Include header in local miniLen.
 			macLang  = GetUns16BE ( boxPtr+2);
			if ( (miniLen <= 4) || (miniLen > (boxEnd - boxPtr)) )
				break;	// Ignore bad or empty values.
 			
 			XMP_StringPtr valuePtr = (char*)(boxPtr+4);
 			size_t valueLen = miniLen - 4;
			newValues->push_back ( ValueInfo() );
			ValueInfo * newValue = &newValues->back();
			
			
			newValue->macLang = macLang;
			if ( IsMacLangKnown ( macLang ) ) newValue->xmpLang = GetXMPLang ( macLang );
			newValue->macValue.assign ( valuePtr, valueLen );

		}

	}
	
	return (! this->parsedBoxes.empty());

}	// TradQT_Manager::ParseCachedBoxes
Commit message: None
CVE: CVE-2017-18233
CWE: CWE-190
Vulnerability description: An issue was discovered in Exempi before 2.4.4. Integer overflow in the Chunk class in XMPFiles/source/FormatSupport/RIFF.cpp allows remote attackers to cause a denial of service (infinite loop) via crafted XMP data in a .avi file.

Project: exempi

Chunk::Chunk( ContainerChunk* parent, RIFF_MetaHandler* handler, bool skip, ChunkType c )
{
	chunkType = c; // base class assumption
	this->parent = parent;
	this->oldSize = 0;
	this->hasChange = false; // [2414649] valid assumption at creation time

	XMP_IO* file = handler->parent->ioRef;
 
 	this->oldPos = file->Offset();
 	this->id = XIO::ReadUns32_LE( file );
	this->oldSize = XIO::ReadUns32_LE( file );
	this->oldSize += 8;
 
 	XMP_Int64 chunkEnd = this->oldPos + this->oldSize;
	if ( parent != 0 ) chunkLimit = parent->oldPos + parent->oldSize;
	if ( chunkEnd > chunkLimit ) {
		bool isUpdate = XMP_OptionIsSet ( handler->parent->openFlags, kXMPFiles_OpenForUpdate );
		bool repairFile = XMP_OptionIsSet ( handler->parent->openFlags, kXMPFiles_OpenRepairFile );
		if ( (! isUpdate) || (repairFile && (parent == 0)) ) {
			this->oldSize = chunkLimit - this->oldPos;
		} else {
			XMP_Throw ( "Bad RIFF chunk size", kXMPErr_BadFileFormat );
		}
	}

	this->newSize = this->oldSize;
	this->needSizeFix = false;

	if ( skip ) file->Seek ( (this->oldSize - 8), kXMP_SeekFromCurrent );

	if ( this->parent != NULL )
	{
		this->parent->children.push_back( this );
		if( this->chunkType == chunk_VALUE )
			this->parent->childmap.insert( std::make_pair( this->id, (ValueChunk*) this ) );
	}
}
Commit message: cirrus: handle negative pitch in cirrus_invalidate_region()

cirrus_invalidate_region() calls memory_region_set_dirty()
on a per-line basis, always ranging from off_begin to
off_begin+bytesperline. With a negative pitch off_begin
marks the top most used address and thus we need to do an
initial shift backwards by a line for negative pitches of
backward blits, otherwise the first iteration covers the
line going from the start offset forwards instead of
backwards.
Additionally since the start address is inclusive, if we
shift by a full `bytesperline` we move to the first address
*not* included in the blit, so we only shift by one less
than bytesperline.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Message-id: 1485352137-29367-1-git-send-email-w.bumiller@proxmox.com

[ kraxel: codestyle fixes ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
CVE: CVE-2017-18030
CWE: CWE-125
Vulnerability description: The cirrus_invalidate_region function in hw/display/cirrus_vga.c in Qemu allows local OS guest privileged users to cause a denial of service (out-of-bounds array access and QEMU process crash) via vectors related to negative pitch.

Project: qemu

static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
				     int off_pitch, int bytesperline,
				     int lines)
{
    int y;
     int off_cur;
     int off_cur_end;
 
    if (off_pitch < 0) {
        off_begin -= bytesperline - 1;
    }

     for (y = 0; y < lines; y++) {
        off_cur = off_begin;
        off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
        assert(off_cur_end >= off_cur);
         memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur);
        off_begin += off_pitch;
     }
    uint8_t *dst;

    dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);

    if (blit_is_unsafe(s, false))
        return 0;

    (*s->cirrus_rop) (s, dst, src,
                      s->cirrus_blt_dstpitch, 0,
                      s->cirrus_blt_width, s->cirrus_blt_height);
    cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
                             s->cirrus_blt_dstpitch, s->cirrus_blt_width,
                             s->cirrus_blt_height);
    return 1;
}
Commit message: qcow2: Fix L1 allocation size in qcow2_snapshot_load_tmp() (CVE-2014-0145)

For the L1 table to loaded for an internal snapshot, the code allocated
only enough memory to hold the currently active L1 table. If the
snapshot's L1 table is actually larger than the current one, this leads
to a buffer overflow.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
CVE: CVE-2014-0145
CWE: CWE-119
Vulnerability description: Multiple buffer overflows in QEMU before 1.7.2 and 2.x before 2.0.0, allow local users to cause a denial of service (crash) or possibly execute arbitrary code via a large (1) L1 table in the qcow2_snapshot_load_tmp in the QCOW 2 block driver (block/qcow2-snapshot.c) or (2) uncompressed chunk, (3) chunk length, or (4) number of sectors in the DMG block driver (block/dmg.c).

Project: qemu
File: qcow2-snapshot.c

int qcow2_snapshot_load_tmp(BlockDriverState *bs,
                            const char *snapshot_id,
                            const char *name,
                            Error **errp)
{
    int i, snapshot_index;
    BDRVQcowState *s = bs->opaque;
    QCowSnapshot *sn;
    uint64_t *new_l1_table;
    int new_l1_bytes;
    int ret;

    assert(bs->read_only);

    /* Search the snapshot */
    snapshot_index = find_snapshot_by_id_and_name(bs, snapshot_id, name);
    if (snapshot_index < 0) {
        error_setg(errp,
                   "Can't find snapshot");
        return -ENOENT;
    }
     sn = &s->snapshots[snapshot_index];
 
     /* Allocate and read in the snapshot's L1 table */
    new_l1_bytes = sn->l1_size * sizeof(uint64_t);
     new_l1_table = g_malloc0(align_offset(new_l1_bytes, 512));
 
     ret = bdrv_pread(bs->file, sn->l1_table_offset, new_l1_table, new_l1_bytes);
    if (ret < 0) {
        error_setg(errp, "Failed to read l1 table for snapshot");
        g_free(new_l1_table);
        return ret;
    }

    /* Switch the L1 table */
    g_free(s->l1_table);

    s->l1_size = sn->l1_size;
    s->l1_table_offset = sn->l1_table_offset;
    s->l1_table = new_l1_table;

    for(i = 0;i < s->l1_size; i++) {
        be64_to_cpus(&s->l1_table[i]);
    }

    return 0;
}
Commit message: qcow2: Avoid integer overflow in get_refcount (CVE-2014-0143)

This ensures that the checks catch all invalid cluster indexes
instead of returning the refcount of a wrong cluster.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
CVE: CVE-2014-0143
CWE: CWE-190
Vulnerability description: Multiple integer overflows in the block drivers in QEMU, possibly before 2.0.0, allow local users to cause a denial of service (crash) via a crafted catalog size in (1) the parallels_open function in block/parallels.c or (2) bochs_open function in bochs.c, a large L1 table in the (3) qcow2_snapshot_load_tmp in qcow2-snapshot.c or (4) qcow2_grow_l1_table function in qcow2-cluster.c, (5) a large request in the bdrv_check_byte_request function in block.c and other block drivers, (6) crafted cluster indexes in the get_refcount function in qcow2-refcount.c, or (7) a large number of blocks in the cloop_open function in cloop.c, which trigger buffer overflows, memory corruption, large memory allocations and out-of-bounds read and writes.

Project: qemu
File: qcow2-refcount.c

 static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
 {
     BDRVQcowState *s = bs->opaque;
    uint64_t refcount_table_index, block_index;
     int64_t refcount_block_offset;
     int ret;
     uint16_t *refcount_block;
    uint16_t refcount;

    refcount_table_index = cluster_index >> (s->cluster_bits - REFCOUNT_SHIFT);
    if (refcount_table_index >= s->refcount_table_size)
        return 0;
    refcount_block_offset =
        s->refcount_table[refcount_table_index] & REFT_OFFSET_MASK;
    if (!refcount_block_offset)
        return 0;

    ret = qcow2_cache_get(bs, s->refcount_block_cache, refcount_block_offset,
        (void**) &refcount_block);
    if (ret < 0) {
        return ret;
    }

    block_index = cluster_index &
        ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
    refcount = be16_to_cpu(refcount_block[block_index]);

    ret = qcow2_cache_put(bs, s->refcount_block_cache,
        (void**) &refcount_block);
    if (ret < 0) {
        return ret;
    }

    return refcount;
}