From: Theodore Ts'o Date: Sat, 22 Jul 2017 20:08:25 +0000 (-0400) Subject: e2fsck: check for invalid quota inode numbers X-Git-Tag: v1.43.5~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d202f46d81c6ca8a0dbce2053cf8114bd68a3ddc;p=thirdparty%2Fe2fsprogs.git e2fsck: check for invalid quota inode numbers If the superblock has invalid inode numbers for the user, group, or project quota inodes, e2fsck should notice and offer to fix things by zeroing out the invalid superblock field. Signed-off-by: Theodore Ts'o --- diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 6ab4f9cca..81c09d7eb 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -505,6 +505,7 @@ extern void set_up_logging(e2fsck_t ctx); /* quota.c */ extern void e2fsck_hide_quota(e2fsck_t ctx); +extern void e2fsck_validate_quota_inodes(e2fsck_t ctx); /* pass1.c */ extern errcode_t e2fsck_setup_icount(e2fsck_t ctx, const char *icount_name, diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 5359d6b84..c4c554295 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -488,6 +488,11 @@ static struct e2fsck_problem problem_table[] = { N_("Bad desired extra isize in @S (%N). "), PROMPT_FIX, 0 }, + /* Invalid quota inode number */ + { PR_0_INVALID_QUOTA_INO, + N_("Invalid %U @q @i %i. "), + PROMPT_FIX, 0 }, + /* Pass 1 errors */ /* Pass 1: Checking inodes, blocks, and sizes */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index d291e26c7..c949547da 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -279,6 +279,9 @@ struct problem_context { /* Bad desired extra isize in superblock */ #define PR_0_BAD_WANT_EXTRA_ISIZE 0x00004E +/* Invalid quota inode number */ +#define PR_0_INVALID_QUOTA_INO 0x00004F + /* * Pass 1 errors diff --git a/e2fsck/quota.c b/e2fsck/quota.c index 173997e0d..b0f9af637 100644 --- a/e2fsck/quota.c +++ b/e2fsck/quota.c @@ -79,8 +79,39 @@ void e2fsck_hide_quota(e2fsck_t ctx) fix_problem(ctx, PR_0_HIDE_QUOTA, &pctx)) { move_quota_inode(fs, pctx.ino, quota_ino, qtype); *quota_sb_inump(sb, qtype) = quota_ino; + ext2fs_mark_super_dirty(fs); } } return; } + +void e2fsck_validate_quota_inodes(e2fsck_t ctx) +{ + struct ext2_super_block *sb = ctx->fs->super; + struct problem_context pctx; + ext2_filsys fs = ctx->fs; + enum quota_type qtype; + ext2_ino_t quota_ino; + + clear_problem_context(&pctx); + + for (qtype = 0; qtype < MAXQUOTAS; qtype++) { + pctx.ino = *quota_sb_inump(sb, qtype); + pctx.num = qtype; + if (pctx.ino && + ((pctx.ino == EXT2_BAD_INO) || + (pctx.ino == EXT2_ROOT_INO) || + (pctx.ino == EXT2_BOOT_LOADER_INO) || + (pctx.ino == EXT2_UNDEL_DIR_INO) || + (pctx.ino == EXT2_RESIZE_INO) || + (pctx.ino == EXT2_JOURNAL_INO) || + (pctx.ino == EXT2_EXCLUDE_INO) || + (pctx.ino == EXT4_REPLICA_INO) || + (pctx.ino > fs->super->s_inodes_count)) && + fix_problem(ctx, PR_0_INVALID_QUOTA_INO, &pctx)) { + *quota_sb_inump(sb, qtype) = 0; + ext2fs_mark_super_dirty(fs); + } + } +} diff --git a/e2fsck/super.c b/e2fsck/super.c index d2fd92253..8153f2bfe 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -910,6 +910,8 @@ void check_super_block(e2fsck_t ctx) } } + e2fsck_validate_quota_inodes(ctx); + /* * Move the ext3 journal file, if necessary. */ diff --git a/tests/f_quota_invalid_inum/expect.1 b/tests/f_quota_invalid_inum/expect.1 new file mode 100644 index 000000000..a989f16c1 --- /dev/null +++ b/tests/f_quota_invalid_inum/expect.1 @@ -0,0 +1,15 @@ +Invalid user quota inode 808464432. Fix? yes + +Invalid group quota inode 808464432. Fix? yes + +Invalid group quota inode 808464432. Fix? yes + +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: ***** FILE SYSTEM WAS MODIFIED ***** +test_filesys: 11/16 files (0.0% non-contiguous), 21/100 blocks +Exit status is 1 diff --git a/tests/f_quota_invalid_inum/expect.2 b/tests/f_quota_invalid_inum/expect.2 new file mode 100644 index 000000000..41ceefb4e --- /dev/null +++ b/tests/f_quota_invalid_inum/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: 11/16 files (0.0% non-contiguous), 21/100 blocks +Exit status is 0 diff --git a/tests/f_quota_invalid_inum/image.gz b/tests/f_quota_invalid_inum/image.gz new file mode 100644 index 000000000..28be80efe Binary files /dev/null and b/tests/f_quota_invalid_inum/image.gz differ diff --git a/tests/f_quota_invalid_inum/name b/tests/f_quota_invalid_inum/name new file mode 100644 index 000000000..a7424060d --- /dev/null +++ b/tests/f_quota_invalid_inum/name @@ -0,0 +1 @@ +invalid quota inode numbers