net/mlx5: Fix MCIA register buffer overflow on 32 dword reads

The MCIA register can return up to 32 dwords (128 bytes) when the device
advertises the mcia_32dwords capability, but struct
mlx5_ifc_mcia_reg_bits only defines dword_0..11, leaving room for just
12 dwords (48 bytes) of data.

mlx5_query_mcia() clamps the read size to mlx5_mcia_max_bytes() and then
memcpy()s that many bytes out of the register, potentially reading past
the end of the 'out' buffer. On kernels built with FORTIFY_SOURCE this
is caught as a buffer overflow while reading the module EEPROM via
ethtool:

  detected buffer overflow in memcpy
  kernel BUG at lib/string_helpers.c:1048!
  RIP: 0010:fortify_panic+0x13/0x20
  Call Trace:
   mlx5_query_mcia.isra.0+0x200/0x210 [mlx5_core]
   mlx5_query_module_eeprom_by_page+0x4a/0xa0 [mlx5_core]
   mlx5e_get_module_eeprom_by_page+0xbb/0x120 [mlx5_core]
   eeprom_prepare_data+0xf3/0x170
   ethnl_default_doit+0xf1/0x3b0

Extend the mcia_reg layout to 32 dwords.

Fixes: 271907ee2f ("net/mlx5: Query the maximum MCIA register read size from firmware")
Signed-off-by: Gal Pressman <gal@nvidia.com>
Reviewed-by: Alex Lazar <alazar@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260717072338.1240582-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Gal Pressman 2026-07-17 10:23:38 +03:00 committed by Jakub Kicinski
parent 9857fc06eb
commit 11c057d234
2 changed files with 3 additions and 14 deletions

View File

@ -314,7 +314,7 @@ static int mlx5_query_module_id(struct mlx5_core_dev *dev, int module_num,
return -EIO;
}
ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0);
ptr = MLX5_ADDR_OF(mcia_reg, out, dwords);
*module_id = ptr[0];
@ -399,7 +399,7 @@ static int mlx5_query_mcia(struct mlx5_core_dev *dev,
return -EIO;
}
ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0);
ptr = MLX5_ADDR_OF(mcia_reg, out, dwords);
memcpy(data, ptr, size);
return size;

View File

@ -12215,18 +12215,7 @@ struct mlx5_ifc_mcia_reg_bits {
u8 reserved_at_60[0x20];
u8 dword_0[0x20];
u8 dword_1[0x20];
u8 dword_2[0x20];
u8 dword_3[0x20];
u8 dword_4[0x20];
u8 dword_5[0x20];
u8 dword_6[0x20];
u8 dword_7[0x20];
u8 dword_8[0x20];
u8 dword_9[0x20];
u8 dword_10[0x20];
u8 dword_11[0x20];
u8 dwords[0x400];
};
struct mlx5_ifc_dcbx_param_bits {