public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Lukas Czerner <lczerner@redhat.com>,
	Theodore Tso <tytso@mit.edu>, Jan Kara <jack@suse.cz>
Subject: [PATCH 3.14 38/64] ext4: fix NULL pointer dereference when journal restart fails
Date: Wed,  3 Jun 2015 20:43:06 +0900	[thread overview]
Message-ID: <20150603063930.074677630@linuxfoundation.org> (raw)
In-Reply-To: <20150603063928.472620468@linuxfoundation.org>

3.14-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Lukas Czerner <lczerner@redhat.com>

commit 9d506594069355d1fb2de3f9104667312ff08ed3 upstream.

Currently when journal restart fails, we'll have the h_transaction of
the handle set to NULL to indicate that the handle has been effectively
aborted. We handle this situation quietly in the jbd2_journal_stop() and just
free the handle and exit because everything else has been done before we
attempted (and failed) to restart the journal.

Unfortunately there are a number of problems with that approach
introduced with commit

41a5b913197c "jbd2: invalidate handle if jbd2_journal_restart()
fails"

First of all in ext4 jbd2_journal_stop() will be called through
__ext4_journal_stop() where we would try to get a hold of the superblock
by dereferencing h_transaction which in this case would lead to NULL
pointer dereference and crash.

In addition we're going to free the handle regardless of the refcount
which is bad as well, because others up the call chain will still
reference the handle so we might potentially reference already freed
memory.

Moreover it's expected that we'll get aborted handle as well as detached
handle in some of the journalling function as the error propagates up
the stack, so it's unnecessary to call WARN_ON every time we get
detached handle.

And finally we might leak some memory by forgetting to free reserved
handle in jbd2_journal_stop() in the case where handle was detached from
the transaction (h_transaction is NULL).

Fix the NULL pointer dereference in __ext4_journal_stop() by just
calling jbd2_journal_stop() quietly as suggested by Jan Kara. Also fix
the potential memory leak in jbd2_journal_stop() and use proper
handle refcounting before we attempt to free it to avoid use-after-free
issues.

And finally remove all WARN_ON(!transaction) from the code so that we do
not get random traces when something goes wrong because when journal
restart fails we will get to some of those functions.

Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 fs/ext4/ext4_jbd2.c   |    6 ++++++
 fs/jbd2/transaction.c |   25 ++++++++++++++++---------
 2 files changed, 22 insertions(+), 9 deletions(-)

--- a/fs/ext4/ext4_jbd2.c
+++ b/fs/ext4/ext4_jbd2.c
@@ -87,6 +87,12 @@ int __ext4_journal_stop(const char *wher
 		ext4_put_nojournal(handle);
 		return 0;
 	}
+
+	if (!handle->h_transaction) {
+		err = jbd2_journal_stop(handle);
+		return handle->h_err ? handle->h_err : err;
+	}
+
 	sb = handle->h_transaction->t_journal->j_private;
 	err = handle->h_err;
 	rc = jbd2_journal_stop(handle);
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -551,7 +551,6 @@ int jbd2_journal_extend(handle_t *handle
 	int result;
 	int wanted;
 
-	WARN_ON(!transaction);
 	if (is_handle_aborted(handle))
 		return -EROFS;
 	journal = transaction->t_journal;
@@ -627,7 +626,6 @@ int jbd2__journal_restart(handle_t *hand
 	tid_t		tid;
 	int		need_to_start, ret;
 
-	WARN_ON(!transaction);
 	/* If we've had an abort of any type, don't even think about
 	 * actually doing the restart! */
 	if (is_handle_aborted(handle))
@@ -791,7 +789,6 @@ do_get_write_access(handle_t *handle, st
 	int need_copy = 0;
 	unsigned long start_lock, time_lock;
 
-	WARN_ON(!transaction);
 	if (is_handle_aborted(handle))
 		return -EROFS;
 	journal = transaction->t_journal;
@@ -1057,7 +1054,6 @@ int jbd2_journal_get_create_access(handl
 	int err;
 
 	jbd_debug(5, "journal_head %p\n", jh);
-	WARN_ON(!transaction);
 	err = -EROFS;
 	if (is_handle_aborted(handle))
 		goto out;
@@ -1271,7 +1267,6 @@ int jbd2_journal_dirty_metadata(handle_t
 	struct journal_head *jh;
 	int ret = 0;
 
-	WARN_ON(!transaction);
 	if (is_handle_aborted(handle))
 		return -EROFS;
 	journal = transaction->t_journal;
@@ -1407,7 +1402,6 @@ int jbd2_journal_forget (handle_t *handl
 	int err = 0;
 	int was_modified = 0;
 
-	WARN_ON(!transaction);
 	if (is_handle_aborted(handle))
 		return -EROFS;
 	journal = transaction->t_journal;
@@ -1538,8 +1532,22 @@ int jbd2_journal_stop(handle_t *handle)
 	tid_t tid;
 	pid_t pid;
 
-	if (!transaction)
-		goto free_and_exit;
+	if (!transaction) {
+		/*
+		 * Handle is already detached from the transaction so
+		 * there is nothing to do other than decrease a refcount,
+		 * or free the handle if refcount drops to zero
+		 */
+		if (--handle->h_ref > 0) {
+			jbd_debug(4, "h_ref %d -> %d\n", handle->h_ref + 1,
+							 handle->h_ref);
+			return err;
+		} else {
+			if (handle->h_rsv_handle)
+				jbd2_free_handle(handle->h_rsv_handle);
+			goto free_and_exit;
+		}
+	}
 	journal = transaction->t_journal;
 
 	J_ASSERT(journal_current_handle() == handle);
@@ -2381,7 +2389,6 @@ int jbd2_journal_file_inode(handle_t *ha
 	transaction_t *transaction = handle->h_transaction;
 	journal_t *journal;
 
-	WARN_ON(!transaction);
 	if (is_handle_aborted(handle))
 		return -EROFS;
 	journal = transaction->t_journal;



  parent reply	other threads:[~2015-06-03 12:12 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-03 11:42 [PATCH 3.14 00/64] 3.14.44-stable review Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 01/64] staging: wlags49_h2: fix extern inline functions Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 02/64] staging, rtl8192e, LLVMLinux: Change extern inline to static inline Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 03/64] staging: rtl8712, rtl8712: avoid lots of build warnings Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 04/64] staging, rtl8192e, LLVMLinux: Remove unused inline prototype Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 05/64] kernel: use the gnu89 standard explicitly Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 06/64] qla2xxx: remove redundant declaration in qla_gbl.h Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 07/64] KVM: MMU: fix CR4.SMEP=1, CR0.WP=0 with shadow pages Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 08/64] net: socket: Fix the wrong returns for recvmsg and sendmsg Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 09/64] fs, omfs: add NULL terminator in the end up the token list Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 10/64] xfs: xfs_iozero can return positive errno Greg Kroah-Hartman
2015-06-03 13:15   ` Luis Henriques
2015-06-03 11:42 ` [PATCH 3.14 11/64] lguest: fix out-by-one error in address checking Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 12/64] libceph: request a new osdmap if lingering request maps to no osd Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 13/64] xen/events: dont bind non-percpu VIRQs with percpu chip Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 14/64] hwmon: (ntc_thermistor) Ensure iio channel is of type IIO_VOLTAGE Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 15/64] hwmon: (nct6775) Add missing sysfs attribute initialization Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 16/64] lib: Fix strnlen_user() to not touch memory after specified maximum Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 17/64] d_walk() might skip too much Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 18/64] ALSA: hda - Add Conexant codecs CX20721, CX20722, CX20723 and CX20724 Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 19/64] ALSA: hda - Add headphone quirk for Lifebook E752 Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 21/64] ASoC: mc13783: Fix wrong mask value used in mc13xxx_reg_rmw() calls Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 22/64] ASoC: uda1380: Avoid accessing i2c bus when codec is disabled Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 23/64] ASoC: wm8960: fix "RINPUT3" audio route error Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 24/64] ASoC: wm8994: correct BCLK DIV 348 to 384 Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 26/64] target/pscsi: Dont leak scsi_host if hba is VIRTUAL_HOST Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 27/64] xhci: fix isoc endpoint dequeue from advancing too far on transaction error Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 28/64] xhci: Solve full event ring by increasing TRBS_PER_SEGMENT to 256 Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 29/64] xhci: gracefully handle xhci_irq dead device Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 30/64] USB: visor: Match I330 phone more precisely Greg Kroah-Hartman
2015-06-03 11:42 ` [PATCH 3.14 31/64] USB: pl2303: Remove support for Samsung I330 Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 32/64] USB: cp210x: add ID for KCF Technologies PRN device Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 33/64] usb-storage: Add NO_WP_DETECT quirk for Lacie 059f:0651 devices Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 34/64] usb: gadget: configfs: Fix interfaces array NULL-termination Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 35/64] powerpc: Align TOC to 256 bytes Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 36/64] mmc: atmel-mci: fix bad variable type for clkdiv Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 37/64] tty/n_gsm.c: fix a memory leak when gsmtty is removed Greg Kroah-Hartman
2015-06-03 11:43 ` Greg Kroah-Hartman [this message]
2015-06-03 11:43 ` [PATCH 3.14 39/64] ext4: check for zero length extent explicitly Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 40/64] jbd2: fix r_count overflows leading to buffer overflow in journal recovery Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 41/64] libata: Add helper to determine when PHY events should be ignored Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 42/64] libata: Ignore spurious PHY event on LPM policy change Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 43/64] rt2x00: add new rt2800usb device DWA 130 Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 44/64] gpio: gpio-kempld: Fix get_direction return value Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 45/64] crypto: s390/ghash - Fix incorrect ghash icv buffer handling Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 46/64] mac80211: move WEP tailroom size check Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 48/64] ARM: fix missing syscall trace exit Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 49/64] tools/vm: fix page-flags build Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 50/64] mm, numa: really disable NUMA balancing by default on single node machines Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 51/64] svcrpc: fix potential GSSX_ACCEPT_SEC_CONTEXT decoding failures Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 52/64] thermal: step_wise: Revert optimization Greg Kroah-Hartman
2015-06-12 11:58   ` Luis Henriques
2015-06-03 11:43 ` [PATCH 3.14 53/64] md/raid5: dont record new size if resize_stripes fails Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 54/64] md/raid0: fix restore to sector variable in raid0_make_request Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 55/64] rtlwifi: rtl8192cu: Fix kernel deadlock Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 56/64] Input: elantech - fix semi-mt protocol for v3 HW Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 57/64] storvsc: Set the SRB flags correctly when no data transfer is needed Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 58/64] sd: Disable support for 256 byte/sector disks Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 59/64] ACPI / init: Fix the ordering of acpi_reserve_resources() Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 60/64] drm/radeon: add new bonaire pci id Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 63/64] vfs: read file_handle only once in handle_to_path Greg Kroah-Hartman
2015-06-03 11:43 ` [PATCH 3.14 64/64] fs/binfmt_elf.c:load_elf_binary(): return -EINVAL on zero-length mappings Greg Kroah-Hartman
2015-06-03 16:52 ` [PATCH 3.14 00/64] 3.14.44-stable review Shuah Khan
2015-06-03 18:15 ` Guenter Roeck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150603063930.074677630@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=jack@suse.cz \
    --cc=lczerner@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox