Merge tag 'mvebu-fixes-5.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/gclem...
[linux-2.6-microblaze.git] / arch / powerpc / kvm / book3s_rtas.c
index c5e6775..0f847f1 100644 (file)
@@ -242,6 +242,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
         * value so we can restore it on the way out.
         */
        orig_rets = args.rets;
+       if (be32_to_cpu(args.nargs) >= ARRAY_SIZE(args.args)) {
+               /*
+                * Don't overflow our args array: ensure there is room for
+                * at least rets[0] (even if the call specifies 0 nret).
+                *
+                * Each handler must then check for the correct nargs and nret
+                * values, but they may always return failure in rets[0].
+                */
+               rc = -EINVAL;
+               goto fail;
+       }
        args.rets = &args.args[be32_to_cpu(args.nargs)];
 
        mutex_lock(&vcpu->kvm->arch.rtas_token_lock);
@@ -269,9 +280,17 @@ int kvmppc_rtas_hcall(struct kvm_vcpu *vcpu)
 fail:
        /*
         * We only get here if the guest has called RTAS with a bogus
-        * args pointer. That means we can't get to the args, and so we
-        * can't fail the RTAS call. So fail right out to userspace,
-        * which should kill the guest.
+        * args pointer or nargs/nret values that would overflow the
+        * array. That means we can't get to the args, and so we can't
+        * fail the RTAS call. So fail right out to userspace, which
+        * should kill the guest.
+        *
+        * SLOF should actually pass the hcall return value from the
+        * rtas handler call in r3, so enter_rtas could be modified to
+        * return a failure indication in r3 and we could return such
+        * errors to the guest rather than failing to host userspace.
+        * However old guests that don't test for failure could then
+        * continue silently after errors, so for now we won't do this.
         */
        return rc;
 }