lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 08 Sep 2014 16:12:15 -0700
From:	"Darrick J. Wong" <darrick.wong@...cle.com>
To:	tytso@....edu, darrick.wong@...cle.com
Cc:	linux-ext4@...r.kernel.org, TR Reardon <thomas_reardon@...mail.com>
Subject: [PATCH 06/25] e2fsck: detect and repair external journal superblock
 checksum errors

Verify the (ext4) superblock checksum of an external journal device
and prompt to correct the checksum if nothing else is wrong with the
superblock.

Signed-off-by: Darrick J. Wong <darrick.wong@...cle.com>
Cc: TR Reardon <thomas_reardon@...mail.com>
---
 e2fsck/journal.c                               |   25 ++++++++++++++
 e2fsck/problem.c                               |    5 +++
 e2fsck/problem.h                               |    3 ++
 tests/j_corrupt_ext_jnl_sb_block/expect        |    5 +++
 tests/j_corrupt_ext_jnl_sb_block/image.tar.bz2 |  Bin
 tests/j_corrupt_ext_jnl_sb_block/name          |    1 +
 tests/j_corrupt_ext_jnl_sb_block/script        |   36 +++++++++++++++++++++
 tests/j_corrupt_ext_jnl_sb_csum/expect         |   25 ++++++++++++++
 tests/j_corrupt_ext_jnl_sb_csum/image.tar.bz2  |  Bin
 tests/j_corrupt_ext_jnl_sb_csum/name           |    1 +
 tests/j_corrupt_ext_jnl_sb_csum/script         |   42 ++++++++++++++++++++++++
 11 files changed, 142 insertions(+), 1 deletion(-)
 create mode 100644 tests/j_corrupt_ext_jnl_sb_block/expect
 create mode 100644 tests/j_corrupt_ext_jnl_sb_block/image.tar.bz2
 create mode 100644 tests/j_corrupt_ext_jnl_sb_block/name
 create mode 100644 tests/j_corrupt_ext_jnl_sb_block/script
 create mode 100644 tests/j_corrupt_ext_jnl_sb_csum/expect
 create mode 100644 tests/j_corrupt_ext_jnl_sb_csum/image.tar.bz2
 create mode 100644 tests/j_corrupt_ext_jnl_sb_csum/name
 create mode 100644 tests/j_corrupt_ext_jnl_sb_csum/script


diff --git a/e2fsck/journal.c b/e2fsck/journal.c
index a19d40b..16bd757 100644
--- a/e2fsck/journal.c
+++ b/e2fsck/journal.c
@@ -456,7 +456,6 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
 		}
 		memcpy(&jsuper, start ? bh->b_data :  bh->b_data + SUPERBLOCK_OFFSET,
 		       sizeof(jsuper));
-		brelse(bh);
 #ifdef WORDS_BIGENDIAN
 		if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
 			ext2fs_swap_super(&jsuper);
@@ -465,6 +464,7 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
 		    !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
 			fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
 			retval = EXT2_ET_LOAD_EXT_JOURNAL;
+			brelse(bh);
 			goto errout;
 		}
 		/* Make sure the journal UUID is correct */
@@ -472,9 +472,32 @@ static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
 			   sizeof(jsuper.s_uuid))) {
 			fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
 			retval = EXT2_ET_LOAD_EXT_JOURNAL;
+			brelse(bh);
 			goto errout;
 		}
 
+		/* Check the superblock checksum */
+		if (jsuper.s_feature_ro_compat &
+		    EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) {
+			struct struct_ext2_filsys fsx;
+			struct ext2_super_block	superx;
+			void *p;
+
+			p = start ? bh->b_data : bh->b_data + SUPERBLOCK_OFFSET;
+			memcpy(&fsx, ctx->fs, sizeof(fsx));
+			memcpy(&superx, ctx->fs->super, sizeof(superx));
+			fsx.super = &superx;
+			fsx.super->s_feature_ro_compat |=
+					EXT4_FEATURE_RO_COMPAT_METADATA_CSUM;
+			if (!ext2fs_superblock_csum_verify(&fsx, p) &&
+			    fix_problem(ctx, PR_0_EXT_JOURNAL_SUPER_CSUM_INVALID,
+					&pctx)) {
+				ext2fs_superblock_csum_set(&fsx, p);
+				mark_buffer_dirty(bh);
+			}
+		}
+		brelse(bh);
+
 		maxlen = ext2fs_blocks_count(&jsuper);
 		journal->j_maxlen = (maxlen < 1ULL << 32) ? maxlen : (1ULL << 32) - 1;
 		start++;
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 99ca7cb..4b41a21 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -459,6 +459,11 @@ static struct e2fsck_problem problem_table[] = {
 	  N_("First_meta_bg is too big.  (%N, max value %g).  "),
 	  PROMPT_CLEAR, 0 },
 
+	/* External journal has corrupt superblock */
+	{ PR_0_EXT_JOURNAL_SUPER_CSUM_INVALID,
+	  N_("External @j @S checksum does not match @S.  "),
+	  PROMPT_FIX, PR_PREEN_OK },
+
 	/* Pass 1 errors */
 
 	/* Pass 1: Checking inodes, blocks, and sizes */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index 5c92d0a..f86c531 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -264,6 +264,9 @@ struct problem_context {
 /* The first_meta_bg is too big */
 #define PR_0_FIRST_META_BG_TOO_BIG		0x000049
 
+/* External journal has corrupt superblock */
+#define PR_0_EXT_JOURNAL_SUPER_CSUM_INVALID	0x00004A
+
 /*
  * Pass 1 errors
  */
diff --git a/tests/j_corrupt_ext_jnl_sb_block/expect b/tests/j_corrupt_ext_jnl_sb_block/expect
new file mode 100644
index 0000000..e638e11
--- /dev/null
+++ b/tests/j_corrupt_ext_jnl_sb_block/expect
@@ -0,0 +1,5 @@
+External journal does not support this filesystem
+
+test_filesys: ********** WARNING: Filesystem still has errors **********
+
+Exit status is 12
diff --git a/tests/j_corrupt_ext_jnl_sb_block/image.tar.bz2 b/tests/j_corrupt_ext_jnl_sb_block/image.tar.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..efb382fafeb26de434c8d182fa155abe803e3d02
GIT binary patch
literal 939
zcmV;c162G%T4*^jL0KkKSz<fD_W**WfB*mg{mfbo|Lyj@...aJ-@)M(+E(B<X47Hk
zDTgOh>|ekG2LLG)kd#R@...Fi2x+0}Jtw5~2GlV$&>Cm~>H+EofEqMt4X6Ma8Uxe~
z9!(~XYMOeVst7d5$TDIy(*kLN448}rWYMD#Vi^pYGGK;ACWZ)P$j~&zGz^BBFd)+-
zAjyc+ObMn4GGZ_hlSYg|h-5No$$}XeniwIIBS6y-&@...z$8$FDL)YOQ`FKnqiTAX
z5$Ge(jW(u+nW_4w6F>$Lk?K7(XhQ_`Gyq{RO{Dc2F+DVqhfapJ9@...S;CWf=SQ~a
zuQoD6kcXKJiz*~_ZXx8j*}Yucz26L#7jq9SE?xC|wg$ngaj8~*y3`^O*Dj(sEt;Yb
zkq*`!ju+iJ64CqcO8J06hRZ;a1X^vRj3$s$!3i(%q_P?SMe6_rfhDhKNg(klGBovh
zRqjrdY>+_~5puf)sKbV_sOjJ<o^HA(4!ZHX8vifMqZ45~T<{ga`1JAY$S7@...*k_
zLh*&;1cZP9oussF2(Q=2h>4hMFW}gs^iHe4YL<mr34#Ft0fIG%(NJ<2uo}{`EEQHv
zGy%J5D7pp`dwWm|A&g^Pu1zq-QHZM5k%GW#EjA<}00Cya0+UMtXFE*sT-vj|RQl!u
zhj4xdblm)?7MM~<fn};Qk|BpSg#UA9K_|v$ihLs6gU+#DJw^@...2pKi|@...&+!@
zI7mb&?%T}HNSP2SPEvB6@...|Q4A4N@...bax+eOMkgg^V5KZSwXC6R5Hiiy&cWeh
zhNvLG$;rheDGFvlVTxgpQ6&L!<HYP#CL;=lsM?}H+-M;pX3-<Fl(Q8Awd)^*eami&
z+bt4%0>!e*r8|eYggc?+WlaspJ{tNCYn(D|l0r*WQ81JVr28xRF?NG!CYeCG?8Bdr
zJ=4@)7h%>R7R?k)Qi!8;RPYMWzC2dWYKsWHGM}c?r2zO2rGcxizBrfn!EszVfuJFe
zO$J9ys&5bIq>Sf>wK~KK-w*ReW2$iJ3}M8Y`wCNixB&*I8YNpr9GMFpWWV^NAFM0N
z&PS%6Aghy*UE)^yo5Vx;kd;;WJwo;^d~8991x?h+&FTl^HT^^&fNMsih01_0QX`4a
z2q8`lVY|9a@...-vu;}+`3+l0(gs-skFzQXAV2^V3%?Be2@...V4yHFd=ZLKMq)So
NUC9*TLP3b{1KjPKr%M0;

literal 0
HcmV?d00001

diff --git a/tests/j_corrupt_ext_jnl_sb_block/name b/tests/j_corrupt_ext_jnl_sb_block/name
new file mode 100644
index 0000000..a5188be
--- /dev/null
+++ b/tests/j_corrupt_ext_jnl_sb_block/name
@@ -0,0 +1 @@
+corrupt external journal fs superblock block (metadata_csum)
diff --git a/tests/j_corrupt_ext_jnl_sb_block/script b/tests/j_corrupt_ext_jnl_sb_block/script
new file mode 100644
index 0000000..02b8e65
--- /dev/null
+++ b/tests/j_corrupt_ext_jnl_sb_block/script
@@ -0,0 +1,36 @@
+FSCK_OPT=-fy
+OUT=$test_name.log
+if [ -f $test_dir/expect.gz ]; then
+	EXP=$test_name.tmp
+	gunzip < $test_dir/expect.gz > $EXP1
+else
+	EXP=$test_dir/expect
+fi
+
+cp /dev/null $OUT
+
+bzip2 -dc < $test_dir/image.tar.bz2 | tar x
+test -d "$JOURNAL_DUMP_DIR" -a -w "$JOURNAL_DUMP_DIR" && cp $test_name.img "$JOURNAL_DUMP_DIR/$test_name.img"
+test -d "$JOURNAL_DUMP_DIR" -a -w "$JOURNAL_DUMP_DIR" && cp $test_name.img.jnl "$JOURNAL_DUMP_DIR/$test_name.img.jnl"
+
+$FSCK $FSCK_OPT -N test_filesys -j $test_name.img.jnl $test_name.img > $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" $OUT.new >> $OUT
+rm -f $OUT.new
+
+rm -f $TMPFILE $test_name.img $test_name.img.jnl
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+	echo "$test_name: $test_description: ok"
+	touch $test_name.ok
+else
+	echo "$test_name: $test_description: failed"
+	diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+	rm -f $test_name.tmp
+fi
+
+unset IMAGE FSCK_OPT OUT EXP
diff --git a/tests/j_corrupt_ext_jnl_sb_csum/expect b/tests/j_corrupt_ext_jnl_sb_csum/expect
new file mode 100644
index 0000000..70a4fe7
--- /dev/null
+++ b/tests/j_corrupt_ext_jnl_sb_csum/expect
@@ -0,0 +1,25 @@
+External journal superblock checksum does not match superblock.  Fix? yes
+
+test_filesys: recovering journal
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+Block bitmap differences:  +(1--31) +34 +(50--82)
+Fix? yes
+
+Inode bitmap differences:  +(1--11)
+Fix? yes
+
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 11/128 files (0.0% non-contiguous), 66/2048 blocks
+Exit status is 1
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 11/128 files (0.0% non-contiguous), 66/2048 blocks
+Exit status is 0
diff --git a/tests/j_corrupt_ext_jnl_sb_csum/image.tar.bz2 b/tests/j_corrupt_ext_jnl_sb_csum/image.tar.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..d04d584c0389112d09a7427fd967a9d9605e68ac
GIT binary patch
literal 929
zcmV;S177?>T4*^jL0KkKS#@A;5dea(|NsC0{mj`}|L^_xUmpMW-qr2{7r{S85b04)
ztBp5X?Rmfh9ZCfiQ9@...PIk&iRm=aiRx`bO*DF$sp<_400*c5Xda*d4^T7!Xc~Hr
z1Jnj;V2=|}KpJVLnrVbGWHJmUhKvCX3<;wn2r_A-Kn4iV#4$9<rXvWznlxcF2m?(t
z(@ijjOol;((9wV)p@...VFpb!XaK<)7=|X9G{j*T6Gn_CfJmeeMyHh8jWqQ%4FDQ6
z05ll}hJXM713(6VGynhq8UPv<MB{@...y8L@@dqU12~~<oe2xv*oqL8pJ6tWl41I|
zt16?CKWB<YmgibSkI1ZrT1#w^v8*bjUOtf2N5#vkAy$ZRIM@...zU{%kV>(DM8h#u
zkpxQHNfr$ttYCzf*`&N}03wqB1c4=F(2_yotT>pN-8vPrq-|Kh8lcyix>U8%GD4$m
zSS5Yc!%W@...b$-bdSo?vC6W+7~$B*3VgaT#w22GH1P!{6q-U300LH$sM0G~j%J(R
z5Q`}wrZf%T+~-lMZA#Ez5SSnk02pzsvqa&>F<{!TWK0Pfp5+*T)-hlhh}?q-9k!kV
zq#9w{&?5+jiH#H*DGd|Yn*@...IFd~uz;)GHelSC^YTr!kO_{of982yy!aH_D+tI@
zWY5|}F66$SSnk*nvyi2eqO>x3CQndRg7FUvD*y?Kk5F*di-ft&S_m=?G)42@...n2
zJ9dkfUBA2E(+CK*8J%U2@...R+B;hKSNGC9q1oYB_H5=2mqx065%9v-7!fcywbuk<
zj0P~X83N7%gxLs)XK`vv)G8}@...|cXF#M+C^D`XGhD8L2z+UX3i2I{!aDI3?XSz3
z%ELdf5|kfve+B6}Y*6-n`P!0k`ADd)TVlFkZFE<b*a_C8s96RD&|P$ctocsI0PPn+
zdN^T!@...KnD2t6@...idNYlM1`K%F8&7m66`?U&+#9j_0=Zj<oWJs@...}NU|xtu
zO)6y%NdgxxwWJ!Nd8(`kKSKnzv#x-e8Z4dnsetthVUf;ATgsnJ5OIu6`zAIBQM5hz
zOi;7WELoxIJ+Ua{dE2(H`GZVMI+i%`@...1uKJVK0@...QJJ8~#Rh;`QDHBLh%!aJ
zK$%?$(y5FEtUWMD>)wAV;}3&K1ONg3o+vY?{U8b<fhYXdqBRScfAM!DQ-ui!RtDh^
DW^tU{

literal 0
HcmV?d00001

diff --git a/tests/j_corrupt_ext_jnl_sb_csum/name b/tests/j_corrupt_ext_jnl_sb_csum/name
new file mode 100644
index 0000000..c182f81
--- /dev/null
+++ b/tests/j_corrupt_ext_jnl_sb_csum/name
@@ -0,0 +1 @@
+corrupt external journal fs superblock csum (metadata_csum)
diff --git a/tests/j_corrupt_ext_jnl_sb_csum/script b/tests/j_corrupt_ext_jnl_sb_csum/script
new file mode 100644
index 0000000..7a110bf
--- /dev/null
+++ b/tests/j_corrupt_ext_jnl_sb_csum/script
@@ -0,0 +1,42 @@
+FSCK_OPT=-fy
+OUT=$test_name.log
+if [ -f $test_dir/expect.gz ]; then
+	EXP=$test_name.tmp
+	gunzip < $test_dir/expect.gz > $EXP1
+else
+	EXP=$test_dir/expect
+fi
+
+cp /dev/null $OUT
+
+bzip2 -dc < $test_dir/image.tar.bz2 | tar x
+test -d "$JOURNAL_DUMP_DIR" -a -w "$JOURNAL_DUMP_DIR" && cp $test_name.img "$JOURNAL_DUMP_DIR/$test_name.img"
+test -d "$JOURNAL_DUMP_DIR" -a -w "$JOURNAL_DUMP_DIR" && cp $test_name.img.jnl "$JOURNAL_DUMP_DIR/$test_name.img.jnl"
+
+$FSCK $FSCK_OPT -N test_filesys -j $test_name.img.jnl $test_name.img > $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" $OUT.new >> $OUT
+rm -f $OUT.new
+
+$FSCK $FSCK_OPT -N test_filesys -j $test_name.img.jnl $test_name.img > $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" $OUT.new >> $OUT
+rm -f $OUT.new
+
+rm -f $TMPFILE $test_name.img $test_name.img.jnl
+
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+	echo "$test_name: $test_description: ok"
+	touch $test_name.ok
+else
+	echo "$test_name: $test_description: failed"
+	diff $DIFF_OPTS $EXP $OUT > $test_name.failed
+	rm -f $test_name.tmp
+fi
+
+unset IMAGE FSCK_OPT OUT EXP

--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ