[PATCH v2] disas: sparc: Fix integer overflow in compare_opcodes() for loop

Christian Barry posted 1 patch 4 days, 21 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260603190446.10319-1-christian.barry@usp.br
Maintainers: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Artyom Tarasenko <atar4qemu@gmail.com>
disas/sparc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
[PATCH v2] disas: sparc: Fix integer overflow in compare_opcodes() for loop
Posted by Christian Barry 4 days, 21 hours ago
From: Christian Barry <christian.barry@usp.br>

Replaced left-shift of a literal 1 by i inside of two for loops in compare_opcodes() with 1ul type qualifier. This makes it so 1 is explicitly interpreted as an unsigned long int, preventing overflows.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/2618

Signed-off-by: Christian Barry <christian.barry@usp.br>
Co-developed-by: Eduardo Augusto Cavalcanti <eduardoaugustoabc@ime.usp.br>
Signed-off-by: Eduardo Augusto Cavalcanti <eduardoaugustoabc@ime.usp.br>
---
 disas/sparc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/disas/sparc.c b/disas/sparc.c
index 5689533ce1..40c1164554 100644
--- a/disas/sparc.c
+++ b/disas/sparc.c
@@ -2515,7 +2515,7 @@ compare_opcodes (const void * a, const void * b)
      another, it is important to order the opcodes in the right order.  */
   for (i = 0; i < 32; ++i)
     {
-      unsigned long int x = 1 << i;
+      unsigned long int x = 1ul << i;
       int x0 = (match0 & x) != 0;
       int x1 = (match1 & x) != 0;
 
@@ -2525,7 +2525,7 @@ compare_opcodes (const void * a, const void * b)
 
   for (i = 0; i < 32; ++i)
     {
-      unsigned long int x = 1 << i;
+      unsigned long int x = 1ul << i;
       int x0 = (lose0 & x) != 0;
       int x1 = (lose1 & x) != 0;
 
-- 
2.43.0
Re: [PATCH v2] disas: sparc: Fix integer overflow in compare_opcodes() for loop
Posted by Philippe Mathieu-Daudé 4 days, 10 hours ago
Hi Christian,

On 3/6/26 21:04, Christian Barry wrote:
> From: Christian Barry <christian.barry@usp.br>
> 
> Replaced left-shift of a literal 1 by i inside of two for loops in compare_opcodes() with 1ul type qualifier. This makes it so 1 is explicitly interpreted as an unsigned long int, preventing overflows.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/2618
> 
> Signed-off-by: Christian Barry <christian.barry@usp.br>
> Co-developed-by: Eduardo Augusto Cavalcanti <eduardoaugustoabc@ime.usp.br>
> Signed-off-by: Eduardo Augusto Cavalcanti <eduardoaugustoabc@ime.usp.br>
> ---
>   disas/sparc.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/disas/sparc.c b/disas/sparc.c
> index 5689533ce1..40c1164554 100644
> --- a/disas/sparc.c
> +++ b/disas/sparc.c
> @@ -2515,7 +2515,7 @@ compare_opcodes (const void * a, const void * b)
>        another, it is important to order the opcodes in the right order.  */
>     for (i = 0; i < 32; ++i)
>       {
> -      unsigned long int x = 1 << i;
> +      unsigned long int x = 1ul << i;
>         int x0 = (match0 & x) != 0;
>         int x1 = (match1 & x) != 0;

As Artyom suggested we should cherry-pick binutils commit 4383e1fc3b326.

Alternatively:

   if (match0 != match1) {
       return extract32(match1, clz32(match0 ^ match1), 1) ?: -1;
   }