On Mon, Feb 10, 2025 at 09:45:05AM -0800, Kees Cook wrote:
> GCC can see that the value range for "order" is capped, but this leads
> it to consider that it might be negative, leading to a false positive
> warning (with GCC 15 with -Warray-bounds -fdiagnostics-details):
>
> ../drivers/net/ethernet/mellanox/mlx4/alloc.c:691:47: error: array subscript
> -1 is below array bounds of 'long unsigned int *[2]' [-Werror=array-bounds=]
> 691 | i = find_first_bit(pgdir->bits[o], MLX4_DB_PER_PAGE
> >> o);
> | ~~~~~~~~~~~^~~
> 'mlx4_alloc_db_from_pgdir': events 1-2
> 691 | i = find_first_bit(pgdir->bits[o], MLX4_DB_PER_PAGE
> >> o); |
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> | | |
> | |
> (2) out of array bounds here
> | (1) when the condition is evaluated to true
> In file included from
> ../drivers/net/ethernet/mellanox/mlx4/mlx4.h:53,
> from ../drivers/net/ethernet/mellanox/mlx4/alloc.c:42:
> ../include/linux/mlx4/device.h:664:33: note: while referencing 'bits'
> 664 | unsigned long *bits[2];
> | ^~~~
>
> Switch the argument to unsigned int, which removes the compiler needing
> to consider negative values.
>
> Signed-off-by: Kees Cook <[email protected]>
> ---
> Cc: Tariq Toukan <[email protected]>
> Cc: Andrew Lunn <[email protected]>
> Cc: "David S. Miller" <[email protected]>
> Cc: Eric Dumazet <[email protected]>
> Cc: Jakub Kicinski <[email protected]>
> Cc: Paolo Abeni <[email protected]>
> Cc: Yishai Hadas <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> ---
> drivers/net/ethernet/mellanox/mlx4/alloc.c | 6 +++---
> include/linux/mlx4/device.h | 2 +-
> 2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx4/alloc.c
> b/drivers/net/ethernet/mellanox/mlx4/alloc.c
> index b330020dc0d6..f2bded847e61 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/alloc.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/alloc.c
> @@ -682,9 +682,9 @@ static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct
> device *dma_device)
> }
>
> static int mlx4_alloc_db_from_pgdir(struct mlx4_db_pgdir *pgdir,
> - struct mlx4_db *db, int order)
> + struct mlx4_db *db, unsigned int order)
> {
> - int o;
> + unsigned int o;
> int i;
>
> for (o = order; o <= 1; ++o) {
^ Knowing now that @order can only be 0 or 1 can this for loop (and
goto) be dropped entirely?
The code is already short and sweet so I don't feel strongly either
way.
> @@ -712,7 +712,7 @@ static int mlx4_alloc_db_from_pgdir(struct mlx4_db_pgdir
> *pgdir,
> return 0;
> }
>
> -int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order)
> +int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, unsigned int
> order)
> {
> struct mlx4_priv *priv = mlx4_priv(dev);
> struct mlx4_db_pgdir *pgdir;
> diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
> index 27f42f713c89..86f0f2a25a3d 100644
> --- a/include/linux/mlx4/device.h
> +++ b/include/linux/mlx4/device.h
> @@ -1135,7 +1135,7 @@ int mlx4_write_mtt(struct mlx4_dev *dev, struct
> mlx4_mtt *mtt,
> int mlx4_buf_write_mtt(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
> struct mlx4_buf *buf);
>
> -int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order);
> +int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, unsigned int
> order);
> void mlx4_db_free(struct mlx4_dev *dev, struct mlx4_db *db);
>
> int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources
> *wqres,
> --
> 2.34.1
>
Justin