[PATCH] hw/net/rocker: Don't overflow in of_dpa_mask2prefix()

Peter Maydell posted 1 patch 4 months, 1 week ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20250710144453.1187576-1-peter.maydell@linaro.org
Maintainers: Jiri Pirko <jiri@resnulli.us>, Jason Wang <jasowang@redhat.com>
There is a newer version of this series
hw/net/rocker/rocker_of_dpa.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH] hw/net/rocker: Don't overflow in of_dpa_mask2prefix()
Posted by Peter Maydell 4 months, 1 week ago
In of_dpa_mask2prefix() we do "(2 << i)" for a loop
where i can go up to 31. At i == 31 we shift off the
top end of an integer.

Use 2ULL to avoid this overflow.

Fixes: dc488f888060a ("rocker: add new rocker switch device")
Coverity: CID 1547602
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/net/rocker/rocker_of_dpa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
index 4aed1787566..9c0fc728eee 100644
--- a/hw/net/rocker/rocker_of_dpa.c
+++ b/hw/net/rocker/rocker_of_dpa.c
@@ -202,7 +202,7 @@ static int of_dpa_mask2prefix(uint32_t mask)
     int count = 32;
 
     for (i = 0; i < 32; i++) {
-        if (!(ntohl(mask) & ((2 << i) - 1))) {
+        if (!(ntohl(mask) & ((2ULL << i) - 1))) {
             count--;
         }
     }
-- 
2.43.0
Re: [PATCH] hw/net/rocker: Don't overflow in of_dpa_mask2prefix()
Posted by Philippe Mathieu-Daudé 4 months, 1 week ago
On 10/7/25 16:44, Peter Maydell wrote:
> In of_dpa_mask2prefix() we do "(2 << i)" for a loop
> where i can go up to 31. At i == 31 we shift off the
> top end of an integer.
> 
> Use 2ULL to avoid this overflow.
> 
> Fixes: dc488f888060a ("rocker: add new rocker switch device")
> Coverity: CID 1547602
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>   hw/net/rocker/rocker_of_dpa.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
> index 4aed1787566..9c0fc728eee 100644
> --- a/hw/net/rocker/rocker_of_dpa.c
> +++ b/hw/net/rocker/rocker_of_dpa.c
> @@ -202,7 +202,7 @@ static int of_dpa_mask2prefix(uint32_t mask)
>       int count = 32;
>   
>       for (i = 0; i < 32; i++) {
> -        if (!(ntohl(mask) & ((2 << i) - 1))) {
> +        if (!(ntohl(mask) & ((2ULL << i) - 1))) {
>               count--;
>           }
>       }

Alternatively using ctz (untested):

-- >8 --
diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
index 4aed1787566..431638dd64e 100644
--- a/hw/net/rocker/rocker_of_dpa.c
+++ b/hw/net/rocker/rocker_of_dpa.c
@@ -198,14 +198,5 @@ typedef struct of_dpa_group {

-static int of_dpa_mask2prefix(uint32_t mask)
+static unsigned of_dpa_mask2prefix(uint32_t mask)
  {
-    int i;
-    int count = 32;
-
-    for (i = 0; i < 32; i++) {
-        if (!(ntohl(mask) & ((2 << i) - 1))) {
-            count--;
-        }
-    }
-
-    return count;
+    return 32 - ctz32(cpu_to_be32(mask));
  }
---