| From 91bb37b17c7a7b49708c86db8404e141ea6a8339 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 19 Sep 2022 09:43:27 +0300 |
| Subject: crypto: cavium - prevent integer overflow loading firmware |
| |
| From: Dan Carpenter <dan.carpenter@oracle.com> |
| |
| [ Upstream commit 2526d6bf27d15054bb0778b2f7bc6625fd934905 ] |
| |
| The "code_length" value comes from the firmware file. If your firmware |
| is untrusted realistically there is probably very little you can do to |
| protect yourself. Still we try to limit the damage as much as possible. |
| Also Smatch marks any data read from the filesystem as untrusted and |
| prints warnings if it not capped correctly. |
| |
| The "ntohl(ucode->code_length) * 2" multiplication can have an |
| integer overflow. |
| |
| Fixes: 9e2c7d99941d ("crypto: cavium - Add Support for Octeon-tx CPT Engine") |
| Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> |
| Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/crypto/cavium/cpt/cptpf_main.c | 6 ++++-- |
| 1 file changed, 4 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c |
| index 8c32d0eb8fcf..6872ac344001 100644 |
| --- a/drivers/crypto/cavium/cpt/cptpf_main.c |
| +++ b/drivers/crypto/cavium/cpt/cptpf_main.c |
| @@ -253,6 +253,7 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae) |
| const struct firmware *fw_entry; |
| struct device *dev = &cpt->pdev->dev; |
| struct ucode_header *ucode; |
| + unsigned int code_length; |
| struct microcode *mcode; |
| int j, ret = 0; |
| |
| @@ -263,11 +264,12 @@ static int cpt_ucode_load_fw(struct cpt_device *cpt, const u8 *fw, bool is_ae) |
| ucode = (struct ucode_header *)fw_entry->data; |
| mcode = &cpt->mcode[cpt->next_mc_idx]; |
| memcpy(mcode->version, (u8 *)fw_entry->data, CPT_UCODE_VERSION_SZ); |
| - mcode->code_size = ntohl(ucode->code_length) * 2; |
| - if (!mcode->code_size) { |
| + code_length = ntohl(ucode->code_length); |
| + if (code_length == 0 || code_length >= INT_MAX / 2) { |
| ret = -EINVAL; |
| goto fw_release; |
| } |
| + mcode->code_size = code_length * 2; |
| |
| mcode->is_ae = is_ae; |
| mcode->core_mask = 0ULL; |
| -- |
| 2.35.1 |
| |