scripts/coccinelle/error-use-after-free.cocci led me to
target/loongarch/kvm/kvm.c:

    int kvm_arch_init_vcpu(CPUState *cs)
    {
        uint64_t val;
        int ret;
        Error *local_err = NULL;

        ret = 0;
        qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);

        if (!kvm_get_one_reg(cs, KVM_REG_LOONGARCH_DEBUG_INST, &val)) {
            brk_insn = val;
        }

        ret = kvm_cpu_check_lsx(cs, &local_err);
        if (ret < 0) {
            error_report_err(local_err);

Reporting an error, but continue anyway.  This is suspicious.

Note for later: @local_error is now non-null.

        }

        ret = kvm_cpu_check_lasx(cs, &local_err);

Passing non-null @local_error to kvm_cpu_check_lasx().  This is wrong.
When kvm_cpu_check_lasx() fails and passes &local_error to error_setg(),
error_setv()'s assertion will fail.

Two possible fixes:

1. If continuing after kvm_cpu_check_lasx() failure is correct, we need
to clear @local_error there.  Since it's not actually an error then, we
should almost certainly not use error_report_err() there.  *Maybe*
warn_report_err().

2. If continuing is wrong, we probably need to return ret.

What is the correct fix?

        if (ret < 0) {
            error_report_err(local_err);

Likewise.

        }

        ret = kvm_cpu_check_lbt(cs, &local_err);
        if (ret < 0) {
            error_report_err(local_err);

Likewise.

        }

        ret = kvm_cpu_check_pmu(cs, &local_err);
        if (ret < 0) {
            error_report_err(local_err);

Likewise.

        }

        ret = kvm_cpu_check_pv_features(cs, &local_err);
        if (ret < 0) {
            error_report_err(local_err);

Best to do the same here.

        }

        return ret;
    }


Reply via email to