| From 36e8f60f0867d3b70d398d653c17108459a04efe Mon Sep 17 00:00:00 2001 |
| From: Stefano Stabellini <stefano.stabellini@xilinx.com> |
| Date: Tue, 23 Nov 2021 13:07:48 -0800 |
| Subject: xen: detect uninitialized xenbus in xenbus_init |
| |
| From: Stefano Stabellini <stefano.stabellini@xilinx.com> |
| |
| commit 36e8f60f0867d3b70d398d653c17108459a04efe upstream. |
| |
| If the xenstore page hasn't been allocated properly, reading the value |
| of the related hvm_param (HVM_PARAM_STORE_PFN) won't actually return |
| error. Instead, it will succeed and return zero. Instead of attempting |
| to xen_remap a bad guest physical address, detect this condition and |
| return early. |
| |
| Note that although a guest physical address of zero for |
| HVM_PARAM_STORE_PFN is theoretically possible, it is not a good choice |
| and zero has never been validly used in that capacity. |
| |
| Also recognize all bits set as an invalid value. |
| |
| For 32-bit Linux, any pfn above ULONG_MAX would get truncated. Pfns |
| above ULONG_MAX should never be passed by the Xen tools to HVM guests |
| anyway, so check for this condition and return early. |
| |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Stefano Stabellini <stefano.stabellini@xilinx.com> |
| Reviewed-by: Juergen Gross <jgross@suse.com> |
| Reviewed-by: Jan Beulich <jbeulich@suse.com> |
| Link: https://lore.kernel.org/r/20211123210748.1910236-1-sstabellini@kernel.org |
| Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/xen/xenbus/xenbus_probe.c | 23 +++++++++++++++++++++++ |
| 1 file changed, 23 insertions(+) |
| |
| --- a/drivers/xen/xenbus/xenbus_probe.c |
| +++ b/drivers/xen/xenbus/xenbus_probe.c |
| @@ -804,6 +804,29 @@ static int __init xenbus_init(void) |
| err = hvm_get_parameter(HVM_PARAM_STORE_PFN, &v); |
| if (err) |
| goto out_error; |
| + /* |
| + * Uninitialized hvm_params are zero and return no error. |
| + * Although it is theoretically possible to have |
| + * HVM_PARAM_STORE_PFN set to zero on purpose, in reality it is |
| + * not zero when valid. If zero, it means that Xenstore hasn't |
| + * been properly initialized. Instead of attempting to map a |
| + * wrong guest physical address return error. |
| + * |
| + * Also recognize all bits set as an invalid value. |
| + */ |
| + if (!v || !~v) { |
| + err = -ENOENT; |
| + goto out_error; |
| + } |
| + /* Avoid truncation on 32-bit. */ |
| +#if BITS_PER_LONG == 32 |
| + if (v > ULONG_MAX) { |
| + pr_err("%s: cannot handle HVM_PARAM_STORE_PFN=%llx > ULONG_MAX\n", |
| + __func__, v); |
| + err = -EINVAL; |
| + goto out_error; |
| + } |
| +#endif |
| xen_store_gfn = (unsigned long)v; |
| xen_store_interface = |
| xen_remap(xen_store_gfn << XEN_PAGE_SHIFT, |