summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Dudau <adrian.dudau@enea.com>2016-05-26 10:12:29 +0200
committerMartin Borg <martin.borg@enea.com>2016-05-31 14:05:50 +0200
commit746363a33825f03166c37deeb185e3b72a4b46f8 (patch)
tree944ea86e65d4f128e07001c018ecc84d1f4baf32
parent90f55810228403b12bd663318e5dc16cc3089fc3 (diff)
downloadmeta-enea-bsp-arm-746363a33825f03166c37deeb185e3b72a4b46f8.tar.gz
linux-ls1: Fix kernel oops caused by fsnotify race condition
Backport from mainline. Only kernels <4.2 are affected by this. Signed-off-by: Adrian Dudau <adrian.dudau@enea.com> Signed-off-by: Martin Borg <martin.borg@enea.com>
-rw-r--r--recipes-kernel/linux/linux-ls1/0001-fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_f.patch80
-rw-r--r--recipes-kernel/linux/linux-ls1_3.12.bbappend1
2 files changed, 81 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ls1/0001-fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_f.patch b/recipes-kernel/linux/linux-ls1/0001-fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_f.patch
new file mode 100644
index 0000000..250c8db
--- /dev/null
+++ b/recipes-kernel/linux/linux-ls1/0001-fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_f.patch
@@ -0,0 +1,80 @@
1From 8f2f3eb59dff4ec538de55f2e0592fec85966aab Mon Sep 17 00:00:00 2001
2From: Jan Kara <jack@suse.com>
3Date: Thu, 6 Aug 2015 15:46:42 -0700
4Subject: [PATCH] fsnotify: fix oops in fsnotify_clear_marks_by_group_flags()
5
6fsnotify_clear_marks_by_group_flags() can race with
7fsnotify_destroy_marks() so that when fsnotify_destroy_mark_locked()
8drops mark_mutex, a mark from the list iterated by
9fsnotify_clear_marks_by_group_flags() can be freed and thus the next
10entry pointer we have cached may become stale and we dereference free
11memory.
12
13Fix the problem by first moving marks to free to a special private list
14and then always free the first entry in the special list. This method
15is safe even when entries from the list can disappear once we drop the
16lock.
17
18Upstream-Status: Backported
19
20Signed-off-by: Jan Kara <jack@suse.com>
21Reported-by: Ashish Sangwan <a.sangwan@samsung.com>
22Reviewed-by: Ashish Sangwan <a.sangwan@samsung.com>
23Cc: Lino Sanfilippo <LinoSanfilippo@gmx.de>
24Cc: <stable@vger.kernel.org>
25Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
26Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
27Signed-off-by: Adrian Dudau <adrian.dudau@enea.com>
28---
29 fs/notify/mark.c | 30 +++++++++++++++++++++++++-----
30 1 file changed, 25 insertions(+), 5 deletions(-)
31
32diff --git a/fs/notify/mark.c b/fs/notify/mark.c
33index 92e48c7..39ddcaf 100644
34--- a/fs/notify/mark.c
35+++ b/fs/notify/mark.c
36@@ -412,16 +412,36 @@ void fsnotify_clear_marks_by_group_flags(struct fsnotify_group *group,
37 unsigned int flags)
38 {
39 struct fsnotify_mark *lmark, *mark;
40+ LIST_HEAD(to_free);
41
42+ /*
43+ * We have to be really careful here. Anytime we drop mark_mutex, e.g.
44+ * fsnotify_clear_marks_by_inode() can come and free marks. Even in our
45+ * to_free list so we have to use mark_mutex even when accessing that
46+ * list. And freeing mark requires us to drop mark_mutex. So we can
47+ * reliably free only the first mark in the list. That's why we first
48+ * move marks to free to to_free list in one go and then free marks in
49+ * to_free list one by one.
50+ */
51 mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
52 list_for_each_entry_safe(mark, lmark, &group->marks_list, g_list) {
53- if (mark->flags & flags) {
54- fsnotify_get_mark(mark);
55- fsnotify_destroy_mark_locked(mark, group);
56- fsnotify_put_mark(mark);
57- }
58+ if (mark->flags & flags)
59+ list_move(&mark->g_list, &to_free);
60 }
61 mutex_unlock(&group->mark_mutex);
62+
63+ while (1) {
64+ mutex_lock_nested(&group->mark_mutex, SINGLE_DEPTH_NESTING);
65+ if (list_empty(&to_free)) {
66+ mutex_unlock(&group->mark_mutex);
67+ break;
68+ }
69+ mark = list_first_entry(&to_free, struct fsnotify_mark, g_list);
70+ fsnotify_get_mark(mark);
71+ fsnotify_destroy_mark_locked(mark, group);
72+ mutex_unlock(&group->mark_mutex);
73+ fsnotify_put_mark(mark);
74+ }
75 }
76
77 /*
78--
791.9.1
80
diff --git a/recipes-kernel/linux/linux-ls1_3.12.bbappend b/recipes-kernel/linux/linux-ls1_3.12.bbappend
index f34b2d1..338b3bf 100644
--- a/recipes-kernel/linux/linux-ls1_3.12.bbappend
+++ b/recipes-kernel/linux/linux-ls1_3.12.bbappend
@@ -1,6 +1,7 @@
1FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" 1FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
2 2
3SRC_URI += "file://ls1021aiot.dts \ 3SRC_URI += "file://ls1021aiot.dts \
4 file://0001-fsnotify-fix-oops-in-fsnotify_clear_marks_by_group_f.patch \
4 " 5 "
5 6
6# fix err: "linux-ls1-3.12-r0 do_deploy: Taskhash mismatch" 7# fix err: "linux-ls1-3.12-r0 do_deploy: Taskhash mismatch"