diff --git a/hw/core/eif.c b/hw/core/eif.c index 7f3b2edc9a..a7128b71ce 100644 --- a/hw/core/eif.c +++ b/hw/core/eif.c @@ -119,6 +119,10 @@ static bool read_eif_header(FILE *f, EifHeader *header, uint32_t *crc, for (int i = 0; i < MAX_SECTIONS; ++i) { header->section_sizes[i] = be64_to_cpu(header->section_sizes[i]); + if (header->section_sizes[i] > SSIZE_MAX) { + error_setg(errp, "Invalid EIF image. Section size out of bounds"); + return false; + } } header->unused = be32_to_cpu(header->unused); @@ -278,7 +282,12 @@ static bool get_signature_fingerprint_sha384(FILE *eif, uint64_t size, struct cbor_load_result result; bool ret = false; - sig = g_malloc(size); + sig = g_try_malloc(size); + if (!sig) { + error_setg(errp, "Out of memory reading signature section"); + goto cleanup; + } + got = fread(sig, 1, size, eif); if ((uint64_t) got != size) { error_setg(errp, "Failed to read EIF signature section data"); @@ -320,7 +329,12 @@ static bool get_signature_fingerprint_sha384(FILE *eif, uint64_t size, error_setg(errp, "Invalid signature CBOR"); goto cleanup; } - cert = g_malloc(len); + cert = g_try_malloc(len); + if (!cert) { + error_setg(errp, "Out of memory reading signature section"); + goto cleanup; + } + for (int i = 0; i < len; ++i) { cbor_item_t *tmp = cbor_array_get(pair->value, i); if (!tmp) { @@ -466,6 +480,10 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, EifSectionHeader hdr; uint16_t section_type; + if (eif_header.section_offsets[i] > OFF_MAX) { + error_setg(errp, "Invalid EIF image. Section offset out of bounds"); + goto cleanup; + } if (fseek(f, eif_header.section_offsets[i], SEEK_SET) != 0) { error_setg_errno(errp, errno, "Failed to offset to %" PRIu64 " in EIF file", eif_header.section_offsets[i]); @@ -499,7 +517,11 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, goto cleanup; } - ptr = g_malloc(hdr.section_size); + ptr = g_try_malloc(hdr.section_size); + if (!ptr) { + error_setg(errp, "Out of memory reading kernel section"); + goto cleanup; + } iov_ptr = g_malloc(sizeof(struct iovec)); iov_ptr->iov_base = ptr; @@ -524,7 +546,11 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, goto cleanup; } size = hdr.section_size; - *cmdline = g_malloc(size + 1); + *cmdline = g_try_malloc(size + 1); + if (!*cmdline) { + error_setg(errp, "Out of memory reading command line section"); + goto cleanup; + } if (!read_eif_cmdline(f, size, *cmdline, &crc, errp)) { goto cleanup; } @@ -563,7 +589,11 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, } } - ptr = g_malloc(hdr.section_size); + ptr = g_try_malloc(hdr.section_size); + if (!ptr) { + error_setg(errp, "Out of memory reading initrd section"); + goto cleanup; + } iov_ptr = g_malloc(sizeof(struct iovec)); iov_ptr->iov_base = ptr; @@ -602,7 +632,11 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, uint8_t *buf; size_t got; uint64_t size = hdr.section_size; - buf = g_malloc(size); + buf = g_try_malloc(size); + if (!buf) { + error_setg(errp, "Out of memory reading unknown section"); + goto cleanup; + } got = fread(buf, 1, size, f); if ((uint64_t) got != size) { g_free(buf); @@ -658,7 +692,11 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd, goto cleanup; } - ptr = g_malloc(machine_initrd_size); + ptr = g_try_malloc(machine_initrd_size); + if (!ptr) { + error_setg(errp, "Out of memory reading initrd file"); + goto cleanup; + } iov_ptr = g_malloc(sizeof(struct iovec)); iov_ptr->iov_base = ptr; diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 830614d930..f9147fecbd 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1252,7 +1252,9 @@ void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus) } /* Anything remaining should be a PCI NIC */ - pci_init_nic_devices(pci_bus, mc->default_nic); + if (pci_bus) { + pci_init_nic_devices(pci_bus, mc->default_nic); + } rom_reset_order_override(); } diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index fe7c3c5f67..fdff07fd99 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -297,6 +297,10 @@ void QEMU_ERROR("code path is reachable") #error building with G_DISABLE_ASSERT is not supported #endif +#ifndef OFF_MAX +#define OFF_MAX (sizeof (off_t) == 8 ? INT64_MAX : INT32_MAX) +#endif + #ifndef O_LARGEFILE #define O_LARGEFILE 0 #endif diff --git a/rust/qemu-api-macros/meson.build b/rust/qemu-api-macros/meson.build index 24325dea5c..6f94a4bb3c 100644 --- a/rust/qemu-api-macros/meson.build +++ b/rust/qemu-api-macros/meson.build @@ -1,3 +1,7 @@ +subproject('proc-macro2-1-rs', required: true) +subproject('quote-1-rs', required: true) +subproject('syn-2-rs', required: true) + quote_dep = dependency('quote-1-rs', native: true) syn_dep = dependency('syn-2-rs', native: true) proc_macro2_dep = dependency('proc-macro2-1-rs', native: true) diff --git a/subprojects/packagefiles/arbitrary-int-1-rs/meson.build b/subprojects/packagefiles/arbitrary-int-1-rs/meson.build index 34a189cbae..cff3f62ce7 100644 --- a/subprojects/packagefiles/arbitrary-int-1-rs/meson.build +++ b/subprojects/packagefiles/arbitrary-int-1-rs/meson.build @@ -1,4 +1,5 @@ project('arbitrary-int-1-rs', 'rust', + meson_version: '>=1.5.0', version: '1.2.7', license: 'MIT', default_options: []) diff --git a/subprojects/packagefiles/bilge-0.2-rs/meson.build b/subprojects/packagefiles/bilge-0.2-rs/meson.build index a6ed4a8f0c..e69bac91b4 100644 --- a/subprojects/packagefiles/bilge-0.2-rs/meson.build +++ b/subprojects/packagefiles/bilge-0.2-rs/meson.build @@ -1,6 +1,7 @@ project( 'bilge-0.2-rs', 'rust', + meson_version: '>=1.5.0', version : '0.2.0', license : 'MIT or Apache-2.0', ) diff --git a/subprojects/packagefiles/bilge-impl-0.2-rs/meson.build b/subprojects/packagefiles/bilge-impl-0.2-rs/meson.build index 80243c7024..f8f3486fc0 100644 --- a/subprojects/packagefiles/bilge-impl-0.2-rs/meson.build +++ b/subprojects/packagefiles/bilge-impl-0.2-rs/meson.build @@ -1,4 +1,5 @@ project('bilge-impl-0.2-rs', 'rust', + meson_version: '>=1.5.0', version: '0.2.0', license: 'MIT OR Apache-2.0', default_options: []) diff --git a/subprojects/packagefiles/either-1-rs/meson.build b/subprojects/packagefiles/either-1-rs/meson.build index a5842eb3a6..608e64e31f 100644 --- a/subprojects/packagefiles/either-1-rs/meson.build +++ b/subprojects/packagefiles/either-1-rs/meson.build @@ -1,4 +1,5 @@ project('either-1-rs', 'rust', + meson_version: '>=1.5.0', version: '1.12.0', license: 'MIT OR Apache-2.0', default_options: []) diff --git a/subprojects/packagefiles/itertools-0.11-rs/meson.build b/subprojects/packagefiles/itertools-0.11-rs/meson.build index 13d2d27019..30982a4ee7 100644 --- a/subprojects/packagefiles/itertools-0.11-rs/meson.build +++ b/subprojects/packagefiles/itertools-0.11-rs/meson.build @@ -1,4 +1,5 @@ project('itertools-0.11-rs', 'rust', + meson_version: '>=1.5.0', version: '0.11.0', license: 'MIT OR Apache-2.0', default_options: []) diff --git a/subprojects/packagefiles/proc-macro-error-1-rs/meson.build b/subprojects/packagefiles/proc-macro-error-1-rs/meson.build index 38ea7b89d3..ae27a69686 100644 --- a/subprojects/packagefiles/proc-macro-error-1-rs/meson.build +++ b/subprojects/packagefiles/proc-macro-error-1-rs/meson.build @@ -1,4 +1,5 @@ project('proc-macro-error-1-rs', 'rust', + meson_version: '>=1.5.0', version: '1.0.4', license: 'MIT OR Apache-2.0', default_options: []) diff --git a/subprojects/packagefiles/proc-macro-error-attr-1-rs/meson.build b/subprojects/packagefiles/proc-macro-error-attr-1-rs/meson.build index d900c54cfd..3281b26433 100644 --- a/subprojects/packagefiles/proc-macro-error-attr-1-rs/meson.build +++ b/subprojects/packagefiles/proc-macro-error-attr-1-rs/meson.build @@ -1,4 +1,5 @@ project('proc-macro-error-attr-1-rs', 'rust', + meson_version: '>=1.5.0', version: '1.12.0', license: 'MIT OR Apache-2.0', default_options: []) diff --git a/subprojects/packagefiles/proc-macro2-1-rs/meson.build b/subprojects/packagefiles/proc-macro2-1-rs/meson.build index 8e601b50cc..f9c8675eba 100644 --- a/subprojects/packagefiles/proc-macro2-1-rs/meson.build +++ b/subprojects/packagefiles/proc-macro2-1-rs/meson.build @@ -1,4 +1,5 @@ project('proc-macro2-1-rs', 'rust', + meson_version: '>=1.5.0', version: '1.0.84', license: 'MIT OR Apache-2.0', default_options: []) diff --git a/subprojects/packagefiles/quote-1-rs/meson.build b/subprojects/packagefiles/quote-1-rs/meson.build index d36609bd3c..7f7792569b 100644 --- a/subprojects/packagefiles/quote-1-rs/meson.build +++ b/subprojects/packagefiles/quote-1-rs/meson.build @@ -1,4 +1,5 @@ project('quote-1-rs', 'rust', + meson_version: '>=1.5.0', version: '1.12.0', license: 'MIT OR Apache-2.0', default_options: []) diff --git a/subprojects/packagefiles/syn-2-rs/meson.build b/subprojects/packagefiles/syn-2-rs/meson.build index 9f56ce1c24..2c62cf7e1b 100644 --- a/subprojects/packagefiles/syn-2-rs/meson.build +++ b/subprojects/packagefiles/syn-2-rs/meson.build @@ -1,4 +1,5 @@ project('syn-2-rs', 'rust', + meson_version: '>=1.5.0', version: '2.0.66', license: 'MIT OR Apache-2.0', default_options: []) diff --git a/subprojects/packagefiles/unicode-ident-1-rs/meson.build b/subprojects/packagefiles/unicode-ident-1-rs/meson.build index 54f2376854..9d76ebbd1a 100644 --- a/subprojects/packagefiles/unicode-ident-1-rs/meson.build +++ b/subprojects/packagefiles/unicode-ident-1-rs/meson.build @@ -1,4 +1,5 @@ project('unicode-ident-1-rs', 'rust', + meson_version: '>=1.5.0', version: '1.0.12', license: '(MIT OR Apache-2.0) AND Unicode-DFS-2016', default_options: []) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 58c96eafea..3725dbbc4b 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1116,7 +1116,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = { [FEAT_7_1_EAX] = { .type = CPUID_FEATURE_WORD, .feat_names = { - NULL, NULL, NULL, NULL, + "sha512", "sm3", "sm4", NULL, "avx-vnni", "avx512-bf16", NULL, "cmpccxadd", NULL, NULL, "fzrm", "fsrs", "fsrc", NULL, NULL, NULL, diff --git a/target/i386/cpu.h b/target/i386/cpu.h index b65eedb617..4c239a6970 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -346,6 +346,7 @@ typedef enum X86Seg { #define PG_MODE_PKE (1 << 17) #define PG_MODE_PKS (1 << 18) #define PG_MODE_SMEP (1 << 19) +#define PG_MODE_PG (1 << 20) #define MCG_CTL_P (1ULL<<8) /* MCG_CAP register available */ #define MCG_SER_P (1ULL<<24) /* MCA recovery/new status bits */ diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index 68dc5d9cf7..c5d025d557 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -239,7 +239,9 @@ int hvf_arch_init_vcpu(CPUState *cpu) init_emu(); init_decoder(); - hvf_state->hvf_caps = g_new0(struct hvf_vcpu_caps, 1); + if (hvf_state->hvf_caps == NULL) { + hvf_state->hvf_caps = g_new0(struct hvf_vcpu_caps, 1); + } env->hvf_mmio_buf = g_new(char, 4096); if (x86cpu->vmware_cpuid_freq) { @@ -584,8 +586,6 @@ int hvf_vcpu_exec(CPUState *cpu) break; } case EXIT_REASON_XSETBV: { - X86CPU *x86_cpu = X86_CPU(cpu); - CPUX86State *env = &x86_cpu->env; uint32_t eax = (uint32_t)rreg(cpu->accel->fd, HV_X86_RAX); uint32_t ecx = (uint32_t)rreg(cpu->accel->fd, HV_X86_RCX); uint32_t edx = (uint32_t)rreg(cpu->accel->fd, HV_X86_RDX); @@ -642,7 +642,6 @@ int hvf_vcpu_exec(CPUState *cpu) break; } case 8: { - X86CPU *x86_cpu = X86_CPU(cpu); if (exit_qual & 0x10) { RRX(env, reg) = cpu_get_apic_tpr(x86_cpu->apic_state); } else { diff --git a/target/i386/hvf/x86_cpuid.c b/target/i386/hvf/x86_cpuid.c index 3a116548a3..af9ee17a11 100644 --- a/target/i386/hvf/x86_cpuid.c +++ b/target/i386/hvf/x86_cpuid.c @@ -32,7 +32,7 @@ static bool cached_xcr0; static uint64_t supported_xcr0; -static void cache_host_xcr0() +static void cache_host_xcr0(void) { if (cached_xcr0) { return; @@ -77,7 +77,7 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx, ecx &= CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 | CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID | CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_MOVBE | - CPUID_EXT_POPCNT | CPUID_EXT_AES | + CPUID_EXT_POPCNT | CPUID_EXT_AES | CPUID_EXT_X2APIC | (supported_xcr0 ? CPUID_EXT_XSAVE : 0) | CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND; ecx |= CPUID_EXT_HYPERVISOR; @@ -119,8 +119,8 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx, eax = 0; break; case 0xD: - if (!supported_xcr0 || - (idx > 1 && !(supported_xcr0 & (1 << idx)))) { + if (!supported_xcr0 || idx >= 63 || + (idx > 1 && !(supported_xcr0 & (UINT64_C(1) << idx)))) { eax = ebx = ecx = edx = 0; break; } diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c index 38c782b8e3..015f760acb 100644 --- a/target/i386/hvf/x86_emu.c +++ b/target/i386/hvf/x86_emu.c @@ -663,6 +663,15 @@ static void exec_lods(CPUX86State *env, struct x86_decode *decode) env->eip += decode->len; } +static void raise_exception(CPUX86State *env, int exception_index, + int error_code) +{ + env->exception_nr = exception_index; + env->error_code = error_code; + env->has_error_code = true; + env->exception_injected = 1; +} + void simulate_rdmsr(CPUX86State *env) { X86CPU *cpu = env_archcpu(env); @@ -677,6 +686,17 @@ void simulate_rdmsr(CPUX86State *env) case MSR_IA32_APICBASE: val = cpu_get_apic_base(cpu->apic_state); break; + case MSR_APIC_START ... MSR_APIC_END: { + int ret; + int index = (uint32_t)env->regs[R_ECX] - MSR_APIC_START; + + ret = apic_msr_read(index, &val); + if (ret < 0) { + raise_exception(env, EXCP0D_GPF, 0); + } + + break; + } case MSR_IA32_UCODE_REV: val = cpu->ucode_rev; break; @@ -774,9 +794,27 @@ void simulate_wrmsr(CPUX86State *env) switch (msr) { case MSR_IA32_TSC: break; - case MSR_IA32_APICBASE: - cpu_set_apic_base(cpu->apic_state, data); + case MSR_IA32_APICBASE: { + int r; + + r = cpu_set_apic_base(cpu->apic_state, data); + if (r < 0) { + raise_exception(env, EXCP0D_GPF, 0); + } + break; + } + case MSR_APIC_START ... MSR_APIC_END: { + int ret; + int index = (uint32_t)env->regs[R_ECX] - MSR_APIC_START; + + ret = apic_msr_write(index, data); + if (ret < 0) { + raise_exception(env, EXCP0D_GPF, 0); + } + + break; + } case MSR_FSBASE: wvmcs(cs->accel->fd, VMCS_GUEST_FS_BASE, data); break; diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 02ae6a0d1f..71962113fb 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -94,7 +94,7 @@ static uint32_t popl(StackAccess *sa) int get_pg_mode(CPUX86State *env) { - int pg_mode = 0; + int pg_mode = PG_MODE_PG; if (!(env->cr[0] & CR0_PG_MASK)) { return 0; } diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c index da187c8792..02d3486421 100644 --- a/target/i386/tcg/sysemu/excp_helper.c +++ b/target/i386/tcg/sysemu/excp_helper.c @@ -298,7 +298,7 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in, /* combine pde and pte nx, user and rw protections */ ptep &= pte ^ PG_NX_MASK; page_size = 4096; - } else if (pg_mode) { + } else if (pg_mode & PG_MODE_PG) { /* * Page table level 2 */