From 93471b68954c1b81d1099461cb724046c9a5bca9 Mon Sep 17 00:00:00 2001 From: Cristian Stoica Date: Tue, 23 Sep 2014 13:44:40 +0300 Subject: crypto: caamctrl: fix array out of bound access desc_len(desc) returns a result masked by a seven bits mask representing a descriptor length. The maximum length is 64 u32 words but masking allows for larger but incorrect values. This fix adds a bound check to the index of deco.descbuf array (which is smaller than the maximum of 64 words), to avoid invalid memory accesses. (based on commit 05dbe2ed7da7d67cfd8915382c2559db684a0a29) Signed-off-by: Cristian Stoica Signed-off-by: Matthew Weigel Change-Id: I05dbe2ed7da7d67cfd8915382c2559db684a0a29 Conflicts: drivers/crypto/caam/ctrl.c Reviewed-on: http://git.am.freescale.net:8181/19805 Tested-by: Review Code-CDREVIEW Reviewed-by: Matthew Weigel diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 17c4cb9..9ea5005 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -76,6 +76,7 @@ static void build_deinstantiation_desc(u32 *desc, int handle) * Return: - 0 if no error occurred * - -ENODEV if the DECO couldn't be acquired * - -EAGAIN if an error occurred while executing the descriptor + * - -EINVAL if the descriptor length is incorrect */ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc, u32 *status) @@ -85,7 +86,7 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc, struct caam_deco __iomem *deco = ctrlpriv->deco; unsigned int timeout = 100000; u32 deco_dbg_reg, flags; - int i, ret; + int i, ret, dlen; if (ctrlpriv->virt_en == 1) { @@ -110,7 +111,14 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc, goto out_err; } - for (i = 0; i < desc_len(desc); i++) + dlen = desc_len(desc); + if (dlen > MAX_CAAM_DESCSIZE) { + dev_err(ctrldev, "invalid descriptor length\n"); + ret = -EINVAL; + goto out_err; + } + + for (i = 0; i < dlen; i++) wr_reg32(&deco->descbuf[i], *(desc + i)); flags = DECO_JQCR_WHL; @@ -118,7 +126,7 @@ static inline int run_descriptor_deco0(struct device *ctrldev, u32 *desc, * If the descriptor length is longer than 4 words, then the * FOUR bit in JRCTRL register must be set. */ - if (desc_len(desc) >= 4) + if (dlen >= 4) flags |= DECO_JQCR_FOUR; /* Instruct the DECO to execute it */ @@ -169,6 +177,7 @@ out_err: * - -EAGAIN if an error occurred when executing the descriptor * f.i. there was a RNG hardware error due to not "good enough" * entropy being aquired. + * - -EINVAL if the descriptor length is incorrect */ static int instantiate_rng(struct device *ctrldev, int state_handle_mask, int gen_sk) @@ -199,7 +208,8 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask, /* Try to run it through DECO0 */ ret = run_descriptor_deco0(ctrldev, desc, &status); - + if (ret) + break; /* * If ret is not 0, or descriptor status is not 0, then * something went wrong. No need to try the next state @@ -237,6 +247,7 @@ static int instantiate_rng(struct device *ctrldev, int state_handle_mask, * - -ENOMEM if there isn't enough memory to allocate the descriptor * - -ENODEV if DECO0 couldn't be acquired * - -EAGAIN if an error occurred when executing the descriptor + * - -EINVAL if the descriptor length is incorrect */ static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask) { -- cgit v0.10.2