From: Qianfeng Rong rongqianfeng@vivo.com
[ Upstream commit 4c634b6b3c77bba237ee64bca172e73f9cee0cb2 ]
As noted in the kernel documentation [1], open-coded multiplication in allocator arguments is discouraged because it can lead to integer overflow.
Use kcalloc() to gain built-in overflow protection, making memory allocation safer when calculating allocation size compared to explicit multiplication. Similarly, use size_add() instead of explicit addition for 'uobj_chunk_num + sobj_chunk_num'.
Link: https://www.kernel.org/doc/html/next/process/deprecated.html#open-coded-arit... #1 Signed-off-by: Qianfeng Rong rongqianfeng@vivo.com Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Acked-by: Giovanni Cabiddu giovanni.cabiddu@intel.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES
- What changed: The allocation in drivers/crypto/intel/qat/qat_common/qat_uclo.c:1903 switched from open-coded arithmetic to overflow-aware helpers: - New: kcalloc(size_add(uobj_chunk_num, sobj_chunk_num), sizeof(*mobj_hdr), GFP_KERNEL) at drivers/crypto/intel/qat/qat_common/qat_uclo.c:1903. - This replaces a prior kzalloc((uobj_chunk_num + sobj_chunk_num) * sizeof(*mobj_hdr), GFP_KERNEL) (per diff), eliminating unchecked addition and multiplication in the allocator arguments.
- Why it matters: The element count comes directly from MOF-parsed headers: - Counts are read from the object headers at drivers/crypto/intel/qat/qat_common/qat_uclo.c:1896–1901 (uobj_hdr->num_chunks, sobj_hdr->num_chunks; defined as unsigned short in drivers/crypto/intel/qat/qat_common/icp_qat_uclo.h:562). - The allocated array is then indexed for each chunk in two loops at drivers/crypto/intel/qat/qat_common/qat_uclo.c:1916–1923 and 1926–1933. If the allocation were undersized due to integer overflow in the size calculation, these loops could write past the end of the buffer. - The MOF data ultimately originates from firmware loaded via request_firmware() and passed to qat_uclo_map_obj() (drivers/crypto/intel/qat/qat_common/adf_accel_engine.c:67–85, 93–101), so a malformed or corrupted file can drive these values. This makes integer-overflow hardening here security-relevant.
- Why it’s a good stable backport: - Bug fix: Prevents potential integer overflow (both addition and multiplication) when computing an allocation size from externally supplied data. kcalloc() provides built-in multiply overflow checking; size_add() prevents addition overflow before the multiply. - Minimal and contained: One-line behavioral change in a single helper, no API/ABI or architectural changes, same zero- initialization semantics as kzalloc. - Low regression risk: On valid inputs behavior is unchanged; on overflow it now fails cleanly with -ENOMEM at drivers/crypto/intel/qat/qat_common/qat_uclo.c:1905, which propagates to the existing error paths and cleanup. - Subsystem impact: Localized to the Intel QAT firmware loading path; does not affect core crypto or memory management.
- Notes for backporting: - If a target stable series lacks size_add(), the same safety intent can be preserved by using kcalloc(uobj_chunk_num + sobj_chunk_num, sizeof(*mobj_hdr), GFP_KERNEL) where the kcalloc() multiply overflow check still blocks the dangerous case. Using size_add() is preferred when available.
Given the clear safety improvement, tiny scope, and near-zero regression risk, this is an appropriate candidate for stable backporting.
drivers/crypto/intel/qat/qat_common/qat_uclo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/crypto/intel/qat/qat_common/qat_uclo.c b/drivers/crypto/intel/qat/qat_common/qat_uclo.c index 21d652a1c8ef3..18c3e4416dc51 100644 --- a/drivers/crypto/intel/qat/qat_common/qat_uclo.c +++ b/drivers/crypto/intel/qat/qat_common/qat_uclo.c @@ -1900,7 +1900,7 @@ static int qat_uclo_map_objs_from_mof(struct icp_qat_mof_handle *mobj_handle) if (sobj_hdr) sobj_chunk_num = sobj_hdr->num_chunks;
- mobj_hdr = kzalloc((uobj_chunk_num + sobj_chunk_num) * + mobj_hdr = kcalloc(size_add(uobj_chunk_num, sobj_chunk_num), sizeof(*mobj_hdr), GFP_KERNEL); if (!mobj_hdr) return -ENOMEM;