Re: [PATCH 5/7] ARM: KVM: KVM_VCPU_GET_MSR_INDEX_LIST/KVM_GET_MSRS/KVM_SET_MSRS for cp15 regs.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 6 August 2012 08:36, Rusty Russell <rusty.russell@xxxxxxxxxx> wrote:
> +static int copy_reg_to_user(const struct coproc_reg *reg, u32 __user **uind)
> +{
> +       if (!*uind)
> +               return 0;
> +
> +       if (put_user(cp15_to_index(reg), *uind))
> +               return -EFAULT;
> +
> +       (*uind)++;
> +       return 0;
> +}

This function returns 0 on success or a negative errno on failure...

> +
> +/* Assumed ordered tables, see kvm_coproc_table_init. */
> +static int walk_msrs(struct kvm_vcpu *vcpu, u32 __user *uind)
> +{
> +       const struct coproc_reg *i1, *i2, *end1, *end2;
> +       unsigned int total = 0;
> +       size_t num;
> +
> +       /* We check for duplicates here, to allow arch-specific overrides. */
> +       i1 = get_target_table(vcpu->arch.target, &num);
> +       end1 = i1 + num;
> +       i2 = cp15_regs;
> +       end2 = cp15_regs + ARRAY_SIZE(cp15_regs);
> +
> +       BUG_ON(i1 == end1 || i2 == end2);
> +
> +       /* Walk carefully, as both tables may refer to the same register. */
> +       while (i1 && i2) {
> +               int cmp = cmp_reg(i1, i2);
> +               /* target-specific overrides generic entry. */
> +               if (cmp <= 0) {
> +                       /* Ignore registers we trap but don't save. */
> +                       if (i1->reg) {
> +                               if (!copy_reg_to_user(i1, &uind))
> +                                       return -EFAULT;

...but this code assumes it returns 0 on failure

> +                               total++;
> +                       }
> +               } else {
> +                       /* Ignore registers we trap but don't save. */
> +                       if (i2->reg) {
> +                               if (!copy_reg_to_user(i2, &uind))
> +                                       return -EFAULT;

...as does this.

The effect is that
(a) trying to query the length of the list returns a too small
or even negative number since kvm_num_guest_msrs() doesn't notice
it just got handed an errno
(b) trying to actually read the list always fails -EFAULT.

Dropping the "!"s fixes this for me, but you might prefer to
change the return value of copy_reg_to_user() instead.

-- PMM
_______________________________________________
kvmarm mailing list
kvmarm@xxxxxxxxxxxxxxxxxxxxx
https://lists.cs.columbia.edu/cucslists/listinfo/kvmarm


[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux