From: Milan Broz <[email-masked]>

In the async case, kcryptd_crypt_write_io_submit() called from
kcryptd_crypt_write_convert() forgets to increment the pending reference count
before the queue_work() is issued.  The endio function could free it while
it is still in use in the calling thread.

-----

Fix a possible dereference of crypt io caused of wrong use
pending operation.

kcryptd_crypt_write_convert
  crypt_convert
    kcrypt_async_done (async mode callback)
    ..
    crypt_endio -> dec_pending(io) -> free(io) 
..
crypt_inc_pending(bad io)

crypt_dec_pending must be called before the crypt_convert
can fire async callback.

Signed-off-by: Milan Broz <[email-masked]>
Cc: [email-masked]
---
 drivers/md/dm-crypt.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

Index: linux/drivers/md/dm-crypt.c
===================================================================
--- linux.orig/drivers/md/dm-crypt.c	2008-08-05 14:14:01.000000000 +0100
+++ linux/drivers/md/dm-crypt.c	2008-08-05 14:14:02.000000000 +0100
@@ -674,6 +674,7 @@ static void kcryptd_crypt_write_io_submi
 		crypt_free_buffer_pages(cc, clone);
 		bio_put(clone);
 		io->error = -EIO;
+		crypt_dec_pending(io);
 		return;
 	}
 
@@ -685,10 +686,8 @@ static void kcryptd_crypt_write_io_submi
 
 	if (async)
 		kcryptd_queue_io(io);
-	else {
-		crypt_inc_pending(io);
+	else
 		generic_make_request(clone);
-	}
 }
 
 static void kcryptd_crypt_write_convert(struct dm_crypt_io *io)
@@ -720,6 +719,8 @@ static void kcryptd_crypt_write_convert(
 
 		remaining -= clone->bi_size;
 
+		crypt_inc_pending(io);
+
 		r = crypt_convert(cc, &io->ctx);
 
 		if (atomic_dec_and_test(&io->ctx.pending)) {
@@ -727,8 +728,7 @@ static void kcryptd_crypt_write_convert(
 			kcryptd_crypt_write_io_submit(io, r, 0);
 			if (unlikely(r < 0))
 				break;
-		} else
-			crypt_inc_pending(io);
+		}
 
 		/* out of memory -> run queues */
 		if (unlikely(remaining)) {