]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.10.72/dm-snapshot-fix-a-possible-invalid-memory-access-on-unload.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.10.72 / dm-snapshot-fix-a-possible-invalid-memory-access-on-unload.patch
1 From 22aa66a3ee5b61e0f4a0bfeabcaa567861109ec3 Mon Sep 17 00:00:00 2001
2 From: Mikulas Patocka <mpatocka@redhat.com>
3 Date: Tue, 17 Feb 2015 14:34:00 -0500
4 Subject: dm snapshot: fix a possible invalid memory access on unload
5
6 From: Mikulas Patocka <mpatocka@redhat.com>
7
8 commit 22aa66a3ee5b61e0f4a0bfeabcaa567861109ec3 upstream.
9
10 When the snapshot target is unloaded, snapshot_dtr() waits until
11 pending_exceptions_count drops to zero. Then, it destroys the snapshot.
12 Therefore, the function that decrements pending_exceptions_count
13 should not touch the snapshot structure after the decrement.
14
15 pending_complete() calls free_pending_exception(), which decrements
16 pending_exceptions_count, and then it performs up_write(&s->lock) and it
17 calls retry_origin_bios() which dereferences s->origin. These two
18 memory accesses to the fields of the snapshot may touch the dm_snapshot
19 struture after it is freed.
20
21 This patch moves the call to free_pending_exception() to the end of
22 pending_complete(), so that the snapshot will not be destroyed while
23 pending_complete() is in progress.
24
25 Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
26 Signed-off-by: Mike Snitzer <snitzer@redhat.com>
27 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28
29 ---
30 drivers/md/dm-snap.c | 4 ++--
31 1 file changed, 2 insertions(+), 2 deletions(-)
32
33 --- a/drivers/md/dm-snap.c
34 +++ b/drivers/md/dm-snap.c
35 @@ -1439,8 +1439,6 @@ out:
36 full_bio->bi_end_io = pe->full_bio_end_io;
37 full_bio->bi_private = pe->full_bio_private;
38 }
39 - free_pending_exception(pe);
40 -
41 increment_pending_exceptions_done_count();
42
43 up_write(&s->lock);
44 @@ -1457,6 +1455,8 @@ out:
45 }
46
47 retry_origin_bios(s, origin_bios);
48 +
49 + free_pending_exception(pe);
50 }
51
52 static void commit_callback(void *context, int success)