xen: detect uninitialized xenbus in xenbus_init
Subsystems (2)
Stefano Stabellini
maintainerPATCH v3 1/1 xen: detect uninitialized xenbus in xenbus_init
From: Stefano Stabellini <[email protected]>
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 the invalid value of INVALID_PFN which is ULLONG_MAX.
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.
---
Changes in v3:
- improve in-code comment
- improve check
Changes in v2:
- add check for ULLONG_MAX (unitialized)
- add check for ULONG_MAX #if BITS_PER_LONG == 32 (actual error)
- add pr_err error message
--- drivers/xen/xenbus/xenbus_probe.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
drivers/xen/xenbus/xenbus_probe.c +24 -0
@@ -951,6 +951,30 @@ 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 the invalid value of INVALID_PFN which is +* ULLONG_MAX. +*/ +if (!v || !(v +1 )) { + 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,
Signature · 1 line
2.25.1
Juergen Gross
maintainerQuoted 41 lines · Stefano Stabellini
From: Stefano Stabellini <[email protected]>
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 toxen_remapa bad guest physical address, detect this condition and return early.Note that although a guest physical address of zero for
HVM_PARAM_STORE_PFNis theoretically possible, it is not a good choice and zero has never been validly used in that capacity.Also recognize the invalid value of
INVALID_PFNwhich isULLONG_MAX.For 32-bit Linux, any pfn above
ULONG_MAXwould get truncated. Pfns aboveULONG_MAXshould never be passed by the Xen tools to HVM guests anyway, so check for this condition and return early.Signed-off-by Stefano Stabellini <[email protected]>---
Changes in v3:
- improve in-code comment
- improve checkChanges in v2:
- add check forULLONG_MAX(unitialized)
- add check forULONG_MAX#ifBITS_PER_LONG== 32 (actual error)
- addpr_errerror message--- drivers/xen/xenbus/xenbus_probe.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)drivers/xen/xenbus/xenbus_probe.c +0
-0@@ -951,6 +951,30 @@ static int __init xenbus_init(void) err =hvm_get_parameter (HVM_PARAM_STORE_PFN , &v);if (err) goto out_error;
drivers/xen/xenbus/xenbus_probe.c static int __init xenbus_init(void) · line 963
Quoted 10 lines
drivers/xen/xenbus/xenbus_probe.c +10
-0+/* +* 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 the invalid value of INVALID_PFN which is +* ULLONG_MAX.
Adjust the comment, e.g. s/ULLONG_MAX/all bits set/ (in the commit message, too)?
drivers/xen/xenbus/xenbus_probe.c static int __init xenbus_init(void) · line 965
Quoted 2 lines
drivers/xen/xenbus/xenbus_probe.c +2
-0+*/ +if (!v || !(v +1 )) {
For me "if (!v || !~v)" would be more readable, but I don't really feel strong here.
Juergen
Quoted 47 lines · Juergen Gross
Quoted 46 lines · Stefano Stabellini
From: Stefano Stabellini <[email protected]>
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 toxen_remapa bad guest physical address, detect this condition and return early.Note that although a guest physical address of zero for
HVM_PARAM_STORE_PFNis theoretically possible, it is not a good choice and zero has never been validly used in that capacity.Also recognize the invalid value of
INVALID_PFNwhich isULLONG_MAX.For 32-bit Linux, any pfn above
ULONG_MAXwould get truncated. Pfns aboveULONG_MAXshould never be passed by the Xen tools to HVM guests anyway, so check for this condition and return early.Signed-off-by Stefano Stabellini <[email protected]>---
Changes in v3:
- improve in-code comment
- improve checkChanges in v2:
- add check forULLONG_MAX(unitialized)
- add check forULONG_MAX#ifBITS_PER_LONG== 32 (actual error)
- addpr_errerror message--- drivers/xen/xenbus/xenbus_probe.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)drivers/xen/xenbus/xenbus_probe.c +5
-0@@ -951,6 +951,30 @@ 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
Quoted 8 lines
drivers/xen/xenbus/xenbus_probe.c static int __init xenbus_init(void) · line 963
Quoted 5 lines
drivers/xen/xenbus/xenbus_probe.c +5
-0+* been properly initialized. Instead of attempting to map a +* wrong guest physical address return error. +* +* Also recognize the invalid value of INVALID_PFN which is +* ULLONG_MAX. Adjust the comment, e.g. s/ULLONG_MAX/all bits set/ (in the commit message, too)?
I also don't think the reference to INVALID_PFN is appropriate here. Afaict the two aren't the same on 32-bit. Plus I can't even find a constant named this way in Linux'es include/.
Quoted 5 lines
drivers/xen/xenbus/xenbus_probe.c static int __init xenbus_init(void) · line 965
Quoted 2 lines
drivers/xen/xenbus/xenbus_probe.c +2
-0+*/ +if (!v || !(v +1 )) {For me "if (!v || !~v)" would be more readable, but I don't really feel strong here.
Oh, indeed.
Jan