aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2013-07-28 20:54:36 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-07-28 21:03:00 -0400
commitdd50ef87432284d93b9f39178c4fab242d76654e (patch)
treebf66feb2fcf658a57929c3a1301150531d6aaef4
parent42b61c50e5af99a10fc56975ecd08ab71e4f00e8 (diff)
downloade2fsprogs-dd50ef87432284d93b9f39178c4fab242d76654e.tar.gz
e2fsprogs-dd50ef87432284d93b9f39178c4fab242d76654e.tar.xz
e2fsprogs-dd50ef87432284d93b9f39178c4fab242d76654e.zip
e2fsck: check extent-mapped directories with really large logical blocks
E2fsck was missing a check for directories with logical blocks so large that i_size > 2GB. Without this check the test image found in the new test f_toobig_extent_dir will cause e2fsck to die with a memory allocation failure: Error storing directory block information (inode=12, block=0, num=475218819): Memory allocation failed e2fsck: aborted Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Reported-by: Andrey Melnikov <temnota.am@gmail.com>
-rw-r--r--e2fsck/pass1.c5
-rw-r--r--tests/f_toobig_extent_dir/expect.112
-rw-r--r--tests/f_toobig_extent_dir/expect.27
-rw-r--r--tests/f_toobig_extent_dir/image.gzbin0 -> 822 bytes
-rw-r--r--tests/f_toobig_extent_dir/name1
5 files changed, 25 insertions, 0 deletions
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index af9afe39..8f2f961c 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -1797,12 +1797,17 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
(extent.e_pblk + extent.e_len) >
ext2fs_blocks_count(ctx->fs->super))
problem = PR_1_EXTENT_ENDS_BEYOND;
+ else if (is_leaf && is_dir &&
+ ((extent.e_lblk + extent.e_len) >
+ (1 << (21 - ctx->fs->super->s_log_block_size))))
+ problem = PR_1_TOOBIG_DIR;
if (problem) {
report_problem:
pctx->blk = extent.e_pblk;
pctx->blk2 = extent.e_lblk;
pctx->num = extent.e_len;
+ pctx->blkcount = extent.e_lblk + extent.e_len;
if (fix_problem(ctx, problem, pctx)) {
e2fsck_read_bitmaps(ctx);
pctx->errcode =
diff --git a/tests/f_toobig_extent_dir/expect.1 b/tests/f_toobig_extent_dir/expect.1
new file mode 100644
index 00000000..610ca3f0
--- /dev/null
+++ b/tests/f_toobig_extent_dir/expect.1
@@ -0,0 +1,12 @@
+Pass 1: Checking inodes, blocks, and sizes
+Inode 12 is too big. Truncate? yes
+
+Block #4294967281 (90) causes directory to be too big. CLEARED.
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 12/56 files (0.0% non-contiguous), 28/400 blocks
+Exit status is 1
diff --git a/tests/f_toobig_extent_dir/expect.2 b/tests/f_toobig_extent_dir/expect.2
new file mode 100644
index 00000000..c0256452
--- /dev/null
+++ b/tests/f_toobig_extent_dir/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: 12/56 files (0.0% non-contiguous), 28/400 blocks
+Exit status is 0
diff --git a/tests/f_toobig_extent_dir/image.gz b/tests/f_toobig_extent_dir/image.gz
new file mode 100644
index 00000000..622f65a0
--- /dev/null
+++ b/tests/f_toobig_extent_dir/image.gz
Binary files differ
diff --git a/tests/f_toobig_extent_dir/name b/tests/f_toobig_extent_dir/name
new file mode 100644
index 00000000..d7453ad3
--- /dev/null
+++ b/tests/f_toobig_extent_dir/name
@@ -0,0 +1 @@
+directory with a very large lblk in extent