[PATCH] crypto: ahash - Fix early termination in hash walk

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When supplied with an offset equal to PAGE_SIZE, the hash walk code returns
zero, resulting in early termination and, in the observed scenario, memory
corruption.  This patch fixes it by clamping nbytes only when walk->offset
is not at the PAGE_SIZE boundary.

Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Eli Cooper <elicooper@xxxxxxx>
---
 crypto/ahash.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/crypto/ahash.c b/crypto/ahash.c
index 3a35d67de7d9..03cbe04c53b1 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -46,8 +46,11 @@ static int hash_walk_next(struct crypto_hash_walk *walk)
 {
 	unsigned int alignmask = walk->alignmask;
 	unsigned int offset = walk->offset;
-	unsigned int nbytes = min(walk->entrylen,
-				  ((unsigned int)(PAGE_SIZE)) - offset);
+	unsigned int pagelen, nbytes = walk->entrylen;
+
+	pagelen = ((unsigned int)(PAGE_SIZE)) - offset;
+	if (pagelen)
+		nbytes = min(nbytes, pagelen);
 
 	if (walk->flags & CRYPTO_ALG_ASYNC)
 		walk->data = kmap(walk->pg);
@@ -86,7 +89,7 @@ static int hash_walk_new_entry(struct crypto_hash_walk *walk)
 int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err)
 {
 	unsigned int alignmask = walk->alignmask;
-	unsigned int nbytes = walk->entrylen;
+	unsigned int pagelen, nbytes = walk->entrylen;
 
 	walk->data -= walk->offset;
 
@@ -94,8 +97,9 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err)
 		walk->offset = ALIGN(walk->offset, alignmask + 1);
 		walk->data += walk->offset;
 
-		nbytes = min(nbytes,
-			     ((unsigned int)(PAGE_SIZE)) - walk->offset);
+		pagelen = ((unsigned int)(PAGE_SIZE)) - walk->offset;
+		if (pagelen)
+			nbytes = min(nbytes, pagelen);
 		walk->entrylen -= nbytes;
 
 		return nbytes;
-- 
2.16.2




[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux