[PATCH] xen/arm: Fix UBSAN failure in start_xen()

Michal Orzel posted 1 patch 2 months, 3 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://gitlab.com/xen-project/patchew/xen tags/patchew/20240208104339.37826-1-michal.orzel@amd.com
xen/arch/arm/setup.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] xen/arm: Fix UBSAN failure in start_xen()
Posted by Michal Orzel 2 months, 3 weeks ago
When running Xen on arm32, in scenario where Xen is loaded at an address
such as boot_phys_offset >= 2GB, UBSAN reports the following:

(XEN) UBSAN: Undefined behaviour in arch/arm/setup.c:739:58
(XEN) pointer operation underflowed 00200000 to 86800000
(XEN) Xen WARN at common/ubsan/ubsan.c:172
(XEN) ----[ Xen-4.19-unstable  arm32  debug=y ubsan=y  Not tainted ]----
...
(XEN) Xen call trace:
(XEN)    [<0031b4c0>] ubsan.c#ubsan_epilogue+0x18/0xf0 (PC)
(XEN)    [<0031d134>] __ubsan_handle_pointer_overflow+0xb8/0xd4 (LR)
(XEN)    [<0031d134>] __ubsan_handle_pointer_overflow+0xb8/0xd4
(XEN)    [<004d15a8>] start_xen+0xe0/0xbe0
(XEN)    [<0020007c>] head.o#primary_switched+0x4/0x30

The failure is reported for the following line:
(paddr_t)(uintptr_t)(_start + boot_phys_offset)

This occurs because the compiler treats (ptr + size) with size bigger than
PTRDIFF_MAX as undefined behavior. To address this, switch to macro
virt_to_maddr(), given the future plans to eliminate boot_phys_offset.

Signed-off-by: Michal Orzel <michal.orzel@amd.com>
---
 xen/arch/arm/setup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 7e28f62d09f1..424744ad5e1a 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -736,7 +736,7 @@ void asmlinkage __init start_xen(unsigned long boot_phys_offset,
 
     /* Register Xen's load address as a boot module. */
     xen_bootmodule = add_boot_module(BOOTMOD_XEN,
-                             (paddr_t)(uintptr_t)(_start + boot_phys_offset),
+                             virt_to_maddr(_start),
                              (paddr_t)(uintptr_t)(_end - _start), false);
     BUG_ON(!xen_bootmodule);
 
-- 
2.25.1
Re: [PATCH] xen/arm: Fix UBSAN failure in start_xen()
Posted by Julien Grall 2 months, 3 weeks ago
Hi Michal,

On 08/02/2024 10:43, Michal Orzel wrote:
> When running Xen on arm32, in scenario where Xen is loaded at an address
> such as boot_phys_offset >= 2GB, UBSAN reports the following:
> 
> (XEN) UBSAN: Undefined behaviour in arch/arm/setup.c:739:58
> (XEN) pointer operation underflowed 00200000 to 86800000
> (XEN) Xen WARN at common/ubsan/ubsan.c:172
> (XEN) ----[ Xen-4.19-unstable  arm32  debug=y ubsan=y  Not tainted ]----
> ...
> (XEN) Xen call trace:
> (XEN)    [<0031b4c0>] ubsan.c#ubsan_epilogue+0x18/0xf0 (PC)
> (XEN)    [<0031d134>] __ubsan_handle_pointer_overflow+0xb8/0xd4 (LR)
> (XEN)    [<0031d134>] __ubsan_handle_pointer_overflow+0xb8/0xd4
> (XEN)    [<004d15a8>] start_xen+0xe0/0xbe0
> (XEN)    [<0020007c>] head.o#primary_switched+0x4/0x30
> 
> The failure is reported for the following line:
> (paddr_t)(uintptr_t)(_start + boot_phys_offset)
> 
> This occurs because the compiler treats (ptr + size) with size bigger than
> PTRDIFF_MAX as undefined behavior. To address this, switch to macro
> virt_to_maddr(), given the future plans to eliminate boot_phys_offset.
> 
> Signed-off-by: Michal Orzel <michal.orzel@amd.com>
> ---
>   xen/arch/arm/setup.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
> index 7e28f62d09f1..424744ad5e1a 100644
> --- a/xen/arch/arm/setup.c
> +++ b/xen/arch/arm/setup.c
> @@ -736,7 +736,7 @@ void asmlinkage __init start_xen(unsigned long boot_phys_offset,
>   
>       /* Register Xen's load address as a boot module. */
>       xen_bootmodule = add_boot_module(BOOTMOD_XEN,
> -                             (paddr_t)(uintptr_t)(_start + boot_phys_offset),
> +                             virt_to_maddr(_start),

The two lines can now be merged. So I have done it while committing.

Also, Stefano, I think this wants to be backported.

Cheers,

-- 
Julien Grall
Re: [PATCH] xen/arm: Fix UBSAN failure in start_xen()
Posted by Luca Fancellu 2 months, 3 weeks ago

> On 8 Feb 2024, at 10:43, Michal Orzel <michal.orzel@amd.com> wrote:
> 
> When running Xen on arm32, in scenario where Xen is loaded at an address
> such as boot_phys_offset >= 2GB, UBSAN reports the following:
> 
> (XEN) UBSAN: Undefined behaviour in arch/arm/setup.c:739:58
> (XEN) pointer operation underflowed 00200000 to 86800000
> (XEN) Xen WARN at common/ubsan/ubsan.c:172
> (XEN) ----[ Xen-4.19-unstable  arm32  debug=y ubsan=y  Not tainted ]----
> ...
> (XEN) Xen call trace:
> (XEN)    [<0031b4c0>] ubsan.c#ubsan_epilogue+0x18/0xf0 (PC)
> (XEN)    [<0031d134>] __ubsan_handle_pointer_overflow+0xb8/0xd4 (LR)
> (XEN)    [<0031d134>] __ubsan_handle_pointer_overflow+0xb8/0xd4
> (XEN)    [<004d15a8>] start_xen+0xe0/0xbe0
> (XEN)    [<0020007c>] head.o#primary_switched+0x4/0x30
> 
> The failure is reported for the following line:
> (paddr_t)(uintptr_t)(_start + boot_phys_offset)
> 
> This occurs because the compiler treats (ptr + size) with size bigger than
> PTRDIFF_MAX as undefined behavior. To address this, switch to macro
> virt_to_maddr(), given the future plans to eliminate boot_phys_offset.
> 
> Signed-off-by: Michal Orzel <michal.orzel@amd.com>
> ---

Hi Michal,

I’ve tested this change with qemu for arm32 and arm64, looks good to me:

Reviewed-by: Luca Fancellu <luca.fancellu@arm.com>
Tested-by: Luca Fancellu <luca.fancellu@arm.com>