db-d2/primevul-codebert-embeddings huggingface dataset:
Commit message: kvm: x86: fix kvm_apic_has_events to check for NULL pointer

Malicious (or egregiously buggy) userspace can trigger it, but it
should never happen in normal operation.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
CVE: CVE-2015-4692
CWE: CWE-703
Vulnerability description: The kvm_apic_has_events function in arch/x86/kvm/lapic.h in the Linux kernel through 4.1.3 allows local users to cause a denial of service (NULL pointer dereference and system crash) or possibly have unspecified other impact by leveraging /dev/kvm access for an ioctl call.

Project: linux
File: lapic.h

static inline bool kvm_lowest_prio_delivery(struct kvm_lapic_irq *irq)
{
	return (irq->delivery_mode == APIC_DM_LOWEST ||
			irq->msi_redir_hint);
}

Project: linux
File: lapic.h

static inline bool kvm_vcpu_has_lapic(struct kvm_vcpu *vcpu)
{
	if (static_key_false(&kvm_no_apic_vcpu))
		return vcpu->arch.apic;
	return true;
}

Project: linux
File: lapic.h

static inline bool kvm_apic_vid_enabled(struct kvm *kvm)
{
	return kvm_x86_ops->vm_has_apicv(kvm);
}

Project: linux
File: lapic.h

static inline int apic_x2apic_mode(struct kvm_lapic *apic)
{
	return apic->vcpu->arch.apic_base & X2APIC_ENABLE;
}

Project: linux
File: lapic.h

static inline int kvm_lapic_enabled(struct kvm_vcpu *vcpu)
{
	return kvm_apic_present(vcpu) && kvm_apic_sw_enabled(vcpu->arch.apic);
}

Project: linux
File: lapic.h

static inline u32 kvm_apic_get_reg(struct kvm_lapic *apic, int reg_off)
{
	        return *((u32 *) (apic->regs + reg_off));
}

Project: linux
File: lapic.h

static inline bool kvm_apic_sw_enabled(struct kvm_lapic *apic)
{
	if (static_key_false(&apic_sw_disabled.key))
		return apic->sw_enabled;
	return true;
}

Project: linux
File: lapic.h

static inline int kvm_apic_hw_enabled(struct kvm_lapic *apic)
{
	if (static_key_false(&apic_hw_disabled.key))
		return apic->vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE;
	return MSR_IA32_APICBASE_ENABLE;
}

Project: linux
File: lapic.h

static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu)
{
	return vcpu->arch.hv_vapic & HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE;
}

Project: linux
File: lapic.h

static inline bool kvm_apic_present(struct kvm_vcpu *vcpu)
{
	return kvm_vcpu_has_lapic(vcpu) && kvm_apic_hw_enabled(vcpu->arch.apic);
}

Project: linux
File: lapic.h

static inline bool kvm_apic_has_events(struct kvm_vcpu *vcpu)
{
	return kvm_vcpu_has_lapic(vcpu) && vcpu->arch.apic->pending_events;
}
Commit message: fixed #1757
CVE: CVE-2021-32135
CWE: CWE-787
Vulnerability description: The trak_box_size function in GPAC 1.0.1 allows attackers to cause a denial of service (NULL pointer dereference) via a crafted file in the MP4Box command.

Project: gpac
File: box_code_base.c


GF_Err trak_box_size(GF_Box *s)
{
	u32 pos=0;
	GF_TrackBox *ptr = (GF_TrackBox *)s;

	if (ptr->sample_encryption && ptr->sample_encryption->load_needed) {
		if (!ptr->moov || !!ptr->moov->mov || !ptr->moov->mov->movieFileMap)
			return GF_ISOM_INVALID_FILE;
		GF_Err e = senc_Parse(ptr->moov->mov->movieFileMap->bs, ptr, NULL, ptr->sample_encryption);
		if (e) return e;
	}

	gf_isom_check_position(s, (GF_Box *)ptr->Header, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->Aperture, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->References, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->editBox, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->Media, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->meta, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->groups, &pos);
	gf_isom_check_position(s, (GF_Box *)ptr->udta, &pos);
	return GF_OK;
Commit message: Adds bound check in oracle protocol

Found by oss-fuzz
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=21780
CVE: CVE-2020-15476
CWE: CWE-125
Vulnerability description: In nDPI through 3.2, the Oracle protocol dissector has a heap-based buffer over-read in ndpi_search_oracle in lib/protocols/oracle.c.

Project: nDPI
File: oracle.c

void init_oracle_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask)
{
  ndpi_set_bitmask_protocol_detection("Oracle", ndpi_struct, detection_bitmask, *id,
				      NDPI_PROTOCOL_ORACLE,
				      ndpi_search_oracle,
				      NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_TCP_WITH_PAYLOAD_WITHOUT_RETRANSMISSION,
				      SAVE_DETECTION_BITMASK_AS_UNKNOWN,
				      ADD_TO_DETECTION_BITMASK);

  *id += 1;
}

Project: nDPI
File: oracle.c

static void ndpi_int_oracle_add_connection(struct ndpi_detection_module_struct
					   *ndpi_struct, struct ndpi_flow_struct *flow)
{
  ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ORACLE, NDPI_PROTOCOL_UNKNOWN);
}

Project: nDPI
File: oracle.c

void ndpi_search_oracle(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;
  u_int16_t dport = 0, sport = 0;

  NDPI_LOG_DBG(ndpi_struct, "search ORACLE\n");

  if(packet->tcp != NULL) {
    sport = ntohs(packet->tcp->source), dport = ntohs(packet->tcp->dest);
    NDPI_LOG_DBG2(ndpi_struct, "calculating ORACLE over tcp\n");
    /* Oracle Database 9g,10g,11g */
    if ((dport == 1521 || sport == 1521)
	&&  (((packet->payload_packet_len >= 3 && packet->payload[0] == 0x07) && (packet->payload[1] == 0xff) && (packet->payload[2] == 0x00))
	     || ((packet->payload_packet_len >= 232) && ((packet->payload[0] == 0x00) || (packet->payload[0] == 0x01)) 
	     && (packet->payload[1] != 0x00)
	     && (packet->payload[2] == 0x00)
		 && (packet->payload[3] == 0x00)))) {
      NDPI_LOG_INFO(ndpi_struct, "found oracle\n");
      ndpi_int_oracle_add_connection(ndpi_struct, flow);
    } else if (packet->payload_packet_len == 213 && packet->payload[0] == 0x00 &&
               packet->payload[1] == 0xd5 && packet->payload[2] == 0x00 &&
               packet->payload[3] == 0x00 ) {
      NDPI_LOG_INFO(ndpi_struct, "found oracle\n");
      ndpi_int_oracle_add_connection(ndpi_struct, flow);
    }
  } else {
    NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
  }
}
Commit message: Fix stack data disclosure when returning static files smaller than
16KiB. It could also cause to return partially incorrect file ending in
case of file not being rounded up to 16KiB.

Thanks to Gynvael Coldwind and hebi for discovering and preparing
report.
CVE: None
Vulnerability description: None

Project: Crow
File: http_connection.h

        void do_write_static()
        {
            is_writing = true;
            asio::write(adaptor_.socket(), buffers_);

            if (res.file_info.statResult == 0)
            {
                std::ifstream is(res.file_info.path.c_str(), std::ios::in | std::ios::binary);
                std::vector<asio::const_buffer> buffers{1};
                char buf[16384];
                is.read(buf, sizeof(buf));
                while (is.gcount() > 0)
                {
                    buffers[0] = asio::buffer(buf, is.gcount());
                    do_write_sync(buffers);
                    is.read(buf, sizeof(buf));
                }
            }
            is_writing = false;
            if (close_connection_)
            {
                adaptor_.shutdown_readwrite();
                adaptor_.close();
                CROW_LOG_DEBUG << this << " from write (static)";
                check_destroy();
            }

            res.end();
            res.clear();
            buffers_.clear();
        }
Commit message: Fixed njs_array_convert_to_slow_array().

Previously, the function might free invalid pointer, as array->start is
not always points to the beginning of allocated memory block.

This closes #540 issue on Github.
CVE: None
Vulnerability description: None

Project: njs
File: njs_array.c

njs_array_expand(njs_vm_t *vm, njs_array_t *array, uint32_t prepend,
    uint32_t append)
{
    uint32_t     free_before, free_after;
    uint64_t     size;
    njs_value_t  *start, *old;

    njs_assert(array->object.fast_array);

    free_before = array->start - array->data;
    free_after = array->size - array->length - free_before;

    if (njs_fast_path(free_before >= prepend && free_after >= append)) {
        return NJS_OK;
    }

    size = (uint64_t) prepend + array->length + append;

    if (size < 16) {
        size *= 2;

    } else {
        size += size / 2;
    }

    if (njs_slow_path(size > (UINT32_MAX / sizeof(njs_value_t)))) {
        goto memory_error;
    }

    start = njs_mp_align(vm->mem_pool, sizeof(njs_value_t),
                         size * sizeof(njs_value_t));
    if (njs_slow_path(start == NULL)) {
        goto memory_error;
    }

    array->size = size;

    old = array->data;
    array->data = start;
    start += prepend;

    if (array->length != 0) {
        memcpy(start, array->start, array->length * sizeof(njs_value_t));
    }

    array->start = start;

    if (old != NULL) {
        njs_mp_free(vm->mem_pool, old);
    }

    return NJS_OK;

memory_error:

    njs_memory_error(vm);

    return NJS_ERROR;
}

Project: njs
File: njs_array.c

njs_array_convert_to_slow_array(njs_vm_t *vm, njs_array_t *array)
{
    uint32_t           i, length;
    njs_value_t        index, value;
    njs_object_prop_t  *prop;

    if (njs_slow_path(!array->object.fast_array)) {
        return NJS_OK;
    }

    njs_set_array(&value, array);
    array->object.fast_array = 0;

    length = array->length;

    for (i = 0; i < length; i++) {
        if (njs_is_valid(&array->start[i])) {
            njs_uint32_to_string(&index, i);
            prop = njs_object_property_add(vm, &value, &index, 0);
            if (njs_slow_path(prop == NULL)) {
                return NJS_ERROR;
            }

            prop->value = array->start[i];
        }
    }

    /* GC: release value. */

    njs_mp_free(vm->mem_pool, array->data);
    array->start = NULL;

    return NJS_OK;
}
Commit message: Check for return size in enc_untrusted_read

Check return size does not exceed requested. The returned result and
content still cannot be trusted, but it's expected behavior when not
using a secure file system.

PiperOrigin-RevId: 333827386
Change-Id: I0bdec0aec9356ea333dc8c647eba5d2772875f29
CVE: CVE-2020-8942
CWE: CWE-125
Vulnerability description: An arbitrary memory read vulnerability in Asylo versions up to 0.6.0 allows an untrusted attacker to make a call to enc_untrusted_read whose return size was not validated against the requrested size. The parameter size is unchecked allowing the attacker to read memory locations outside of the intended buffer size including memory addresses within the secure enclave. We recommend upgrading past commit b1d120a2c7d7446d2cc58d517e20a1b184b82200

Project: asylo
File: host_calls.cc

ssize_t enc_untrusted_read(int fd, void *buf, size_t count) {
  ssize_t ret = static_cast<ssize_t>(EnsureInitializedAndDispatchSyscall(
      asylo::system_call::kSYS_read, fd, buf, count));
  if (ret != -1 && ret > count) {
    ::asylo::primitives::TrustedPrimitives::BestEffortAbort(
        "enc_untrusted_read: read result exceeds requested");
  }
  return ret;
}
Commit message: (for 4.9.3) VRRP: Add a missing bounds check

In vrrp_print().

This fixes a buffer over-read discovered by Konrad Rieck and
Bhargava Shastry.

Add a test using the capture file supplied by the reporter(s)
restricted to VRRP packets.
CVE: None
CWE: CWE-787
Vulnerability description: None

Project: tcpdump
File: print-vrrp.c

vrrp_print(netdissect_options *ndo,
           register const u_char *bp, register u_int len,
           register const u_char *bp2, int ttl)
{
	int version, type, auth_type = VRRP_AUTH_NONE; /* keep compiler happy */
	const char *type_s;

	ND_TCHECK(bp[0]);
	version = (bp[0] & 0xf0) >> 4;
	type = bp[0] & 0x0f;
	type_s = tok2str(type2str, "unknown type (%u)", type);
	ND_PRINT((ndo, "VRRPv%u, %s", version, type_s));
	if (ttl != 255)
		ND_PRINT((ndo, ", (ttl %u)", ttl));
	if (version < 2 || version > 3 || type != VRRP_TYPE_ADVERTISEMENT)
		return;
	ND_TCHECK(bp[2]);
	ND_PRINT((ndo, ", vrid %u, prio %u", bp[1], bp[2]));
	ND_TCHECK(bp[5]);

	if (version == 2) {
		auth_type = bp[4];
		ND_PRINT((ndo, ", authtype %s", tok2str(auth2str, NULL, auth_type)));
		ND_PRINT((ndo, ", intvl %us, length %u", bp[5], len));
	} else { /* version == 3 */
		uint16_t intvl = (bp[4] & 0x0f) << 8 | bp[5];
		ND_PRINT((ndo, ", intvl %ucs, length %u", intvl, len));
	}

	if (ndo->ndo_vflag) {
		int naddrs = bp[3];
		int i;
		char c;

		if (version == 2 && ND_TTEST2(bp[0], len)) {
			struct cksum_vec vec[1];

			vec[0].ptr = bp;
			vec[0].len = len;
			if (in_cksum(vec, 1)) {
				ND_TCHECK_16BITS(&bp[6]);
				ND_PRINT((ndo, ", (bad vrrp cksum %x)",
					EXTRACT_16BITS(&bp[6])));
			}
		}

		if (version == 3 && ND_TTEST2(bp[0], len)) {
			uint16_t cksum = nextproto4_cksum(ndo, (const struct ip *)bp2, bp,
				len, len, IPPROTO_VRRP);
			if (cksum) {
				ND_TCHECK_16BITS(&bp[6]);
				ND_PRINT((ndo, ", (bad vrrp cksum %x)",
					EXTRACT_16BITS(&bp[6])));
			}
		}

		ND_PRINT((ndo, ", addrs"));
		if (naddrs > 1)
			ND_PRINT((ndo, "(%d)", naddrs));
		ND_PRINT((ndo, ":"));
		c = ' ';
		bp += 8;
		for (i = 0; i < naddrs; i++) {
			ND_TCHECK(bp[3]);
			ND_PRINT((ndo, "%c%s", c, ipaddr_string(ndo, bp)));
			c = ',';
			bp += 4;
		}
		if (version == 2 && auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */
			ND_TCHECK(bp[7]);
			ND_PRINT((ndo, " auth \""));
			if (fn_printn(ndo, bp, 8, ndo->ndo_snapend)) {
				ND_PRINT((ndo, "\""));
				goto trunc;
			}
			ND_PRINT((ndo, "\""));
		}
	}
	return;
trunc:
	ND_PRINT((ndo, "[|vrrp]"));
}
Commit message: be stricter in PAT processing - cf #1269
CVE: CVE-2019-20628
CWE: CWE-416
Vulnerability description: An issue was discovered in libgpac.a in GPAC before 0.8.0, as demonstrated by MP4Box. It contains a Use-After-Free vulnerability in gf_m2ts_process_pmt in media_tools/mpegts.c that can cause a denial of service via a crafted MP4 file.

Project: gpac
File: mpegts.c

static void gf_m2ts_process_pat(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ses, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status)
{
	GF_M2TS_Program *prog;
	GF_M2TS_SECTION_ES *pmt;
	u32 i, nb_progs, evt_type;
	u32 nb_sections;
	u32 data_size;
	unsigned char *data;
	GF_M2TS_Section *section;

	/*wait for the last section */
	if (!(status&GF_M2TS_TABLE_END)) return;

	/*skip if already received*/
	if (status&GF_M2TS_TABLE_REPEAT) {
		if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_PAT_REPEAT, NULL);
		return;
	}

	nb_sections = gf_list_count(sections);
	if (nb_sections > 1) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("PAT on multiple sections not supported\n"));
	}

	section = (GF_M2TS_Section *)gf_list_get(sections, 0);
	data = section->data;
	data_size = section->data_size;

	if (!(status&GF_M2TS_TABLE_UPDATE) && gf_list_count(ts->programs)) {
		if (ts->pat->demux_restarted) {
			ts->pat->demux_restarted = 0;
		} else {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Multiple different PAT on single TS found, ignoring new PAT declaration (table id %d - extended table id %d)\n", table_id, ex_table_id));
		}
		return;
	}
	nb_progs = data_size / 4;

	for (i=0; i<nb_progs; i++) {
		u16 number, pid;
		number = (data[0]<<8) | data[1];
		pid = (data[2]&0x1f)<<8 | data[3];
		data += 4;
		if (number==0) {
			if (!ts->nit) {
				ts->nit = gf_m2ts_section_filter_new(gf_m2ts_process_nit, 0);
			}
		} else if (!pid) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Broken PAT found reserved PID 0, ignoring\n", pid));
		} else if (! ts->ess[pid]) {
			GF_SAFEALLOC(prog, GF_M2TS_Program);
			if (!prog) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Fail to allocate program for pid %d\n", pid));
				return;
			}
			prog->streams = gf_list_new();
			prog->pmt_pid = pid;
			prog->number = number;
			prog->ts = ts;
			gf_list_add(ts->programs, prog);
			GF_SAFEALLOC(pmt, GF_M2TS_SECTION_ES);
			if (!pmt) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Fail to allocate pmt filter for pid %d\n", pid));
				return;
			}
			pmt->flags = GF_M2TS_ES_IS_SECTION;
			gf_list_add(prog->streams, pmt);
			pmt->pid = prog->pmt_pid;
			pmt->program = prog;
			ts->ess[pmt->pid] = (GF_M2TS_ES *)pmt;
			pmt->sec = gf_m2ts_section_filter_new(gf_m2ts_process_pmt, 0);
		}
	}

	evt_type = (status&GF_M2TS_TABLE_UPDATE) ? GF_M2TS_EVT_PAT_UPDATE : GF_M2TS_EVT_PAT_FOUND;
	if (ts->on_event) ts->on_event(ts, evt_type, NULL);
}
Commit message: fopen: add Curl_fopen() for better overwriting of files

Bug: https://curl.se/docs/CVE-2022-32207.html
CVE-2022-32207
Reported-by: Harry Sintonen
Closes #9050
CVE: None
Vulnerability description: None

Project: curl

CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
                    FILE **fh, char **tempname)
{
  CURLcode result = CURLE_WRITE_ERROR;
  unsigned char randsuffix[9];
  char *tempstore = NULL;
  struct_stat sb;
  int fd = -1;
  *tempname = NULL;

  if(stat(filename, &sb) == -1 || !S_ISREG(sb.st_mode)) {
    /* a non-regular file, fallback to direct fopen() */
    *fh = fopen(filename, FOPEN_WRITETEXT);
    if(*fh)
      return CURLE_OK;
    goto fail;
  }

  result = Curl_rand_hex(data, randsuffix, sizeof(randsuffix));
  if(result)
    goto fail;

  tempstore = aprintf("%s.%s.tmp", filename, randsuffix);
  if(!tempstore) {
    result = CURLE_OUT_OF_MEMORY;
    goto fail;
  }

  result = CURLE_WRITE_ERROR;
  fd = open(tempstore, O_WRONLY | O_CREAT | O_EXCL, 0600);
  if(fd == -1)
    goto fail;

#ifdef HAVE_FCHMOD
  {
    struct_stat nsb;
    if((fstat(fd, &nsb) != -1) &&
       (nsb.st_uid == sb.st_uid) && (nsb.st_gid == sb.st_gid)) {
      /* if the user and group are the same, clone the original mode */
      if(fchmod(fd, sb.st_mode) == -1)
        goto fail;
    }
  }
#endif

  *fh = fdopen(fd, FOPEN_WRITETEXT);
  if(!*fh)
    goto fail;

  *tempname = tempstore;
  return CURLE_OK;

fail:
  if(fd != -1) {
    close(fd);
    unlink(tempstore);
  }

  free(tempstore);

  *tempname = NULL;
  return result;
}
Commit message: TableLookUp::setTable(): do actually check that the LUT is <2^16
CVE: CVE-2018-25017
CWE: CWE-787
Vulnerability description: RawSpeed (aka librawspeed) 3.1 has a heap-based buffer overflow in TableLookUp::setTable.

Project: rawspeed
File: TableLookUp.cpp

TableLookUp::TableLookUp(int _ntables, bool _dither)
    : ntables(_ntables), dither(_dither) {
  if (ntables < 1) {
    ThrowRDE("Cannot construct 0 tables");
  }
  tables.resize(ntables * TABLE_SIZE, ushort16(0));
}

Project: rawspeed
File: TableLookUp.cpp

ushort16* TableLookUp::getTable(int n) {
  if (n > ntables) {
    ThrowRDE("Table lookup with number greater than number of tables.");
  }
  return &tables[n * TABLE_SIZE];
}

Project: rawspeed
File: TableLookUp.cpp

void TableLookUp::setTable(int ntable, const std::vector<ushort16>& table) {
  assert(!table.empty());

  const int nfilled = table.size();
  if (nfilled >= 65536)
    ThrowRDE("Table lookup with %i entries is unsupported", nfilled);

  if (ntable > ntables) {
    ThrowRDE("Table lookup with number greater than number of tables.");
  }
  ushort16* t = &tables[ntable * TABLE_SIZE];
  if (!dither) {
    for (int i = 0; i < 65536; i++) {
      t[i] = (i < nfilled) ? table[i] : table[nfilled - 1];
    }
    return;
  }
  for (int i = 0; i < nfilled; i++) {
    int center = table[i];
    int lower = i > 0 ? table[i - 1] : center;
    int upper = i < (nfilled - 1) ? table[i + 1] : center;
    int delta = upper - lower;
    t[i * 2] = center - ((upper - lower + 2) / 4);
    t[i * 2 + 1] = delta;
  }

  for (int i = nfilled; i < 65536; i++) {
    t[i * 2] = table[nfilled - 1];
    t[i * 2 + 1] = 0;
  }
  t[0] = t[1];
  t[TABLE_SIZE - 1] = t[TABLE_SIZE - 2];
}
Commit message: bochs: Use unsigned variables for offsets and sizes (CVE-2014-0147)

Gets us rid of integer overflows resulting in negative sizes which
aren't correctly checked.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
CVE: CVE-2014-0147
CWE: CWE-190
Vulnerability description: Qemu before 1.6.2 block diver for the various disk image formats used by Bochs and for the QCOW version 2 format, are vulnerable to a possible crash caused by signed data types or a logic error while creating QCOW2 snapshots, which leads to incorrectly calling update_refcount() routine.

Project: qemu
File: bochs.c

static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
                      Error **errp)
{
    BDRVBochsState *s = bs->opaque;
    uint32_t i;
    struct bochs_header bochs;
    int ret;

    bs->read_only = 1; // no write support yet

    ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
    if (ret < 0) {
        return ret;
    }

    if (strcmp(bochs.magic, HEADER_MAGIC) ||
        strcmp(bochs.type, REDOLOG_TYPE) ||
        strcmp(bochs.subtype, GROWING_TYPE) ||
	((le32_to_cpu(bochs.version) != HEADER_VERSION) &&
	(le32_to_cpu(bochs.version) != HEADER_V1))) {
        error_setg(errp, "Image not in Bochs format");
        return -EINVAL;
    }

    if (le32_to_cpu(bochs.version) == HEADER_V1) {
        bs->total_sectors = le64_to_cpu(bochs.extra.redolog_v1.disk) / 512;
    } else {
        bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
    }

    s->catalog_size = le32_to_cpu(bochs.catalog);
    s->catalog_bitmap = g_malloc(s->catalog_size * 4);

    ret = bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
                     s->catalog_size * 4);
    if (ret < 0) {
        goto fail;
    }

    for (i = 0; i < s->catalog_size; i++)
	le32_to_cpus(&s->catalog_bitmap[i]);

    s->data_offset = le32_to_cpu(bochs.header) + (s->catalog_size * 4);

    s->bitmap_blocks = 1 + (le32_to_cpu(bochs.bitmap) - 1) / 512;
    s->extent_blocks = 1 + (le32_to_cpu(bochs.extent) - 1) / 512;

    s->extent_size = le32_to_cpu(bochs.extent);

    qemu_co_mutex_init(&s->lock);
    return 0;

fail:
    g_free(s->catalog_bitmap);
    return ret;
}