From 575307cc63d24766ff789262a5cea7b4faf2fa13 Mon Sep 17 00:00:00 2001 From: Kalpak Shah Date: Mon, 9 Jul 2007 13:05:45 -0400 Subject: [PATCH] e2fsck: Fix salvage_directory when the last entry's rec_len is too big Recently, one of our customers found this message in pass2 of e2fsck while doing some regression testing: "Entry '4, 0x695a, 0x81ff, 0x0040, 0x8320, 0xa192, 0x0021' in ??? (136554) has rec_len of 14200, should be 26908." Both the displayed rec_len and the "should be" value are bogus. The reason is that salvage_directory sets a offset beyond blocksize leading to bogus messages. Signed-off-by: "Theodore Ts'o" --- e2fsck/pass2.c | 9 +++++---- tests/f_baddir2/expect.1 | 12 ++++++++++++ tests/f_baddir2/expect.2 | 7 +++++++ tests/f_baddir2/image.gz | Bin 0 -> 587 bytes tests/f_baddir2/name | 1 + 5 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 tests/f_baddir2/expect.1 create mode 100644 tests/f_baddir2/expect.2 create mode 100644 tests/f_baddir2/image.gz create mode 100644 tests/f_baddir2/name diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index e235348..5e088e2 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -675,11 +675,12 @@ static void salvage_directory(ext2_filsys fs, return; } /* - * If the directory entry is a multiple of four, so it is - * valid, let the previous directory entry absorb the invalid - * one. + * If the record length of the directory entry is a multiple + * of four, and not too big, such that it is valid, let the + * previous directory entry absorb the invalid one. */ - if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) { + if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0 && + (*offset + dirent->rec_len <= fs->blocksize)) { prev->rec_len += dirent->rec_len; *offset += dirent->rec_len; return; diff --git a/tests/f_baddir2/expect.1 b/tests/f_baddir2/expect.1 new file mode 100644 index 0000000..1bfea69 --- /dev/null +++ b/tests/f_baddir2/expect.1 @@ -0,0 +1,12 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Directory inode 12, block 0, offset 60: directory corrupted +Salvage? yes + +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information + +test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** +test_filesys: 15/16 files (0.0% non-contiguous), 23/100 blocks +Exit status is 1 diff --git a/tests/f_baddir2/expect.2 b/tests/f_baddir2/expect.2 new file mode 100644 index 0000000..b85bbab --- /dev/null +++ b/tests/f_baddir2/expect.2 @@ -0,0 +1,7 @@ +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: 15/16 files (0.0% non-contiguous), 23/100 blocks +Exit status is 0 diff --git a/tests/f_baddir2/image.gz b/tests/f_baddir2/image.gz new file mode 100644 index 0000000000000000000000000000000000000000..0d9fcdf7c2e47ccf37dd222505fa25ae4587d98c GIT binary patch literal 587 zcmb2|=HNKBZ;~4mb7pR0dMd-)+xxSH6J^*ReAm;=ntdx`H3wf>n8ww!3o~S8T)34= z1jJRvxRMUa7vEkvnXjoYk1x;9isRrx`-853xUE9O*&P-4O+VebxirwD=j`VL?RR2@ z;@<83Uj5|WhcT^3dK zKBr8sc7j9_&qgnwt>OPY)1@VN-+tS9@7s1WgP?0Aj6JJ9ea@fg`0wA1xQw&u{Ib@! z^UsDm|NL1qe}2}NgTLI&0z=onlly;C|MC0$GcWEf{GO*cf5n~Jzn2TveA)TekUi$>-cy77gv}3Sw45;oF$w0zBQRU_w4Z>J`(=#*W9Zw$g2GM z@NSyjGy4#&%;Kl>q}ksv3R}PWpRKySKEdV3W&SJn3;r>FfJBx(<6Y6PQw$Rr832Kh2wwmI literal 0 HcmV?d00001 diff --git a/tests/f_baddir2/name b/tests/f_baddir2/name new file mode 100644 index 0000000..568a7c9 --- /dev/null +++ b/tests/f_baddir2/name @@ -0,0 +1 @@ +salvage last directory entry -- 1.8.3.1