--- /dev/null
+From dbfcef6b0f4012c57bc0b6e0e660d5ed12a5eaed Mon Sep 17 00:00:00 2001
+From: Sahitya Tummala <stummala@codeaurora.org>
+Date: Wed, 1 Feb 2017 20:49:35 -0500
+Subject: jbd2: fix use after free in kjournald2()
+
+From: Sahitya Tummala <stummala@codeaurora.org>
+
+commit dbfcef6b0f4012c57bc0b6e0e660d5ed12a5eaed upstream.
+
+Below is the synchronization issue between unmount and kjournald2
+contexts, which results into use after free issue in kjournald2().
+Fix this issue by using journal->j_state_lock to synchronize the
+wait_event() done in journal_kill_thread() and the wake_up() done
+in kjournald2().
+
+TASK 1:
+umount cmd:
+ |--jbd2_journal_destroy() {
+ |--journal_kill_thread() {
+ write_lock(&journal->j_state_lock);
+ journal->j_flags |= JBD2_UNMOUNT;
+ ...
+ write_unlock(&journal->j_state_lock);
+ wake_up(&journal->j_wait_commit); TASK 2 wakes up here:
+ kjournald2() {
+ ...
+ checks JBD2_UNMOUNT flag and calls goto end-loop;
+ ...
+ end_loop:
+ write_unlock(&journal->j_state_lock);
+ journal->j_task = NULL; --> If this thread gets
+ pre-empted here, then TASK 1 wait_event will
+ exit even before this thread is completely
+ done.
+ wait_event(journal->j_wait_done_commit, journal->j_task == NULL);
+ ...
+ write_lock(&journal->j_state_lock);
+ write_unlock(&journal->j_state_lock);
+ }
+ |--kfree(journal);
+ }
+}
+ wake_up(&journal->j_wait_done_commit); --> this step
+ now results into use after free issue.
+ }
+
+Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Cc: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/jbd2/journal.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/jbd2/journal.c
++++ b/fs/jbd2/journal.c
+@@ -275,11 +275,11 @@ loop:
+ goto loop;
+
+ end_loop:
+- write_unlock(&journal->j_state_lock);
+ del_timer_sync(&journal->j_commit_timer);
+ journal->j_task = NULL;
+ wake_up(&journal->j_wait_done_commit);
+ jbd_debug(1, "Journal thread exiting.\n");
++ write_unlock(&journal->j_state_lock);
+ return 0;
+ }
+