Linux cryptographic layer development
 help / color / mirror / Atom feed
From: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
To: Patrick McHardy <kaber@trash.net>
Cc: Herbert Xu <herbert@gondor.apana.org.au>, linux-crypto@vger.kernel.org
Subject: Re: HIFN+IPsec crashes in current -git
Date: Fri, 22 Feb 2008 15:42:14 +0300	[thread overview]
Message-ID: <20080222124211.GA15003@2ka.mipt.ru> (raw)
In-Reply-To: <47BD98F2.4080305@trash.net>

Hi Patrick.

On Thu, Feb 21, 2008 at 04:29:54PM +0100, Patrick McHardy (kaber@trash.net) wrote:
> Unfortunately still no luck. I got an error from ablkcipher_add()
> because of this condition:

...

> - further down it uses dst->length in the last while-loop,
>   which seems to need a similar change.

Does this patch  (on top of unpatched tree) helps?
I can not test it with real hardware, since I'm sicking at home with
laptop only, but I already know how to make a test case for this problem
without complex setup, so if it does not work, I will investigate it
further as soon as be able to move to office with testing machine :)

diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index dfbf24c..7807ca9 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -1464,7 +1464,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
 		crypto_ablkcipher_alignmask(crypto_ablkcipher_reqtfm(req));
 	struct scatterlist *src, *dst, *t;
 	void *daddr;
-	unsigned int nbytes = req->nbytes, offset, copy, diff;
+	unsigned int nbytes = req->nbytes, offset, copy, diff, nb;
 	int idx, tidx, err;
 
 	tidx = idx = 0;
@@ -1475,11 +1475,13 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
 
 		src = &req->src[idx];
 		dst = &req->dst[idx];
+		
+		nb = min(nbytes, src->length);
 
 		dprintk("\n%s: slen: %u, dlen: %u, soff: %u, doff: %u, offset: %u, "
-				"blocksize: %u, nbytes: %u.\n",
+				"blocksize: %u, nbytes: %u, nb: %u.\n",
 				__func__, src->length, dst->length, src->offset,
-				dst->offset, offset, blocksize, nbytes);
+				dst->offset, offset, blocksize, nbytes, nb);
 
 		if (src->length & (blocksize - 1) ||
 				src->offset & (alignmask - 1) ||
@@ -1492,7 +1494,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
 			t = &w->cache[idx];
 
 			daddr = kmap_atomic(sg_page(t), KM_SOFTIRQ0);
-			err = ablkcipher_add(daddr, &dlen, src, slen, &nbytes);
+			err = ablkcipher_add(daddr, &dlen, src, nb, &nbytes);
 			if (err < 0)
 				goto err_out_unmap;
 
@@ -1501,7 +1503,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
 			copy = slen & ~(blocksize - 1);
 			diff = slen & (blocksize - 1);
 
-			if (dlen < nbytes) {
+			if (dlen < nb) {
 				/*
 				 * Destination page does not have enough space
 				 * to put there additional blocksized chunk,
@@ -1510,17 +1512,17 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
 				 * 	t->length = (slen & ~(blocksize - 1));
 				 * and increase number of bytes to be processed
 				 * in next chunk:
-				 * 	nbytes += diff;
+				 * 	nb += diff;
 				 */
-				nbytes += diff;
+				nb += diff;
 
 				/*
 				 * Temporary of course...
 				 * Kick author if you will catch this one.
 				 */
 				printk(KERN_ERR "%s: dlen: %u, nbytes: %u,"
-					"slen: %u, offset: %u.\n",
-					__func__, dlen, nbytes, slen, offset);
+					"slen: %u, offset: %u, nb: %u.\n",
+					__func__, dlen, nbytes, slen, offset, nb);
 				printk(KERN_ERR "%s: please contact author to fix this "
 					"issue, generally you should not catch "
 					"this path under any condition but who "
@@ -1528,11 +1530,11 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
 					"Thank you.\n",	__func__);
 				BUG();
 			} else {
-				copy += diff + nbytes;
+				copy += diff + nb;
 
 				src = &req->src[idx];
 
-				err = ablkcipher_add(daddr + slen, &dlen, src, nbytes, &nbytes);
+				err = ablkcipher_add(daddr + slen, &dlen, src, nb, &nbytes);
 				if (err < 0)
 					goto err_out_unmap;
 
@@ -1544,7 +1546,7 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
 
 			kunmap_atomic(daddr, KM_SOFTIRQ0);
 		} else {
-			nbytes -= src->length;
+			nbytes -= nb;
 			idx++;
 		}
 
@@ -1564,7 +1566,7 @@ static int hifn_setup_session(struct ablkcipher_request *req)
 	struct hifn_device *dev = ctx->dev;
 	struct page *spage, *dpage;
 	unsigned long soff, doff, flags;
-	unsigned int nbytes = req->nbytes, idx = 0, len;
+	unsigned int nbytes = req->nbytes, idx = 0, len, nb;
 	int err = -EINVAL, sg_num;
 	struct scatterlist *src, *dst, *t;
 	unsigned blocksize =
@@ -1581,6 +1583,8 @@ static int hifn_setup_session(struct ablkcipher_request *req)
 		src = &req->src[idx];
 		dst = &req->dst[idx];
 
+		nb = min(src->length, nbytes);
+
 		if (src->length & (blocksize - 1) ||
 				src->offset & (alignmask - 1) ||
 				dst->length & (blocksize - 1) ||
@@ -1588,7 +1592,7 @@ static int hifn_setup_session(struct ablkcipher_request *req)
 			ctx->walk.flags |= ASYNC_FLAGS_MISALIGNED;
 		}
 
-		nbytes -= src->length;
+		nbytes -= nb;
 		idx++;
 	}
 
@@ -1602,6 +1606,10 @@ static int hifn_setup_session(struct ablkcipher_request *req)
 	idx = 0;
 
 	sg_num = ablkcipher_walk(req, &ctx->walk);
+	if (sg_num < 0) {
+		err = sg_num;
+		goto err_out_exit;
+	}
 
 	atomic_set(&ctx->sg_num, sg_num);
 
@@ -1632,10 +1640,12 @@ static int hifn_setup_session(struct ablkcipher_request *req)
 
 			len = dst->length;
 		}
+		
+		nb = min(len, nbytes);
 
 		idx++;
 
-		err = hifn_setup_dma(dev, spage, soff, dpage, doff, nbytes,
+		err = hifn_setup_dma(dev, spage, soff, dpage, doff, nb,
 				req, ctx);
 		if (err)
 			goto err_out;
@@ -1652,7 +1662,7 @@ err_out:
 	spin_unlock_irqrestore(&dev->lock, flags);
 err_out_exit:
 	if (err && printk_ratelimit())
-		dprintk("%s: iv: %p [%d], key: %p [%d], mode: %u, op: %u, "
+		printk("%s: iv: %p [%d], key: %p [%d], mode: %u, op: %u, "
 				"type: %u, err: %d.\n",
 			dev->name, ctx->iv, ctx->ivsize,
 			ctx->key, ctx->keysize,
@@ -1786,7 +1796,7 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error)
 		BUG();
 
 	if (atomic_dec_and_test(&ctx->sg_num)) {
-		unsigned int nbytes = req->nbytes;
+		unsigned int nbytes = req->nbytes, nb;
 		int idx = 0, err;
 		struct scatterlist *dst, *t;
 		void *saddr;
@@ -1796,6 +1806,8 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error)
 				t = &ctx->walk.cache[idx];
 				dst = &req->dst[idx];
 
+				nb = min(nbytes, dst->length);
+
 				dprintk("\n%s: sg_page(t): %p, t->length: %u, "
 					"sg_page(dst): %p, dst->length: %u, "
 					"nbytes: %u.\n",
@@ -1803,7 +1815,7 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error)
 					sg_page(dst), dst->length, nbytes);
 
 				if (!t->length) {
-					nbytes -= dst->length;
+					nbytes -= nb;
 					idx++;
 					continue;
 				}
@@ -1811,7 +1823,7 @@ static void hifn_process_ready(struct ablkcipher_request *req, int error)
 				saddr = kmap_atomic(sg_page(t), KM_IRQ1);
 
 				err = ablkcipher_get(saddr, &t->length, t->offset,
-						dst, nbytes, &nbytes);
+						dst, nb, &nbytes);
 				if (err < 0) {
 					kunmap_atomic(saddr, KM_IRQ1);
 					break;


-- 
	Evgeniy Polyakov

  parent reply	other threads:[~2008-02-22 12:43 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-13 13:17 HIFN+IPsec crashes in current -git Patrick McHardy
2008-02-13 14:44 ` Evgeniy Polyakov
2008-02-14  9:30   ` Evgeniy Polyakov
2008-02-19 16:10     ` Patrick McHardy
2008-02-19 16:14       ` Patrick McHardy
2008-02-19  6:23 ` Herbert Xu
2008-02-19 16:27   ` Patrick McHardy
2008-02-20  0:53     ` Herbert Xu
2008-02-20 12:33       ` Patrick McHardy
2008-02-20 13:19         ` Evgeniy Polyakov
2008-02-20 17:29           ` Herbert Xu
2008-02-20 17:26         ` Herbert Xu
2008-02-21  9:10           ` Evgeniy Polyakov
2008-02-21 14:10             ` Herbert Xu
2008-02-21 14:18               ` Evgeniy Polyakov
2008-02-21 14:20                 ` Patrick McHardy
2008-02-21 14:37                   ` Evgeniy Polyakov
2008-02-21 14:41                     ` Patrick McHardy
2008-02-21 15:29                       ` Patrick McHardy
2008-02-21 15:31                         ` Patrick McHardy
2008-02-22 12:42                         ` Evgeniy Polyakov [this message]
2008-02-22 13:53                           ` Patrick McHardy
2008-02-22  2:27               ` Test AES-CCM mode via IPSec (NETKEY) Loc Ho
2008-02-22  5:45                 ` Herbert Xu
2008-03-13 17:34                   ` Loc Ho
2008-03-14  1:12                     ` Herbert Xu
2008-04-04 22:37                     ` Joy Latten
2008-04-04 23:08                       ` Loc Ho

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080222124211.GA15003@2ka.mipt.ru \
    --to=johnpol@2ka.mipt.ru \
    --cc=herbert@gondor.apana.org.au \
    --cc=kaber@trash.net \
    --cc=linux-crypto@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox