lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200126133805.20294-1-gilad@benyossef.com>
Date:   Sun, 26 Jan 2020 15:38:05 +0200
From:   Gilad Ben-Yossef <gilad@...yossef.com>
To:     Herbert Xu <herbert@...dor.apana.org.au>,
        "David S. Miller" <davem@...emloft.net>
Cc:     Ofir Drang <ofir.drang@....com>,
        Geert Uytterhoeven <geert@...ux-m68k.org>,
        linux-crypto@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [RFC] crypto: ccree - protect against short scatterlists

Deal gracefully with the event of being handed a scatterlist
which is shorter than expected.

This mitigates a crash in some cases of crashes due to
attempt to map empty (but not NULL) scatterlists with none
zero lengths.

This is an interim patch, to help diagnoze the issue, not
intended for mainline in its current form as of yet.

Signed-off-by: Gilad Ben-Yossef <gilad@...yossef.com>
Reported-by: Geert Uytterhoeven <geert@...ux-m68k.org>
---
 drivers/crypto/ccree/cc_buffer_mgr.c | 30 +++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c
index a72586eccd81..9667a2630c66 100644
--- a/drivers/crypto/ccree/cc_buffer_mgr.c
+++ b/drivers/crypto/ccree/cc_buffer_mgr.c
@@ -286,10 +286,32 @@ static void cc_add_sg_entry(struct device *dev, struct buffer_array *sgl_data,
 	sgl_data->num_of_buffers++;
 }
 
+static unsigned int cc_sg_trunc_len(struct scatterlist *sg, unsigned int len)
+{
+	unsigned int total;
+
+	if (!len)
+		return 0;
+
+	for (total = 0; sg; sg = sg_next(sg)) {
+		total += sg->length;
+		if (total >= len) {
+			total = len;
+			break;
+		}
+	}
+
+	return total;
+}
+
 static int cc_map_sg(struct device *dev, struct scatterlist *sg,
 		     unsigned int nbytes, int direction, u32 *nents,
 		     u32 max_sg_nents, u32 *lbytes, u32 *mapped_nents)
 {
+	int ret;
+
+	nbytes = cc_sg_trunc_len(sg, nbytes);
+
 	if (sg_is_last(sg)) {
 		/* One entry only case -set to DLLI */
 		if (dma_map_sg(dev, sg, 1, direction) != 1) {
@@ -313,12 +335,14 @@ static int cc_map_sg(struct device *dev, struct scatterlist *sg,
 		/* In case of mmu the number of mapped nents might
 		 * be changed from the original sgl nents
 		 */
-		*mapped_nents = dma_map_sg(dev, sg, *nents, direction);
-		if (*mapped_nents == 0) {
+		ret = dma_map_sg(dev, sg, *nents, direction);
+		if (dma_mapping_error(dev, ret)) {
 			*nents = 0;
-			dev_err(dev, "dma_map_sg() sg buffer failed\n");
+			dev_err(dev, "dma_map_sg() sg buffer failed %d\n", ret);
 			return -ENOMEM;
 		}
+
+		*mapped_nents = ret;
 	}
 
 	return 0;
-- 
2.23.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ