[PATCH] target/hppa: prevent overflow in BTLB entry size calculation

gerben@altlinux.org posted 1 patch 3 months, 3 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20250722101902.16613-1-gerben@altlinux.org
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Helge Deller <deller@gmx.de>
target/hppa/mem_helper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] target/hppa: prevent overflow in BTLB entry size calculation
Posted by gerben@altlinux.org 3 months, 3 weeks ago
From: Denis Rastyogin <gerben@altlinux.org>

Cast len to long long before multiplying by TARGET_PAGE_SIZE
when calculating btlb->itree.last to ensure 64-bit arithmetic
and avoid potential overflow.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Signed-off-by: Denis Rastyogin <gerben@altlinux.org>
---
 target/hppa/mem_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 9bdd0a6f23..0c196b5bfc 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -766,7 +766,7 @@ void HELPER(diag_btlb)(CPUHPPAState *env)
 
             /* Create new BTLB entry */
             btlb->itree.start = virt_page << TARGET_PAGE_BITS;
-            btlb->itree.last = btlb->itree.start + len * TARGET_PAGE_SIZE - 1;
+            btlb->itree.last = btlb->itree.start + (long long) len * TARGET_PAGE_SIZE - 1;
             btlb->pa = phys_page << TARGET_PAGE_BITS;
             set_access_bits_pa11(env, btlb, env->gr[20]);
             btlb->t = 0;
-- 
2.42.2
Re: [PATCH] target/hppa: prevent overflow in BTLB entry size calculation
Posted by Richard Henderson 3 months, 3 weeks ago
On 7/22/25 03:18, gerben@altlinux.org wrote:
> From: Denis Rastyogin <gerben@altlinux.org>
> 
> Cast len to long long before multiplying by TARGET_PAGE_SIZE
> when calculating btlb->itree.last to ensure 64-bit arithmetic
> and avoid potential overflow.
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Signed-off-by: Denis Rastyogin <gerben@altlinux.org>
> ---
>   target/hppa/mem_helper.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
> index 9bdd0a6f23..0c196b5bfc 100644
> --- a/target/hppa/mem_helper.c
> +++ b/target/hppa/mem_helper.c
> @@ -766,7 +766,7 @@ void HELPER(diag_btlb)(CPUHPPAState *env)
>   
>               /* Create new BTLB entry */
>               btlb->itree.start = virt_page << TARGET_PAGE_BITS;
> -            btlb->itree.last = btlb->itree.start + len * TARGET_PAGE_SIZE - 1;
> +            btlb->itree.last = btlb->itree.start + (long long) len * TARGET_PAGE_SIZE - 1;
>               btlb->pa = phys_page << TARGET_PAGE_BITS;
>               set_access_bits_pa11(env, btlb, env->gr[20]);
>               btlb->t = 0;

(1) long long is always wrong.

(2) If there's truncation anywhere, it's in the type of len itself:

       unsigned int len; len = env->gpr[21];

     However, from the comment at the top of the function I deduce
     this is a parisc-1.1 thing, where gprs are 32 bits, so this is
     producing the correct result.


r~