]>
Commit | Line | Data |
---|---|---|
f24163ee GKH |
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 | @@ -1432,8 +1432,6 @@ out: | |
36 | full_bio->bi_private = pe->full_bio_private; | |
37 | atomic_inc(&full_bio->bi_remaining); | |
38 | } | |
39 | - free_pending_exception(pe); | |
40 | - | |
41 | increment_pending_exceptions_done_count(); | |
42 | ||
43 | up_write(&s->lock); | |
44 | @@ -1450,6 +1448,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) |