[Concept,08/14] linux: jbd2: Add validation in jbd2_journal_write_metadata_buffer

Message ID 20251230205157.3383926-9-sjg@u-boot.org
State New
Headers
Series ext4l: Linux adaptation patches for ext4 write support |

Commit Message

Simon Glass Dec. 30, 2025, 8:51 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

When debugging journal corruption issues, invalid journal_head or
buffer_head pointers can cause crashes that are difficult to diagnose.

Add explicit validation of jh_in and its associated buffer_head at the
start of jbd2_journal_write_metadata_buffer() to catch corruption early
and provide useful debug output rather than crashing with a SIGSEGV.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 fs/jbd2/journal.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)
  

Patch

diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 0cd95df8192..138b650fae9 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -305,9 +305,31 @@  int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
 	struct buffer_head *new_bh;
 	struct folio *new_folio;
 	unsigned int new_offset;
-	struct buffer_head *bh_in = jh2bh(jh_in);
+	struct buffer_head *bh_in;
 	journal_t *journal = transaction->t_journal;
 
+#ifdef __UBOOT__
+	/* Validate jh_in before dereferencing */
+	if (!jh_in || !jh_in->b_bh) {
+		printf("jbd2: ERROR: invalid jh_in=%p b_bh=%p\n",
+		       jh_in, jh_in ? jh_in->b_bh : NULL);
+		return -EIO;
+	}
+#endif
+	bh_in = jh2bh(jh_in);
+#ifdef __UBOOT__
+	/* Additional validation for buffer head */
+	if (!bh_in->b_folio || !bh_in->b_blocknr) {
+		printf("jbd2: ERROR: bh=%p folio=%p blocknr=%llu b_data=%p b_count=%d\n",
+		       bh_in, bh_in->b_folio, (unsigned long long)bh_in->b_blocknr,
+		       bh_in->b_data, atomic_read(&bh_in->b_count));
+		printf("jbd2: ERROR: jh=%p b_jlist=%d b_jcount=%d b_next=%p\n",
+		       jh_in, jh_in->b_jlist, jh_in->b_jcount,
+		       jh_in->b_tnext);
+		return -EIO;
+	}
+#endif
+
 	/*
 	 * The buffer really shouldn't be locked: only the current committing
 	 * transaction is allowed to write it, so nobody else is allowed