@@ -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;
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@vger.kernel.org Signed-off-by: Eli Cooper <elicooper@gmx.com> --- crypto/ahash.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)