[PATCH] tcg: Silence ubsan error on tcg_splitwx_diff causing overflow

Fabiano Rosas posted 1 patch 4 days, 10 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260603223048.2574846-1-farosas@suse.de
Maintainers: Richard Henderson <richard.henderson@linaro.org>
There is a newer version of this series
tcg/region.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
[PATCH] tcg: Silence ubsan error on tcg_splitwx_diff causing overflow
Posted by Fabiano Rosas 4 days, 10 hours ago
UBSAN complains:
runtime error: addition of unsigned offset to 0x7bc06e1f5000
overflowed to 0x7bc02e1f5000

Cast the pointer to unsigned integer to perform the arithmetic and
silence the error.

Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
 tcg/region.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/tcg/region.c b/tcg/region.c
index 5d4be1453b..b405fa2ecb 100644
--- a/tcg/region.c
+++ b/tcg/region.c
@@ -112,7 +112,7 @@ const void *tcg_splitwx_to_rx(void *rw)
     /* Pass NULL pointers unchanged. */
     if (rw) {
         g_assert(in_code_gen_buffer(rw));
-        rw += tcg_splitwx_diff;
+        rw = (void *)((uintptr_t)rw + tcg_splitwx_diff);
     }
     return rw;
 }
@@ -121,7 +121,7 @@ void *tcg_splitwx_to_rw(const void *rx)
 {
     /* Pass NULL pointers unchanged. */
     if (rx) {
-        rx -= tcg_splitwx_diff;
+        rx = (void *)((uintptr_t)rx - tcg_splitwx_diff);
         /* Assert that we end with a pointer in the rw region. */
         g_assert(in_code_gen_buffer(rx));
     }
@@ -200,7 +200,7 @@ static struct tcg_region_tree *tc_ptr_to_region_tree(const void *p)
      * a signal handler over which the caller has no control.
      */
     if (!in_code_gen_buffer(p)) {
-        p -= tcg_splitwx_diff;
+        p = (void *)((uintptr_t)p - tcg_splitwx_diff);
         if (!in_code_gen_buffer(p)) {
             return NULL;
         }
@@ -763,8 +763,9 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned max_threads)
     /* Request large pages for the buffer and the splitwx.  */
     qemu_madvise(region.start_aligned, region.total_size, QEMU_MADV_HUGEPAGE);
     if (tcg_splitwx_diff) {
-        qemu_madvise(region.start_aligned + tcg_splitwx_diff,
-                     region.total_size, QEMU_MADV_HUGEPAGE);
+        uintptr_t buf_rx = (uintptr_t)region.start_aligned + tcg_splitwx_diff;
+
+        qemu_madvise((void *)buf_rx, region.total_size, QEMU_MADV_HUGEPAGE);
     }
 
     /*
-- 
2.53.0
Re: [PATCH] tcg: Silence ubsan error on tcg_splitwx_diff causing overflow
Posted by Richard Henderson 4 days, 9 hours ago
On 6/3/26 15:30, Fabiano Rosas wrote:
> UBSAN complains:
> runtime error: addition of unsigned offset to 0x7bc06e1f5000
> overflowed to 0x7bc02e1f5000
> 
> Cast the pointer to unsigned integer to perform the arithmetic and
> silence the error.
> 
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> ---
>   tcg/region.c | 11 ++++++-----
>   1 file changed, 6 insertions(+), 5 deletions(-)

That's irritating. Does it work to make tcg_splitwx_diff be ptrdiff_t instead?


r~


> 
> diff --git a/tcg/region.c b/tcg/region.c
> index 5d4be1453b..b405fa2ecb 100644
> --- a/tcg/region.c
> +++ b/tcg/region.c
> @@ -112,7 +112,7 @@ const void *tcg_splitwx_to_rx(void *rw)
>       /* Pass NULL pointers unchanged. */
>       if (rw) {
>           g_assert(in_code_gen_buffer(rw));
> -        rw += tcg_splitwx_diff;
> +        rw = (void *)((uintptr_t)rw + tcg_splitwx_diff);
>       }
>       return rw;
>   }
> @@ -121,7 +121,7 @@ void *tcg_splitwx_to_rw(const void *rx)
>   {
>       /* Pass NULL pointers unchanged. */
>       if (rx) {
> -        rx -= tcg_splitwx_diff;
> +        rx = (void *)((uintptr_t)rx - tcg_splitwx_diff);
>           /* Assert that we end with a pointer in the rw region. */
>           g_assert(in_code_gen_buffer(rx));
>       }
> @@ -200,7 +200,7 @@ static struct tcg_region_tree *tc_ptr_to_region_tree(const void *p)
>        * a signal handler over which the caller has no control.
>        */
>       if (!in_code_gen_buffer(p)) {
> -        p -= tcg_splitwx_diff;
> +        p = (void *)((uintptr_t)p - tcg_splitwx_diff);
>           if (!in_code_gen_buffer(p)) {
>               return NULL;
>           }
> @@ -763,8 +763,9 @@ void tcg_region_init(size_t tb_size, int splitwx, unsigned max_threads)
>       /* Request large pages for the buffer and the splitwx.  */
>       qemu_madvise(region.start_aligned, region.total_size, QEMU_MADV_HUGEPAGE);
>       if (tcg_splitwx_diff) {
> -        qemu_madvise(region.start_aligned + tcg_splitwx_diff,
> -                     region.total_size, QEMU_MADV_HUGEPAGE);
> +        uintptr_t buf_rx = (uintptr_t)region.start_aligned + tcg_splitwx_diff;
> +
> +        qemu_madvise((void *)buf_rx, region.total_size, QEMU_MADV_HUGEPAGE);
>       }
>   
>       /*