diff mbox series

crypto: cavium - prevent integer overflow loading firmware

Message ID YxDQpc9IINUuUhQr@kili (mailing list archive)
State Changes Requested
Delegated to: Herbert Xu
Headers show
Series crypto: cavium - prevent integer overflow loading firmware | expand

Commit Message

Dan Carpenter Sept. 1, 2022, 3:32 p.m. UTC
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>
---
 drivers/crypto/cavium/cpt/cptpf_main.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Comments

Herbert Xu Sept. 8, 2022, 9:42 a.m. UTC | #1
On Thu, Sep 01, 2022 at 06:32:53PM +0300, Dan Carpenter wrote:
>
> @@ -263,7 +264,13 @@ 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;
> +
> +	code_length = ntohl(ucode->code_length);
> +	if (code_length >= INT_MAX / 2) {
> +		ret = -EINVAL;
> +		goto fw_release;
> +	}
> +	mcode->code_size = code_length;

Where did the "* 2" go?

BTW, what is the threat model here? If the firmware metadata can't
be trusted, shouldn't we be capping the firmware size at a level
a lot lower than INT_MAX?

Cheers,
Dan Carpenter Sept. 15, 2022, 1:49 p.m. UTC | #2
On Thu, Sep 08, 2022 at 05:42:54PM +0800, Herbert Xu wrote:
> On Thu, Sep 01, 2022 at 06:32:53PM +0300, Dan Carpenter wrote:
> >
> > @@ -263,7 +264,13 @@ 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;
> > +
> > +	code_length = ntohl(ucode->code_length);
> > +	if (code_length >= INT_MAX / 2) {
> > +		ret = -EINVAL;
> > +		goto fw_release;
> > +	}
> > +	mcode->code_size = code_length;
> 
> Where did the "* 2" go?

Crud.  :/  Sorry.

> 
> BTW, what is the threat model here? If the firmware metadata can't
> be trusted, shouldn't we be capping the firmware size at a level
> a lot lower than INT_MAX?

This is not firmware metadata, I'm fairly sure the fw_entry->data is raw
data from the file system.  Realistically, if you can't trust your
firmware then you are probably toasted but there is a move to trust as
little as possible.  Also Smatch marks data from the file system as
untrusted so it will generate static checker warnings.

regards,
dan carpenter
diff mbox series

Patch

diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c
index 8c32d0eb8fcf..b196579dcd98 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,7 +264,13 @@  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;
+
+	code_length = ntohl(ucode->code_length);
+	if (code_length >= INT_MAX / 2) {
+		ret = -EINVAL;
+		goto fw_release;
+	}
+	mcode->code_size = code_length;
 	if (!mcode->code_size) {
 		ret = -EINVAL;
 		goto fw_release;