Compare commits

...

No commits in common. "factory" and "SLE_12_SP4" have entirely different histories.

26 changed files with 2545 additions and 571 deletions

4
.gitattributes vendored
View File

@ -20,6 +20,4 @@
*.whl filter=lfs diff=lfs merge=lfs -text *.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text *.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text *.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text *.zst filter=lfs diff=lfs merge=lfs -text
## Specific LFS patterns
e2fsprogs.keyring filter=lfs diff=lfs merge=lfs -text

2
.lfsconfig Normal file
View File

@ -0,0 +1,2 @@
[lfs]
url = http://gitea.opensuse.org:9999/gitlfs

View File

@ -0,0 +1,55 @@
From 8dd73c149f418238f19791f9d666089ef9734dff Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Thu, 19 Dec 2019 19:37:34 -0500
Subject: [PATCH] e2fsck: abort if there is a corrupted directory block
when rehashing
References: bsc#1160571 CVE-2019-5188
In e2fsck pass 3a, when we are rehashing directories, at least in
theory, all of the directories should have had corruptions with
respect to directory entry structure fixed. However, it's possible
(for example, if the user declined a fix) that we can reach this stage
of processing with a corrupted directory entries.
So check for that case and don't try to process a corrupted directory
block so we don't run into trouble in mutate_name() if there is a
zero-length file name.
Addresses: TALOS-2019-0973
Addresses: CVE-2019-5188
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
---
e2fsck/rehash.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c
index a5fc1be1a210..3dd1e94131c6 100644
--- a/e2fsck/rehash.c
+++ b/e2fsck/rehash.c
@@ -160,6 +160,10 @@ static int fill_dir_block(ext2_filsys fs,
dir_offset += rec_len;
if (dirent->inode == 0)
continue;
+ if ((name_len) == 0) {
+ fd->err = EXT2_ET_DIR_CORRUPTED;
+ return BLOCK_ABORT;
+ }
if (!fd->compress && (name_len == 1) &&
(dirent->name[0] == '.'))
continue;
@@ -401,6 +405,11 @@ static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
continue;
}
new_len = ext2fs_dirent_name_len(ent->dir);
+ if (new_len == 0) {
+ /* should never happen */
+ ext2fs_unmark_valid(fs);
+ continue;
+ }
memcpy(new_name, ent->dir->name, new_len);
mutate_name(new_name, &new_len);
for (j=0; j < fd->num_array; j++) {
--
2.16.4

View File

@ -0,0 +1,565 @@
From 6d0b48896247dc70b16482a8ff4123d570285a2a Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Sun, 5 May 2019 16:43:33 -0400
Subject: [PATCH] e2fsck: check and fix tails of all bitmap blocks
References: bsc#1128383
Currently, e2fsck effectively checks only tail of the last inode and
block bitmap in the filesystem. Thus if some previous bitmap has unset
bits it goes unnoticed. Mostly these tail bits in the bitmap are
ignored; however, if blocks_per_group are smaller than 8*blocksize,
the multi-block allocator in the kernel can get confused when the tail
bits are unset and return bogus free extent.
Add support to libext2fs to check these bitmap tails when loading
bitmaps (as that's about the only place which has access to the bitmap
tail bits) and make e2fsck use this functionality to detect buggy bitmap
tails and fix them (by rewriting the bitmaps).
Reported-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
e2fsck/pass5.c | 40 ++++++++++++++++---
lib/ext2fs/ext2fs.h | 2 +
lib/ext2fs/rw_bitmaps.c | 26 +++++++++++-
tests/f_bitmaps/expect.1 | 2 +
tests/f_dup/expect.1 | 2 +
tests/f_dup2/expect.1 | 2 +
tests/f_dup3/expect.1 | 2 +
tests/f_end-bitmap/expect.1 | 2 +
tests/f_illbbitmap/expect.1 | 2 +
tests/f_illibitmap/expect.1 | 2 +
tests/f_illitable_flexbg/expect.1 | 2 +
tests/f_lpf/expect.1 | 2 +
tests/f_overfsblks/expect.1 | 2 +
tests/f_super_bad_csum/expect.1 | 4 +-
tests/j_corrupt_ext_jnl_sb_csum/expect | 2 +
tests/j_ext_long_trans/expect | 2 +
tests/j_long_trans/expect | 2 +
tests/j_long_trans_mcsum_32bit/expect | 2 +
tests/j_long_trans_mcsum_64bit/expect | 2 +
tests/j_recover_csum2_32bit/expect.1 | 2 +
tests/j_recover_csum2_64bit/expect.1 | 2 +
tests/j_short_trans/expect | 2 +
tests/j_short_trans_64bit/expect | 2 +
tests/j_short_trans_mcsum_64bit/expect | 2 +
tests/j_short_trans_old_csum/expect | 2 +
tests/j_short_trans_open_recover/expect | 2 +
tests/j_short_trans_recover/expect | 2 +
.../j_short_trans_recover_mcsum_64bit/expect | 2 +
tests/t_replay_and_set/expect | 2 +
29 files changed, 113 insertions(+), 9 deletions(-)
Index: e2fsprogs-1.43.8/e2fsck/pass5.c
===================================================================
--- e2fsprogs-1.43.8.orig/e2fsck/pass5.c
+++ e2fsprogs-1.43.8/e2fsck/pass5.c
@@ -840,6 +840,7 @@ static void check_inode_end(e2fsck_t ctx
ext2_filsys fs = ctx->fs;
ext2_ino_t end, save_inodes_count, i;
struct problem_context pctx;
+ int asked = 0;
clear_problem_context(&pctx);
@@ -853,11 +854,12 @@ static void check_inode_end(e2fsck_t ctx
return;
}
if (save_inodes_count == end)
- return;
+ goto check_intra_bg_tail;
/* protect loop from wrap-around if end is maxed */
for (i = save_inodes_count + 1; i <= end && i > save_inodes_count; i++) {
if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
+ asked = 1;
if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
for (; i <= end; i++)
ext2fs_mark_inode_bitmap(fs->inode_map,
@@ -877,6 +879,20 @@ static void check_inode_end(e2fsck_t ctx
ctx->flags |= E2F_FLAG_ABORT; /* fatal */
return;
}
+ /*
+ * If the number of inodes per block group != blocksize, we
+ * can also have a potential problem with the tail bits in
+ * each individual inode bitmap block. If there is a problem,
+ * it would have been noticed when the bitmap was loaded. And
+ * fixing this is easy; all we need to do force the bitmap to
+ * be written back to disk.
+ */
+check_intra_bg_tail:
+ if (!asked && fs->flags & EXT2_FLAG_IBITMAP_TAIL_PROBLEM)
+ if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx))
+ ext2fs_mark_ib_dirty(fs);
+ else
+ ext2fs_unmark_valid(fs);
}
static void check_block_end(e2fsck_t ctx)
@@ -884,6 +900,7 @@ static void check_block_end(e2fsck_t ctx
ext2_filsys fs = ctx->fs;
blk64_t end, save_blocks_count, i;
struct problem_context pctx;
+ int asked = 0;
clear_problem_context(&pctx);
@@ -898,12 +915,13 @@ static void check_block_end(e2fsck_t ctx
return;
}
if (save_blocks_count == end)
- return;
+ goto check_intra_bg_tail;
/* Protect loop from wrap-around if end is maxed */
for (i = save_blocks_count + 1; i <= end && i > save_blocks_count; i++) {
if (!ext2fs_test_block_bitmap2(fs->block_map,
EXT2FS_C2B(fs, i))) {
+ asked = 1;
if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
for (; i <= end; i++)
ext2fs_mark_block_bitmap2(fs->block_map,
@@ -923,7 +941,19 @@ static void check_block_end(e2fsck_t ctx
ctx->flags |= E2F_FLAG_ABORT; /* fatal */
return;
}
+ /*
+ * If the number of blocks per block group != blocksize, we
+ * can also have a potential problem with the tail bits in
+ * each individual block bitmap block. If there is a problem,
+ * it would have been noticed when the bitmap was loaded. And
+ * fixing this is easy; all we need to do force the bitmap to
+ * be written back to disk.
+ */
+check_intra_bg_tail:
+ if (!asked && fs->flags & EXT2_FLAG_BBITMAP_TAIL_PROBLEM) {
+ if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx))
+ ext2fs_mark_bb_dirty(fs);
+ else
+ ext2fs_unmark_valid(fs);
+ }
}
-
-
-
Index: e2fsprogs-1.43.8/lib/ext2fs/ext2fs.h
===================================================================
--- e2fsprogs-1.43.8.orig/lib/ext2fs/ext2fs.h
+++ e2fsprogs-1.43.8/lib/ext2fs/ext2fs.h
@@ -196,6 +196,8 @@ typedef struct ext2_file *ext2_file_t;
#define EXT2_FLAG_DIRECT_IO 0x80000
#define EXT2_FLAG_SKIP_MMP 0x100000
#define EXT2_FLAG_IGNORE_CSUM_ERRORS 0x200000
+#define EXT2_FLAG_BBITMAP_TAIL_PROBLEM 0x1000000
+#define EXT2_FLAG_IBITMAP_TAIL_PROBLEM 0x2000000
/*
* Special flag in the ext2 inode i_flag field that means that this is
Index: e2fsprogs-1.43.8/lib/ext2fs/rw_bitmaps.c
===================================================================
--- e2fsprogs-1.43.8.orig/lib/ext2fs/rw_bitmaps.c
+++ e2fsprogs-1.43.8/lib/ext2fs/rw_bitmaps.c
@@ -195,6 +195,16 @@ static errcode_t mark_uninit_bg_group_bl
return 0;
}
+static int bitmap_tail_verify(unsigned char *bitmap, int first, int last)
+{
+ int i;
+
+ for (i = first; i <= last; i++)
+ if (bitmap[i] != 0xff)
+ return 0;
+ return 1;
+}
+
static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
{
dgrp_t i;
@@ -203,6 +213,7 @@ static errcode_t read_bitmaps(ext2_filsy
errcode_t retval;
int block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8;
int inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8;
+ int tail_flags = 0;
int csum_flag;
unsigned int cnt;
blk64_t blk;
@@ -317,6 +328,9 @@ static errcode_t read_bitmaps(ext2_filsy
EXT2_ET_BLOCK_BITMAP_CSUM_INVALID;
goto cleanup;
}
+ if (!bitmap_tail_verify(block_bitmap,
+ block_nbytes, fs->blocksize - 1))
+ tail_flags |= EXT2_FLAG_BBITMAP_TAIL_PROBLEM;
} else
memset(block_bitmap, 0, block_nbytes);
cnt = block_nbytes << 3;
@@ -349,6 +363,9 @@ static errcode_t read_bitmaps(ext2_filsy
EXT2_ET_INODE_BITMAP_CSUM_INVALID;
goto cleanup;
}
+ if (!bitmap_tail_verify(inode_bitmap,
+ inode_nbytes, fs->blocksize - 1))
+ tail_flags |= EXT2_FLAG_IBITMAP_TAIL_PROBLEM;
} else
memset(inode_bitmap, 0, inode_nbytes);
cnt = inode_nbytes << 3;
@@ -368,10 +385,15 @@ static errcode_t read_bitmaps(ext2_filsy
}
success_cleanup:
- if (inode_bitmap)
+ if (inode_bitmap) {
ext2fs_free_mem(&inode_bitmap);
- if (block_bitmap)
+ fs->flags &= ~EXT2_FLAG_IBITMAP_TAIL_PROBLEM;
+ }
+ if (block_bitmap) {
ext2fs_free_mem(&block_bitmap);
+ fs->flags &= ~EXT2_FLAG_BBITMAP_TAIL_PROBLEM;
+ }
+ fs->flags |= tail_flags;
return 0;
cleanup:
Index: e2fsprogs-1.43.8/tests/f_bitmaps/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/f_bitmaps/expect.1
+++ e2fsprogs-1.43.8/tests/f_bitmaps/expect.1
@@ -11,6 +11,8 @@ Fix? yes
Inode bitmap differences: +11 -15
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/32 files (9.1% non-contiguous), 22/100 blocks
Index: e2fsprogs-1.43.8/tests/f_dup/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/f_dup/expect.1
+++ e2fsprogs-1.43.8/tests/f_dup/expect.1
@@ -30,6 +30,8 @@ Fix? yes
Free blocks count wrong (62, counted=60).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
Padding at end of block bitmap is not set. Fix? yes
Index: e2fsprogs-1.43.8/tests/f_dup2/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/f_dup2/expect.1
+++ e2fsprogs-1.43.8/tests/f_dup2/expect.1
@@ -37,6 +37,8 @@ Fix? yes
Free blocks count wrong (26, counted=22).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
Padding at end of block bitmap is not set. Fix? yes
Index: e2fsprogs-1.43.8/tests/f_dup3/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/f_dup3/expect.1
+++ e2fsprogs-1.43.8/tests/f_dup3/expect.1
@@ -39,6 +39,8 @@ Fix? yes
Free blocks count wrong (20, counted=19).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 16/16 files (25.0% non-contiguous), 81/100 blocks
Index: e2fsprogs-1.43.8/tests/f_end-bitmap/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/f_end-bitmap/expect.1
+++ e2fsprogs-1.43.8/tests/f_end-bitmap/expect.1
@@ -8,6 +8,8 @@ Pass 5: Checking group summary informati
Free blocks count wrong for group #0 (44, counted=63).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
Padding at end of block bitmap is not set. Fix? yes
Index: e2fsprogs-1.43.8/tests/f_illbbitmap/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/f_illbbitmap/expect.1
+++ e2fsprogs-1.43.8/tests/f_illbbitmap/expect.1
@@ -22,6 +22,8 @@ Fix? yes
Inode bitmap differences: -(12--21)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/32 files (0.0% non-contiguous), 22/100 blocks
Index: e2fsprogs-1.43.8/tests/f_illibitmap/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/f_illibitmap/expect.1
+++ e2fsprogs-1.43.8/tests/f_illibitmap/expect.1
@@ -19,6 +19,8 @@ Pass 5: Checking group summary informati
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/32 files (0.0% non-contiguous), 22/100 blocks
Index: e2fsprogs-1.43.8/tests/f_illitable_flexbg/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/f_illitable_flexbg/expect.1
+++ e2fsprogs-1.43.8/tests/f_illitable_flexbg/expect.1
@@ -18,6 +18,8 @@ Pass 5: Checking group summary informati
Inode bitmap differences: -(65--128)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 12/256 files (0.0% non-contiguous), 31163/32768 blocks
Index: e2fsprogs-1.43.8/tests/f_lpf/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/f_lpf/expect.1
+++ e2fsprogs-1.43.8/tests/f_lpf/expect.1
@@ -42,6 +42,8 @@ Fix? yes
Free inodes count wrong (1, counted=0).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 16/16 files (12.5% non-contiguous), 67/100 blocks
Index: e2fsprogs-1.43.8/tests/f_overfsblks/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/f_overfsblks/expect.1
+++ e2fsprogs-1.43.8/tests/f_overfsblks/expect.1
@@ -13,6 +13,8 @@ Pass 5: Checking group summary informati
Inode bitmap differences: -(12--21)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/32 files (0.0% non-contiguous), 22/100 blocks
Index: e2fsprogs-1.43.8/tests/f_super_bad_csum/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/f_super_bad_csum/expect.1
+++ e2fsprogs-1.43.8/tests/f_super_bad_csum/expect.1
@@ -5,8 +5,8 @@ Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-Inode bitmap differences: Group 1 inode bitmap does not match checksum.
-FIXED.
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/1024 files (0.0% non-contiguous), 1557/16384 blocks
Index: e2fsprogs-1.43.8/tests/j_corrupt_ext_jnl_sb_csum/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_corrupt_ext_jnl_sb_csum/expect
+++ e2fsprogs-1.43.8/tests/j_corrupt_ext_jnl_sb_csum/expect
@@ -12,6 +12,8 @@ Fix? yes
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/128 files (0.0% non-contiguous), 66/2048 blocks
Index: e2fsprogs-1.43.8/tests/j_ext_long_trans/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_ext_long_trans/expect
+++ e2fsprogs-1.43.8/tests/j_ext_long_trans/expect
@@ -98,6 +98,8 @@ Fix? yes
Free inodes count wrong (16372, counted=16373).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/16384 files (0.0% non-contiguous), 6228/262144 blocks
Index: e2fsprogs-1.43.8/tests/j_long_trans/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_long_trans/expect
+++ e2fsprogs-1.43.8/tests/j_long_trans/expect
@@ -96,6 +96,8 @@ Fix? yes
Free inodes count wrong (16372, counted=16373).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
Recreate journal? yes
Creating journal (8192 blocks): Done.
Index: e2fsprogs-1.43.8/tests/j_long_trans_mcsum_32bit/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_long_trans_mcsum_32bit/expect
+++ e2fsprogs-1.43.8/tests/j_long_trans_mcsum_32bit/expect
@@ -135,6 +135,8 @@ Fix? yes
Free inodes count wrong (32756, counted=32757).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
Recreate journal? yes
Creating journal (16384 blocks): Done.
Index: e2fsprogs-1.43.8/tests/j_long_trans_mcsum_64bit/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_long_trans_mcsum_64bit/expect
+++ e2fsprogs-1.43.8/tests/j_long_trans_mcsum_64bit/expect
@@ -134,6 +134,8 @@ Fix? yes
Free inodes count wrong (32756, counted=32757).
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
Recreate journal? yes
Creating journal (16384 blocks): Done.
Index: e2fsprogs-1.43.8/tests/j_recover_csum2_32bit/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_recover_csum2_32bit/expect.1
+++ e2fsprogs-1.43.8/tests/j_recover_csum2_32bit/expect.1
@@ -10,6 +10,8 @@ Fix? yes
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/8192 files (0.0% non-contiguous), 7739/131072 blocks
Index: e2fsprogs-1.43.8/tests/j_recover_csum2_64bit/expect.1
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_recover_csum2_64bit/expect.1
+++ e2fsprogs-1.43.8/tests/j_recover_csum2_64bit/expect.1
@@ -10,6 +10,8 @@ Fix? yes
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/8192 files (0.0% non-contiguous), 7739/131072 blocks
Index: e2fsprogs-1.43.8/tests/j_short_trans/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_short_trans/expect
+++ e2fsprogs-1.43.8/tests/j_short_trans/expect
@@ -32,6 +32,8 @@ Fix? yes
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
Index: e2fsprogs-1.43.8/tests/j_short_trans_64bit/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_short_trans_64bit/expect
+++ e2fsprogs-1.43.8/tests/j_short_trans_64bit/expect
@@ -34,6 +34,8 @@ Fix? yes
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/16384 files (0.0% non-contiguous), 5196/65536 blocks
Index: e2fsprogs-1.43.8/tests/j_short_trans_mcsum_64bit/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_short_trans_mcsum_64bit/expect
+++ e2fsprogs-1.43.8/tests/j_short_trans_mcsum_64bit/expect
@@ -34,6 +34,8 @@ Fix? yes
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/32768 files (0.0% non-contiguous), 6353/131072 blocks
Index: e2fsprogs-1.43.8/tests/j_short_trans_old_csum/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_short_trans_old_csum/expect
+++ e2fsprogs-1.43.8/tests/j_short_trans_old_csum/expect
@@ -34,6 +34,8 @@ Fix? yes
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
Index: e2fsprogs-1.43.8/tests/j_short_trans_open_recover/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_short_trans_open_recover/expect
+++ e2fsprogs-1.43.8/tests/j_short_trans_open_recover/expect
@@ -37,6 +37,8 @@ Fix? yes
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
Index: e2fsprogs-1.43.8/tests/j_short_trans_recover/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_short_trans_recover/expect
+++ e2fsprogs-1.43.8/tests/j_short_trans_recover/expect
@@ -34,6 +34,8 @@ Fix? yes
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
Index: e2fsprogs-1.43.8/tests/j_short_trans_recover_mcsum_64bit/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/j_short_trans_recover_mcsum_64bit/expect
+++ e2fsprogs-1.43.8/tests/j_short_trans_recover_mcsum_64bit/expect
@@ -36,6 +36,8 @@ Fix? yes
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/32768 files (0.0% non-contiguous), 6353/131072 blocks
Index: e2fsprogs-1.43.8/tests/t_replay_and_set/expect
===================================================================
--- e2fsprogs-1.43.8.orig/tests/t_replay_and_set/expect
+++ e2fsprogs-1.43.8/tests/t_replay_and_set/expect
@@ -30,6 +30,8 @@ Fix? yes
Inode bitmap differences: +(1--11)
Fix? yes
+Padding at end of inode bitmap is not set. Fix? yes
+
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks

View File

@ -0,0 +1,96 @@
From 125850eb92f042c76b6f001bf63833ffc15e7916 Mon Sep 17 00:00:00 2001
From: Jan Kara <jack@suse.cz>
Date: Thu, 13 Feb 2020 11:15:56 +0100
Subject: [PATCH] e2fsck: clarify overflow link count error message
References: bsc#1160979
When directory link count is set to overflow value (1) but during pass 4
we find out the exact link count would fit, we either silently fix this
(which is not great because e2fsck then reports the fs was modified but
output doesn't indicate why in any way), or we report that link count is
wrong and ask whether we should fix it (in case -n option was
specified). The second case is even more misleading because it suggests
non-trivial fs corruption which then gets silently fixed on the next
run. Similarly to how we fix up other non-problems, just create a new
error message for the case directory link count is not overflown anymore
and always report it to clarify what is going on.
Reviewed-by: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
(cherry picked from commit 4ebce13292f54c96f43dcb1bd1d5b8df5dc8749d)
Acked-by: Jan Kara <jack@suse.cz>
---
e2fsck/pass4.c | 20 ++++++++++++++++----
e2fsck/problem.c | 5 +++++
e2fsck/problem.h | 3 +++
3 files changed, 24 insertions(+), 4 deletions(-)
Index: e2fsprogs-1.43.8/e2fsck/pass4.c
===================================================================
--- e2fsprogs-1.43.8.orig/e2fsck/pass4.c
+++ e2fsprogs-1.43.8/e2fsck/pass4.c
@@ -169,6 +169,8 @@ void e2fsck_pass4(e2fsck_t ctx)
if (isdir && (link_counted > EXT2_LINK_MAX))
link_counted = 1;
if (link_counted != link_count) {
+ int fix_nlink = 0;
+
e2fsck_read_inode_full(ctx, i, EXT2_INODE(inode),
inode_size, "pass4");
pctx.ino = i;
@@ -182,10 +184,20 @@ void e2fsck_pass4(e2fsck_t ctx)
pctx.num = link_counted;
/* i_link_count was previously exceeded, but no longer
* is, fix this but don't consider it an error */
- if ((isdir && link_counted > 1 &&
- (inode->i_flags & EXT2_INDEX_FL) &&
- link_count == 1 && !(ctx->options & E2F_OPT_NO)) ||
- fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
+ if (isdir && link_counted > 1 &&
+ (inode->i_flags & EXT2_INDEX_FL) &&
+ link_count == 1) {
+ if ((ctx->options & E2F_OPT_READONLY) == 0) {
+ fix_nlink =
+ fix_problem(ctx,
+ PR_4_DIR_OVERFLOW_REF_COUNT,
+ &pctx);
+ }
+ } else {
+ fix_nlink = fix_problem(ctx, PR_4_BAD_REF_COUNT,
+ &pctx);
+ }
+ if (fix_nlink) {
inode->i_links_count = link_counted;
e2fsck_write_inode_full(ctx, i,
EXT2_INODE(inode),
Index: e2fsprogs-1.43.8/e2fsck/problem.c
===================================================================
--- e2fsprogs-1.43.8.orig/e2fsck/problem.c
+++ e2fsprogs-1.43.8/e2fsck/problem.c
@@ -1857,6 +1857,11 @@ static struct e2fsck_problem problem_tab
"They @s the same!\n"),
PROMPT_NONE, 0 },
+ /* Directory inode ref count set to overflow but could be exact value */
+ { PR_4_DIR_OVERFLOW_REF_COUNT,
+ N_("@d @i %i ref count set to overflow but could be exact value %N. "),
+ PROMPT_FIX, PR_PREEN_OK, 0, 0, 0 },
+
/* Pass 5 errors */
/* Pass 5: Checking group summary information */
Index: e2fsprogs-1.43.8/e2fsck/problem.h
===================================================================
--- e2fsprogs-1.43.8.orig/e2fsck/problem.h
+++ e2fsprogs-1.43.8/e2fsck/problem.h
@@ -1123,6 +1123,9 @@ struct problem_context {
/* Inconsistent inode count information cached */
#define PR_4_INCONSISTENT_COUNT 0x040004
+/* Directory ref count set to overflow but it doesn't have to be */
+#define PR_4_DIR_OVERFLOW_REF_COUNT 0x040007
+
/*
* Pass 5 errors
*/

View File

@ -0,0 +1,48 @@
From 71ba13755337e19c9a826dfc874562a36e1b24d3 Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Thu, 19 Dec 2019 19:45:06 -0500
Subject: [PATCH] e2fsck: don't try to rehash a deleted directory
References: bsc#1160571 CVE-2019-5188
If directory has been deleted in pass1[bcd] processing, then we
shouldn't try to rehash the directory in pass 3a when we try to
rehash/reoptimize directories.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
---
e2fsck/pass1b.c | 4 ++++
e2fsck/rehash.c | 2 ++
2 files changed, 6 insertions(+)
diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c
index 5693b9cfcc5a..bca701cab94f 100644
--- a/e2fsck/pass1b.c
+++ b/e2fsck/pass1b.c
@@ -705,6 +705,10 @@ static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
if (ctx->inode_bad_map)
ext2fs_unmark_inode_bitmap2(ctx->inode_bad_map, ino);
+ if (ctx->inode_reg_map)
+ ext2fs_unmark_inode_bitmap2(ctx->inode_reg_map, ino);
+ ext2fs_unmark_inode_bitmap2(ctx->inode_dir_map, ino);
+ ext2fs_unmark_inode_bitmap2(ctx->inode_used_map, ino);
ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(dp->inode.i_mode));
quota_data_sub(ctx->qctx, &dp->inode, ino,
pb.dup_blocks * fs->blocksize);
diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c
index 3dd1e94131c6..2c908be04d70 100644
--- a/e2fsck/rehash.c
+++ b/e2fsck/rehash.c
@@ -1028,6 +1028,8 @@ void e2fsck_rehash_directories(e2fsck_t ctx)
if (!ext2fs_u32_list_iterate(iter, &ino))
break;
}
+ if (!ext2fs_test_inode_bitmap2(ctx->inode_dir_map, ino))
+ continue;
pctx.dir = ino;
if (first) {
--
2.16.4

3
e2fsprogs-1.43.8.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6f831e372afeabc188d3e87dba9d8ff48f9f24cf3c5e354dcfa525ae9381dc27
size 7474876

Binary file not shown.

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2f16c9176704cf645dc69d5b15ff704ae722d665df38b2ed3cfc249757d8d81e
size 7040672

View File

@ -1,366 +1,68 @@
------------------------------------------------------------------- -------------------------------------------------------------------
Tue Sep 13 13:47:21 UTC 2022 - Christian Goll <cgoll@suse.com> Fri Apr 29 15:54:25 UTC 2022 - Jan Kara <jack@suse.cz>
- enabled fuse2fs build which enable to mount ext2/3/4 via FUSE - libext2fs-add-sanity-check-to-extent-manipulation.patch: libext2fs: add
sanity check to extent manipulation (bsc#1198446 CVE-2022-1304)
------------------------------------------------------------------- -------------------------------------------------------------------
Tue Apr 19 20:51:15 UTC 2022 - Dirk Müller <dmueller@suse.com> Mon Mar 30 09:57:19 UTC 2020 - Jan Kara <jack@suse.cz>
- avoid empty preuninstall script - e2fsck-clarify-overflow-link-count-error-message.patch: e2fsck: clarify
overflow link count error message (bsc#1160979)
- ext2fs-update-allocation-info-earlier-in-ext2fs_mkdi.patch: ext2fs: update
allocation info earlier in ext2fs_mkdir() (bsc#1160979)
- ext2fs-implement-dir-entry-creation-in-htree-directo.patch: ext2fs: implement
dir entry creation in htree directories (bsc#1160979)
- tests-add-test-to-excercise-indexed-directories-with.patch: tests: add test
to excercise indexed directories with metadata_csum (bsc#1160979)
- tune2fs-update-dir-checksums-when-clearing-dir_index.patch: tune2fs: update
dir checksums when clearing dir_index feature (bsc#1160979)
------------------------------------------------------------------- -------------------------------------------------------------------
Fri Jan 28 15:40:35 UTC 2022 - Jan Kara <jack@suse.cz> Thu Jan 9 14:50:45 UTC 2020 - Jan Kara <jack@suse.cz>
- Update to 1.46.5:
* better handling for resizing to fs sizes which would exceed inode limits
* fix crash in e2fsck fastcommit handling
* fix possibly lost quota limits when e2fsck corrects quota files
* fix tune2fs to properly transfer quota limits when convertion quota files
* add support for handling of version 0 quota files in tune2fs
* teach libss to use libreadline.so.8
* optimize resize2fs cpu usage for large filesystems
* teach libuuid to use getrandom() or getentropy() if available
- libss-add-newer-libreadline.so.8-to-dlopen-path.patch: Remove, merged upstream
- quota-Add-support-to-version-0-quota-format.patch: Remove, merged upstream
- quota-Fold-quota_read_all_dquots-into-quota_update_l.patch: Remove, merged upstream
- quota-Rename-quota_update_limits-to-quota_read_all_d.patch: Remove, merged upstream
- tune2fs-Fix-conversion-of-quota-files.patch: Remove, merged upstream
- e2fsck-Do-not-trash-user-limits-when-processing-orph.patch: Remove, merged upstream
- debugfs-Fix-headers-for-quota-commands.patch: Remove, merged upstream
- quota-Drop-dead-code.patch: Remove, merged upstream
- e2fsck-abort-if-there-is-a-corrupted-directory-block.patch: e2fsck: abort if
there is a corrupted directory block when rehashing (bsc#1160571
CVE-2019-5188)
- e2fsck-don-t-try-to-rehash-a-deleted-directory.patch: 2fsck: don't try to
rehash a deleted directory (bsc#1160571 CVE-2019-5188)
------------------------------------------------------------------- -------------------------------------------------------------------
Fri Oct 15 12:11:41 UTC 2021 - Johannes Segitz <jsegitz@suse.com> Mon Sep 30 15:09:04 UTC 2019 - Jan Kara <jack@suse.cz>
- Drop ProtectClock hardening, can cause issues if other device acceess is needed - libsupport-add-checks-to-prevent-buffer-overrun-bugs.patch: add checks to
prevent buffer overrun bugs in quota code (bsc#1152101, CVE-2019-5094)
------------------------------------------------------------------- -------------------------------------------------------------------
Thu Sep 30 14:13:06 UTC 2021 - Jan Kara <jack@suse.cz> Wed Aug 28 15:57:05 UTC 2019 - Jan Kara <jack@suse.cz>
- quota-Add-support-to-version-0-quota-format.patch: quota: Add support to - libext2fs-call-fsync-2-to-clear-stale-errors-for-a-n.patch: libext2fs: call
version 0 quota format (jsc#SLE-17360) fsync(2) to clear stale errors for a new a unix I/O channel (bsc#1145716)
quota-Fold-quota_read_all_dquots-into-quota_update_l.patch: quota: Fold
quota_read_all_dquots() into quota_update_limits() (jsc#SLE-17360)
quota-Rename-quota_update_limits-to-quota_read_all_d.patch: quota: Rename
quota_update_limits() to quota_read_all_dquots() (jsc#SLE-17360)
tune2fs-Fix-conversion-of-quota-files.patch: tune2fs: Fix conversion of quota
files (jsc#SLE-17360)
e2fsck-Do-not-trash-user-limits-when-processing-orph.patch: e2fsck: Do not
trash user limits when processing orphan list (jsc#SLE-17360)
debugfs-Fix-headers-for-quota-commands.patch: debugfs: Fix headers for quota
commands (jsc#SLE-17360)
quota-Drop-dead-code.patch: quota: Drop dead code (jsc#SLE-17360)
- add these not yet released fixes to e2fsprogs package so that SLE15-SP4 ships
with them
------------------------------------------------------------------- -------------------------------------------------------------------
Wed Sep 15 09:16:54 UTC 2021 - Jan Kara <jack@suse.cz> Thu May 16 15:24:05 UTC 2019 - Jan Kara <jack@suse.cz>
- Update to 1.46.4: - e2fsck-check-and-fix-tails-of-all-bitmaps.patch: e2fsck: check and fix tails
* Default to 256-byte inodes for all filesystems, not only larger ones of all bitmap blocks (bsc#1128383)
* Bigalloc is considered supported now for small cluster sizes
* E2fsck and e2image fixes for quota feature
* Fix mke2fs creation of filesystem into non-existent file
- libss-add-newer-libreadline.so.8-to-dlopen-path.patch: libss: add newer
libreadline.so.8 to dlopen path (bsc#1189453)
------------------------------------------------------------------- -------------------------------------------------------------------
Tue Sep 14 07:03:07 UTC 2021 - Johannes Segitz <jsegitz@suse.com> Fri Jun 1 16:31:22 UTC 2018 - jack@suse.cz
- Added hardening to systemd service(s) (bsc#1181400). Added patch(es): - libext2fs-Fix-fsync-2-detection.patch: libext2fs: Fix fsync(2) detection
* harden_e2scrub@.service.patch (bsc#1038194)
* harden_e2scrub_all.service.patch
* harden_e2scrub_fail@.service.patch
* harden_e2scrub_reap.service.patch
------------------------------------------------------------------- -------------------------------------------------------------------
Mon Aug 2 20:47:09 UTC 2021 - Jan Kara <jack@suse.cz> Fri Jun 1 15:57:14 UTC 2018 - jack@suse.cz
- Update to 1.46.3: - Add references from old package:
* Add -V and -VV options to filefrag Fix resize2fs-Fix-32-64-bit-overflow-when-multiplying-by-blocks-cl.patch
* Fix fs corruption cause by resize2fs on filesystems with MMP blocks in 1.42.12 (bsc#1009532)
* Fast commit portability fixes Fix libext2fs-fix-potential-buffer-overflow-in-closefs.patch
* Fix direct IO support in Unix IO manager in 1.42.13 (bsc#918346 CVE-2015-1572)
* Avoid calling EXT2_IOC_[GS]ETFLAGS for block devices Fix libext2fs-avoid-buffer-overflow-if-s_first_meta_bg-i.patch
* Fix mke2fs to not discard blocks beyond end of filesystem in 1.42.12 (bsc#915402 CVE-2015-0247)
* Make e2fsck set filetype of '.' and '..' entries Got specfile fix through Factory (bsc#960273)
* Fix QCOW image generation in e2image for very large filesystems Fix libext2fs-don-t-ignore-fsync-errors.patch in 1.43.4 (bsc#1038194)
* Update translations
-------------------------------------------------------------------
Wed Jun 2 08:31:22 UTC 2021 - Christophe Giboudeaux <christophe@krop.fr>
- Fix the %doc files. RELEASE-NOTES is a symlink to
doc/RelNotes/v%version.
-------------------------------------------------------------------
Sun Mar 14 15:25:20 UTC 2021 - Andreas Stieger <andreas.stieger@gmx.de>
- e2fsprogs 1.46.2:
* tune2fs -c now takes "random" argument
* Add support for the FS_NOCOMP_FL flag to chattr and lsattr
* Fix warnings when resizing small file systems to a super-large
* Fix the debugfs rdump and ls commands so they will work correctly
for uid's and gid's => 65536
* Fix the debugfs write and symlink commands so they support
targets which contain a pathname
* Fix Direct I/O support on block devices where the logical block
size is greater 1k
* Fix debugfs's logdump so it works on file systems whose block
size is greater than 8k
* Fix a crash when there is error while e2fsck is trying to open
the file system, and e2fsck calls ext2fs_mmp_stop() before MMP
has been initialized
* Improved error checking in the fast commit replay code in e2fsck
* Fix various compiler and Coverity warnings
* Update the Spanish translation from the translation project
-------------------------------------------------------------------
Thu Feb 18 14:44:00 UTC 2021 - Jan Kara <jack@suse.cz>
- Remove autoreconf (and resulting dependencies) from the spec file. The
upstream configure script should be fine.
-------------------------------------------------------------------
Tue Feb 16 17:31:25 UTC 2021 - Jan Kara <jack@suse.cz>
- Update to 1.46.1:
* Fix setting extended attributes in libext2fs and debugfs
* Fix e2fsck to accept large_dir directories greater than 4G
* Fix fast commit support on big endian architectures
* Fix mke2fs -d to correctly import a small file stored using inline_data
feature and which has ACL or extended attribute
* Various compilation fixes
* Speedup bitmap loading for large filesystems using multiple threads
* Speedup mke2fs for bigalloc filesystems
* E2fsck fixes when rehashing directories
* Fix e2fsck crashes on maliciously corrupted filesystems
* Fix e2fsck handling of duplicated case-folded file names
* Implement hashed directory support in libext2fs
* Support for fast commit feature
* Support for combination of casefolding and encryption
* Support for stable inodes feature
* Add support for per-inode DAX flag
* Fix tune2fs to unlock MMP on failure
* Fix e2fsck buffer overflow when scanning directory blocks
* Fix resize2fs overflowing block group descriptors with 1k block size
- delete e2fsprogs-1.45.2-gettext.patch - it was merged upstream
- Add autoconf-archive to build requirements
- Fix installation of info files for older distros
-------------------------------------------------------------------
Thu Jan 28 15:02:08 UTC 2021 - Thorsten Kukuk <kukuk@suse.com>
- Fix usage of info macros on openSUSE, we use file triggers today
- Use file requires for post section
-------------------------------------------------------------------
Thu Oct 29 10:31:32 UTC 2020 - Ludwig Nussel <lnussel@suse.de>
- prepare usrmerge (boo#1029961)
-------------------------------------------------------------------
Sat May 2 09:44:11 UTC 2020 - Andreas Stieger <andreas.stieger@gmx.de>
- Update to 1.45.6:
* Debugfs will ignore lines in its command files which start with
a comment character ("#")
* Fix a number of potential out of bounds memory accesses caused
by fuzzed / malicious file systems
* Fix a spurious complaint from e2fsck when a directory which
previously had more than 32000 subdirectories has the number
of subdirectories drops below 32000
* Fix an ismounted check when an LVM device is renamed while the
device is mounted
* Mke2fs -d now correctly sets permission with files where the
owner permissions are not rwx
* Improve e2fsck's ability to deal with file systems with very
large number of directories, such that various data structures
take more than 2GiB of memory. Use better structure packing to
improve the memory efficiency of these data structures.
* Fix debugfs so it correctly prints inode numbers > 2**31.
* Filefrag now supports very large files (with > 4 billion
blocks), as well as block sizes up to 1 GiB.
* Update and clarify various man pages
* Reserved the error code EXT2_ET_NO_GDESC (which will be used
in e2fsprogs v1.46+)
* Add a thread-safe variant of e2p_feature2string(),
e2p_feature_to_string() to the libe2p library.
* Fixed portability problems caused by gcc 10.
* Synchroniz changes from Android's AOSP e2fsprogs tree
* Update the Malay translation from the translation project
- add upstream signing key and verify source signature
-------------------------------------------------------------------
Thu Jan 9 13:48:12 UTC 2020 - Jan Kara <jack@suse.cz>
- Update to 1.45.5:
* Fix out of bounds write when checking maliciously corrupted filesystem
* Remove unnecessary sleep in e2scrub
* Fix spurious emails from e2scrub_all
* Fix crash in e2fsck when rebuilding very large directories
* Improve resize2fs minimum fs size estimates when the fs is mounted
* Fix UBSAN failures when fuzzing filesystem images
* Fix potential memory leak in read_bitmap() in libext2fs
* Speedup e2fsck on file systems with a very large number of inodes
* fuse2fs fixes
-------------------------------------------------------------------
Mon Sep 30 16:34:37 UTC 2019 - Jan Kara <jack@suse.cz>
- Update to 1.45.4:
* A maliciously corrupted file systems can trigger buffer overruns in the
quota code used by e2fsck. (Addresses CVE-2019-5094)
* E2fsck now checks to make sure the casefold flag is only set on
directories, and only when the casefold feature is enabled
* E2fsck will not disable the low dtime checks when using a backup superblock
where the last mount time is zero
* Scrubbing scripts fixes
* Update translations
-------------------------------------------------------------------
Fri Aug 9 09:09:39 UTC 2019 - Jan Kara <jack@suse.cz>
- Update to 1.45.3:
* Whether or not automatic online scrubbing will be called is now controlled
in /etc/e2scrub.conf.
* Fix e2fsck handling of filesystems with large_dir and inline directories
* Fix e2scrub_all for encrypted LUKS partitions
* Fix e2scrub_all volume cleanup
* Regression tests cleanups and improvements
* Fixed compiler warnings
* Translation fixes and updates (boo#1170964)
-------------------------------------------------------------------
Wed Jul 24 20:47:22 UTC 2019 - Antoine Belvire <antoine.belvire@opensuse.org>
- Fix build with gettext 0.20:
* Add e2fsprogs-1.45.2-gettext.patch.
* Exclude in-sources intl/ directory from build.
- Fix install_info_delete usage: It must be called in preun.
-------------------------------------------------------------------
Tue Jul 2 07:28:56 UTC 2019 - Martin Liška <mliska@suse.cz>
- Use FAT LTO objects in order to provide proper static library.
-------------------------------------------------------------------
Fri May 31 10:42:41 UTC 2019 - Jan Kara <jack@suse.cz>
- Package e2scrub unit files and separate scrubbing bits into a separate
subpackage e2fsprogs-scrub
-------------------------------------------------------------------
Fri May 31 03:50:23 UTC 2019 - seanlew@opensuse.org
- Update to 1.45.2
* Fixed e2scrub_all issues running from cron
* When mke2fs asks to proceed, fall back on English Y/y
* Fix spurious complaint of blocks beyond i_size
* Fixed 'make install' failure when the cron.d dir doesn't exist
-------------------------------------------------------------------
Wed May 15 14:49:56 UTC 2019 - Jan Kara <jack@suse.cz>
- Remove unused configure-Fix-autoheader-failure.patch.
-------------------------------------------------------------------
Wed May 15 13:48:31 UTC 2019 - seanlew@opensuse.org
- Update to 1.45.1
* Remove configure-Fix-autoheader-failure.patch (fixed upstream)
* Debugfs now supports non-printable chars
* E2fsck now checks to make sure all unused bits in block are set
* E2fsck now supports writing out a problem code log
* Fixed various casefold bugs
* Fix mke2fs support for < 900TB disks
* E2scrub will take its snapshots with UDISK_IGNORE
* Dropped utf8/nls symbols from libext2fs shared library
-------------------------------------------------------------------
Fri Mar 29 16:56:07 UTC 2019 - Jan Kara <jack@suse.cz>
- configure-Fix-autoheader-failure.patch: Fix autoheader failure
-------------------------------------------------------------------
Fri Mar 29 15:01:02 UTC 2019 - Jan Kara <jack@suse.cz>
- Update to 1.45.0
* Add support to force check at the next fsck run to tune2fs
* Add e2scrub script to run e2fsck on LVM backed filesystem
* Mke2fs will attempt to use ZERO_RANGE before PUNCH_HOLE so that we don't
lose allocated blocks in preallocated files
* Initial support for setting character set encoding
* Add support for setting inode checksum to debugfs
* Add support for specifying superblock location to e2image
* Fix e4defrag to handle situation when files are created while it is running
* Fix e2fsck to handle dirs > 2 GiB when largedir feature is enabled
* Fix mke2fs huge file creation
* Fix libext2fs to be more robust against invalid group descriptors
* Fix mke2fs and debugfs to correctly copy files > 2 GiB
* Fix memory leaks in debugfs, mke2fs, and e2freefrag
-------------------------------------------------------------------
Tue Jan 8 09:34:17 UTC 2019 - jack@suse.cz
- Update to 1.44.5
* use 64-bit counters to track number of defragged files
* correctly traslate Posix ACLs
* Use the online free block counts
* Fix a false warning that tune2fs will take along time to change UUID
* e2fsck will only offer to set the inline_data feature flag sometimes
* e4defrag running as root but can't find file system
* resize2fs was failing to update extent tree checksums
* fuse2fs command line parsing fixed
* e2fs segfault fix when corrupted journal file-system is too large
* e2image now includes the mmp block
* fix various verity handling bugs which made it unusable
* fix a bug in tune2fs to dereference freed memory after replay
-------------------------------------------------------------------
Tue Sep 11 15:34:00 UTC 2018 - jack@suse.cz
- Update to 1.44.4
* fix debugs ncheck command to work for files with multiple hardlinks
* avoid floating point exception when libblkid probes maliciously corrupted
superblocks
* fix e2fsck to handle filesystems with resize_inode and meta_bg enabled
* basic fsverify support
* debugfs can operate on corrupted filesystems so they can be fixed
* new debugfs commands for dumping xattr blocks and i_blocks array
* dumpe2fs can print MMP block
* inode's project ID properly byte-swapped on big-endian filesystems
* e2fsck can handle s_inodes_count corruption
* other e2fsck improvements and fixes
* mke2fs fixes where in various corner cases invalid filesystem would be
created
- add new e2mmpstatus alias for dumpe2fs to spec file
-------------------------------------------------------------------
Wed May 23 15:00:07 UTC 2018 - jack@suse.cz
- Update to 1.44.2
* support for directories over 2 GB (large_dir feature)
* support for large extended attributes (ea_inode feature)
* metadata checksumming is enabled by default by mke2fs
* resize2fs deemed stable enough for bigalloc file systems
* tune2fs now replays the journal before modifying the file system
* improved consistency checks for symlinks
* various fixes in e2image, dumpe2fs, debugfs, and e2fsck for bigalloc
file systems
* fix e2image handling of images on big endian systems
* fixed e2fsck to properly update quotas when handling orphan inodes
-------------------------------------------------------------------
Tue Mar 6 10:32:58 UTC 2018 - jack@suse.cz
- libext2fs-fix-build-failure-in-swapfs.c-on-big-endia.patch: Removed as it is
included in the new release
- switched to .xz archive as kernel.org is going to deprecate gzip archives
- Update to 1.43.9
* fix build failure on big endian systems
* inode flag cleanup in libe2p
------------------------------------------------------------------- -------------------------------------------------------------------
Wed Jan 24 14:41:11 UTC 2018 - jack@suse.cz Wed Jan 24 14:41:11 UTC 2018 - jack@suse.cz

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b833a31ef08dd4ac5e19894f031af612622e02560ec5165bd5f687f1487cbe01
size 465237

View File

@ -23,28 +23,22 @@ Name: e2fsprogs
# Hint for ZYPP # Hint for ZYPP
Supplements: filesystem(ext2) filesystem(ext3) filesystem(ext4) Supplements: filesystem(ext2) filesystem(ext3) filesystem(ext4)
%endif %endif
%if 0%{?suse_version} >= 1210 BuildRequires: autoconf
%bcond_without systemd BuildRequires: automake
%else
%bcond_with systemd
%endif
BuildRequires: fuse-devel
BuildRequires: libblkid-devel BuildRequires: libblkid-devel
BuildRequires: libuuid-devel BuildRequires: libuuid-devel
BuildRequires: pkg-config BuildRequires: pkg-config
BuildRequires: xz
%if ! %{build_mini} %if ! %{build_mini}
%if 0%{?suse_version} > 1220 %if 0%{?suse_version} > 1220
BuildRequires: makeinfo BuildRequires: makeinfo
%endif %endif
# Define info macros if missing (for Fedora builds) # Define info macros if missing (for Fedora builds)
%if ! 0%{?suse_version} %if 0%{!?%install_info_prereq:1}
%define install_info_prereq info %define install_info_prereq info
%define install_info sbin/install-info %define install_info sbin/install-info
%define install_info_delete sbin/install-info --delete %define install_info_delete sbin/install-info --delete
Requires(post): %install_info_prereq
Requires(preun):%install_info_prereq
%endif %endif
Requires: %install_info_prereq
%endif %endif
# bug437293 # bug437293
%ifarch ppc64 %ifarch ppc64
@ -67,33 +61,38 @@ Conflicts: libext2fs-mini-devel
Conflicts: libext2fs2-mini Conflicts: libext2fs2-mini
%endif %endif
# #
Version: 1.46.5 Version: 1.43.8
Release: 0 Release: 0
Summary: Utilities for the Second Extended File System Summary: Utilities for the Second Extended File System
License: GPL-2.0-only License: GPL-2.0-only
Group: System/Filesystems Group: System/Filesystems
URL: http://e2fsprogs.sourceforge.net URL: http://e2fsprogs.sourceforge.net
# For regenerate_initrd_post macro Requires(post): coreutils
Requires(post): /usr/bin/mkdir /usr/bin/touch
Requires: libcom_err2 >= %{version} Requires: libcom_err2 >= %{version}
Requires: libext2fs2 >= %{version} Requires: libext2fs2 >= %{version}
Suggests: e2fsprogs-scrub Source: http://www.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/v%{version}/e2fsprogs-%{version}.tar.gz
Source: http://www.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/v%{version}/e2fsprogs-%{version}.tar.xz
Source2: README.SUSE Source2: README.SUSE
Source3: baselibs.conf Source3: baselibs.conf
Source4: http://www.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/v%{version}/e2fsprogs-%{version}.tar.sign
Source5: https://thunk.org/tytso/tytso-key.asc#/%{name}.keyring
# #
# e2fsprogs patches # e2fsprogs patches
# #
Patch1: libext2fs-fix-build-failure-in-swapfs.c-on-big-endia.patch
# libcom_err patches # libcom_err patches
Patch3: libcom_err-compile_et_permissions.patch Patch3: libcom_err-compile_et_permissions.patch
Patch4: e2fsprogs-1.42-implicit_fortify_decl.patch Patch4: e2fsprogs-1.42-implicit_fortify_decl.patch
Patch5: e2fsprogs-1.42-ext2fsh_implicit.patch Patch5: e2fsprogs-1.42-ext2fsh_implicit.patch
Patch6: harden_e2scrub@.service.patch Patch6: libext2fs-Fix-fsync-2-detection.patch
Patch7: harden_e2scrub_all.service.patch Patch7: e2fsck-check-and-fix-tails-of-all-bitmaps.patch
Patch8: harden_e2scrub_fail@.service.patch Patch8: libext2fs-call-fsync-2-to-clear-stale-errors-for-a-n.patch
Patch9: harden_e2scrub_reap.service.patch Patch9: libsupport-add-checks-to-prevent-buffer-overrun-bugs.patch
Patch10: e2fsck-abort-if-there-is-a-corrupted-directory-block.patch
Patch11: e2fsck-don-t-try-to-rehash-a-deleted-directory.patch
Patch12: e2fsck-clarify-overflow-link-count-error-message.patch
Patch13: ext2fs-update-allocation-info-earlier-in-ext2fs_mkdi.patch
Patch14: ext2fs-implement-dir-entry-creation-in-htree-directo.patch
Patch15: tests-add-test-to-excercise-indexed-directories-with.patch
Patch16: tune2fs-update-dir-checksums-when-clearing-dir_index.patch
Patch17: libext2fs-add-sanity-check-to-extent-manipulation.patch
# Do not suppress make commands # Do not suppress make commands
BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRoot: %{_tmppath}/%{name}-%{version}-build
@ -118,28 +117,6 @@ Requires: libuuid-devel
%description devel %description devel
Dummy development package for backwards compatibility. Dummy development package for backwards compatibility.
%if %{build_mini}
%package -n e2fsprogs-scrub-mini
%else
%package -n e2fsprogs-scrub
%endif
Summary: Ext2fs scrubbing scripts and service files
License: GPL-2.0-only
Group: System/Filesystems
%if %{with systemd}
BuildRequires: systemd-rpm-macros
%{?systemd_requires}
%endif
Requires: e2fsprogs
Requires: lvm2
Requires: postfix
Requires: util-linux
%description -n e2fsprogs-scrub
Scripts and systemd service files for background scrubbing of LVM volumes
with ext2, ext3, and ext4 filesystems.
%if %{build_mini} %if %{build_mini}
%package -n libext2fs2-mini %package -n libext2fs2-mini
%else %else
@ -260,38 +237,39 @@ Obsoletes: libcom_err-devel-64bit
Development files for the com_err error message display library. Static libraries. Development files for the com_err error message display library. Static libraries.
%endif %endif
%package -n fuse2fs
Summary: FUSE file system client for ext2/ext3/ext4 file systems
License: MIT
%description -n fuse2fs
fuse2fs is a FUSE file system client that supports reading and
writing from devices or image files containing ext2, ext3, and
ext4 file systems.
%prep %prep
%setup -q -n e2fsprogs-%{version} %setup -q -n e2fsprogs-%{version}
# e2fsprogs patches
%patch1 -p1
# libcom_err patches # libcom_err patches
%patch3 -p1 %patch3 -p1
%patch4 %patch4
%patch5 %patch5
cp %{SOURCE2} .
%patch6 -p1 %patch6 -p1
%patch7 -p1 %patch7 -p1
%patch8 -p1 %patch8 -p1
%patch9 -p1 %patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%patch16 -p1
%patch17 -p1
cp %{SOURCE2} .
%build %build
%global _lto_cflags %{_lto_cflags} -ffat-lto-objects autoreconf --force --install
%configure \ %configure \
--disable-evms \
--with-root-prefix='' \ --with-root-prefix='' \
--enable-elf-shlibs \ --enable-elf-shlibs \
--disable-libblkid \ --disable-libblkid \
--disable-libuuid \ --disable-libuuid \
--disable-uuidd \ --disable-uuidd \
--disable-fsck \ --disable-fsck \
--without-crond-dir \ --enable-static \
--with-systemd-unit-dir=%{?_unitdir} \
CFLAGS="$RPM_OPT_FLAGS" CFLAGS="$RPM_OPT_FLAGS"
%if %{build_mini} %if %{build_mini}
rm -rf doc rm -rf doc
@ -307,7 +285,7 @@ make install install-libs DESTDIR=$RPM_BUILD_ROOT ELF_INSTALL_DIR=/%{_libdir}
rm $RPM_BUILD_ROOT%{_libdir}/e2initrd_helper rm $RPM_BUILD_ROOT%{_libdir}/e2initrd_helper
%if !0%{?usrmerged} #UsrMerge
mkdir %{buildroot}/sbin mkdir %{buildroot}/sbin
ln -s %{_sbindir}/badblocks %{buildroot}/sbin/badblocks ln -s %{_sbindir}/badblocks %{buildroot}/sbin/badblocks
ln -s %{_sbindir}/debugfs %{buildroot}/sbin/debugfs ln -s %{_sbindir}/debugfs %{buildroot}/sbin/debugfs
@ -315,7 +293,6 @@ ln -s %{_sbindir}/dumpe2fs %{buildroot}/sbin/dumpe2fs
ln -s %{_sbindir}/e2undo %{buildroot}/sbin/e2undo ln -s %{_sbindir}/e2undo %{buildroot}/sbin/e2undo
ln -s %{_sbindir}/e2fsck %{buildroot}/sbin/e2fsck ln -s %{_sbindir}/e2fsck %{buildroot}/sbin/e2fsck
ln -s %{_sbindir}/e2label %{buildroot}/sbin/e2label ln -s %{_sbindir}/e2label %{buildroot}/sbin/e2label
ln -s %{_sbindir}/e2mmpstatus %{buildroot}/sbin/e2mmpstatus
ln -s %{_sbindir}/fsck.ext2 %{buildroot}/sbin/fsck.ext2 ln -s %{_sbindir}/fsck.ext2 %{buildroot}/sbin/fsck.ext2
ln -s %{_sbindir}/fsck.ext3 %{buildroot}/sbin/fsck.ext3 ln -s %{_sbindir}/fsck.ext3 %{buildroot}/sbin/fsck.ext3
ln -s %{_sbindir}/fsck.ext4 %{buildroot}/sbin/fsck.ext4 ln -s %{_sbindir}/fsck.ext4 %{buildroot}/sbin/fsck.ext4
@ -334,67 +311,22 @@ popd
for libName in $LIBNAMES; for libName in $LIBNAMES;
do ln -s %{_libdir}/$libName %{buildroot}/%{_lib}; do ln -s %{_libdir}/$libName %{buildroot}/%{_lib};
done done
%endif
%if %{with systemd}
%if %{build_mini}
%pre -n e2fsprogs-scrub-mini
%else
%pre -n e2fsprogs-scrub
%endif
%service_add_pre e2scrub@.service e2scrub_all.service e2scrub_all.timer e2scrub_fail@.service e2scrub_reap.service
%endif
#EndUsrMerge
%post %post
/sbin/ldconfig /sbin/ldconfig
%if ! %{build_mini} %if ! %{build_mini}
%if 0%{?suse_version} <= 1530 %install_info --info-dir=%{_infodir} %{_infodir}/libext2fs.info.gz || :
%install_info --info-dir=%{_infodir} %{_infodir}/libext2fs.info.gz
%endif
%{?regenerate_initrd_post} %{?regenerate_initrd_post}
%endif %endif
%if %{with systemd}
%if %{build_mini}
%post -n e2fsprogs-scrub-mini
%else
%post -n e2fsprogs-scrub
%endif
%service_add_post e2scrub@.service e2scrub_all.service e2scrub_all.timer e2scrub_fail@.service e2scrub_reap.service
%endif
%if %{with systemd}
%if %{build_mini}
%preun -n e2fsprogs-scrub-mini
%else
%if 0%{?suse_version} <= 1530
%preun
%install_info_delete --info-dir=%{_infodir} %{_infodir}/libext2fs.info.gz
%endif
%preun -n e2fsprogs-scrub
%endif
%service_del_preun e2scrub@.service e2scrub_all.service e2scrub_all.timer e2scrub_fail@.service e2scrub_reap.service
%endif
%postun %postun
/sbin/ldconfig /sbin/ldconfig
%if ! %{build_mini} %if ! %{build_mini}
%install_info_delete --info-dir=%{_infodir} %{_infodir}/libext2fs.info.gz || :
%{?regenerate_initrd_post} %{?regenerate_initrd_post}
%endif %endif
%if %{with systemd}
%if %{build_mini}
%postun -n e2fsprogs-scrub-mini
%else
%postun -n e2fsprogs-scrub
%endif
%service_del_postun e2scrub@.service e2scrub_all.service e2scrub_all.timer e2scrub_fail@.service e2scrub_reap.service
%endif
%if ! %{build_mini} %if ! %{build_mini}
%posttrans %posttrans
%{?regenerate_initrd_posttrans} %{?regenerate_initrd_posttrans}
@ -426,19 +358,18 @@ done
%files -f e2fsprogs.lang %files -f e2fsprogs.lang
%defattr(-, root, root) %defattr(-, root, root)
%doc doc/RelNotes/v%{version}.txt README %doc RELEASE-NOTES README
%if 0%{?sle_version} > 120200 %if 0%{?sle_version} > 120200
%license NOTICE %license NOTICE
%endif %endif
%config /etc/mke2fs.conf %config /etc/mke2fs.conf
%if !0%{?usrmerged} #UsrMerge
/sbin/badblocks /sbin/badblocks
/sbin/debugfs /sbin/debugfs
/sbin/dumpe2fs /sbin/dumpe2fs
/sbin/e2undo /sbin/e2undo
/sbin/e2fsck /sbin/e2fsck
/sbin/e2label /sbin/e2label
/sbin/e2mmpstatus
/sbin/fsck.ext2 /sbin/fsck.ext2
/sbin/fsck.ext3 /sbin/fsck.ext3
/sbin/fsck.ext4 /sbin/fsck.ext4
@ -450,14 +381,13 @@ done
/sbin/tune2fs /sbin/tune2fs
/sbin/e2image /sbin/e2image
/sbin/logsave /sbin/logsave
%endif #EndUsrMerge
%{_sbindir}/badblocks %{_sbindir}/badblocks
%{_sbindir}/debugfs %{_sbindir}/debugfs
%{_sbindir}/dumpe2fs %{_sbindir}/dumpe2fs
%{_sbindir}/e2undo %{_sbindir}/e2undo
%{_sbindir}/e2fsck %{_sbindir}/e2fsck
%{_sbindir}/e2label %{_sbindir}/e2label
%{_sbindir}/e2mmpstatus
%{_sbindir}/fsck.ext2 %{_sbindir}/fsck.ext2
%{_sbindir}/fsck.ext3 %{_sbindir}/fsck.ext3
%{_sbindir}/fsck.ext4 %{_sbindir}/fsck.ext4
@ -490,26 +420,6 @@ done
%defattr(-,root,root) %defattr(-,root,root)
%doc README.SUSE %doc README.SUSE
%if %{build_mini}
%files -n e2fsprogs-scrub-mini
%else
%files -n e2fsprogs-scrub
%endif
%defattr(-,root,root)
%config /etc/e2scrub.conf
%{_sbindir}/e2scrub
%{_sbindir}/e2scrub_all
%if %{with systemd}
%{_libdir}/e2fsprogs/
%{_libdir}/e2fsprogs/e2scrub_fail
%{_unitdir}/e2scrub@.service
%{_unitdir}/e2scrub_all.service
%{_unitdir}/e2scrub_all.timer
%{_unitdir}/e2scrub_fail@.service
%{_unitdir}/e2scrub_reap.service
%endif
%if %{build_mini} %if %{build_mini}
%files -n libext2fs2-mini %files -n libext2fs2-mini
%else %else
@ -517,10 +427,10 @@ done
%files -n libext2fs2 %files -n libext2fs2
%endif %endif
%defattr(-, root, root) %defattr(-, root, root)
%if !0%{?usrmerged} #UsrMerge
/%{_lib}/libext2fs.so.* /%{_lib}/libext2fs.so.*
/%{_lib}/libe2p.so.* /%{_lib}/libe2p.so.*
%endif #EndUsrMerge
%{_libdir}/libext2fs.so.* %{_libdir}/libext2fs.so.*
%{_libdir}/libe2p.so.* %{_libdir}/libe2p.so.*
@ -545,10 +455,10 @@ done
%files -n libcom_err2 %files -n libcom_err2
%endif %endif
%defattr(-, root, root) %defattr(-, root, root)
%if !0%{?usrmerged} #UsrMerge
/%{_lib}/libcom_err.so.* /%{_lib}/libcom_err.so.*
/%{_lib}/libss.so.* /%{_lib}/libss.so.*
%endif #EndUsrMerge
%{_libdir}/libcom_err.so.* %{_libdir}/libcom_err.so.*
%{_libdir}/libss.so.* %{_libdir}/libss.so.*
@ -586,8 +496,4 @@ done
%{_libdir}/libe2p.a %{_libdir}/libe2p.a
%endif %endif
%files -n fuse2fs
%_bindir/fuse2fs
%{_mandir}/man1/fuse2fs.1.gz
%changelog %changelog

View File

@ -0,0 +1,616 @@
From 9a4d2dcc8deaa1c28b3a713c2f610be503855946 Mon Sep 17 00:00:00 2001
From: Jan Kara <jack@suse.cz>
Date: Thu, 13 Feb 2020 11:15:59 +0100
Subject: [PATCH 2/5] ext2fs: implement dir entry creation in htree directories
References: bsc#1160979
Implement proper creation of new directory entries in htree directories
in ext2fs_link(). So far we just cleared EXT2_INDEX_FL and treated
directory as unindexed however this results in mismatched checksums if
metadata checksums are in use because checksums are placed in different
places depending on htree node type.
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
---
lib/ext2fs/link.c | 549 ++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 497 insertions(+), 52 deletions(-)
Index: e2fsprogs-1.43.8/lib/ext2fs/link.c
===================================================================
--- e2fsprogs-1.43.8.orig/lib/ext2fs/link.c
+++ e2fsprogs-1.43.8/lib/ext2fs/link.c
@@ -18,6 +18,153 @@
#include "ext2_fs.h"
#include "ext2fs.h"
+#include "ext2fsP.h"
+
+#define EXT2_DX_ROOT_OFF 24
+
+struct dx_frame {
+ void *buf;
+ blk64_t pblock;
+ struct ext2_dx_countlimit *head;
+ struct ext2_dx_entry *entries;
+ struct ext2_dx_entry *at;
+};
+
+struct dx_lookup_info {
+ const char *name;
+ int namelen;
+ int hash_alg;
+ __u32 hash;
+ int levels;
+ struct dx_frame frames[2];
+};
+
+static errcode_t alloc_dx_frame(ext2_filsys fs, struct dx_frame *frame)
+{
+ return ext2fs_get_mem(fs->blocksize, &frame->buf);
+}
+
+static void dx_release(struct dx_lookup_info *info)
+{
+ struct ext2_dx_root_info *root;
+ int level;
+
+ for (level = 0; level < info->levels; level++) {
+ if (info->frames[level].buf == NULL)
+ break;
+ ext2fs_free_mem(&(info->frames[level].buf));
+ }
+ info->levels = 0;
+}
+
+static void dx_search_entry(struct dx_frame *frame, int count, __u32 hash)
+{
+ struct ext2_dx_entry *p, *q, *m;
+
+ p = frame->entries + 1;
+ q = frame->entries + count - 1;
+ while (p <= q) {
+ m = p + (q - p) / 2;
+ if (ext2fs_le32_to_cpu(m->hash) > hash)
+ q = m - 1;
+ else
+ p = m + 1;
+ }
+ frame->at = p - 1;
+}
+
+static errcode_t load_logical_dir_block(ext2_filsys fs, ext2_ino_t dir,
+ struct ext2_inode *diri, blk64_t block,
+ blk64_t *pblk, void *buf)
+{
+ errcode_t errcode;
+ int ret_flags;
+
+ errcode = ext2fs_bmap2(fs, dir, diri, NULL, 0, block, &ret_flags,
+ pblk);
+ if (errcode)
+ return errcode;
+ if (ret_flags & BMAP_RET_UNINIT)
+ return EXT2_ET_DIR_CORRUPTED;
+ return ext2fs_read_dir_block4(fs, *pblk, buf, 0, dir);
+}
+
+static errcode_t dx_lookup(ext2_filsys fs, ext2_ino_t dir,
+ struct ext2_inode *diri, struct dx_lookup_info *info)
+{
+ struct ext2_dx_root_info *root;
+ errcode_t errcode;
+ int level = 0;
+ int count, limit;
+ int hash_alg;
+ __u32 hash, minor_hash;
+ struct dx_frame *frame;
+
+ errcode = alloc_dx_frame(fs, &(info->frames[0]));
+ if (errcode)
+ return errcode;
+ info->levels = 1;
+
+ errcode = load_logical_dir_block(fs, dir, diri, 0,
+ &(info->frames[0].pblock),
+ info->frames[0].buf);
+ if (errcode)
+ goto out_err;
+ root = info->frames[0].buf + EXT2_DX_ROOT_OFF;
+ hash_alg = root->hash_version;
+ if (hash_alg != EXT2_HASH_TEA && hash_alg != EXT2_HASH_HALF_MD4 &&
+ hash_alg != EXT2_HASH_LEGACY) {
+ errcode = EXT2_ET_DIRHASH_UNSUPP;
+ goto out_err;
+ }
+ if (hash_alg <= EXT2_HASH_TEA &&
+ fs->super->s_flags & EXT2_FLAGS_UNSIGNED_HASH)
+ hash_alg += 3;
+ if (root->indirect_levels >= 2) {
+ errcode = EXT2_ET_DIR_CORRUPTED;
+ goto out_err;
+ }
+ info->hash_alg = hash_alg;
+
+ errcode = ext2fs_dirhash(hash_alg, info->name, info->namelen,
+ fs->super->s_hash_seed, &info->hash,
+ &minor_hash);
+ if (errcode)
+ goto out_err;
+
+ for (level = 0; level <= root->indirect_levels; level++) {
+ frame = &(info->frames[level]);
+ if (level > 0) {
+ errcode = alloc_dx_frame(fs, frame);
+ if (errcode)
+ goto out_err;
+ info->levels++;
+
+ errcode = load_logical_dir_block(fs, dir, diri,
+ ext2fs_le32_to_cpu(info->frames[level-1].at->block) & 0x0fffffff,
+ &(frame->pblock), frame->buf);
+ if (errcode)
+ goto out_err;
+ }
+ errcode = ext2fs_get_dx_countlimit(fs, frame->buf,
+ &(frame->head), NULL);
+ if (errcode)
+ goto out_err;
+ count = ext2fs_le16_to_cpu(frame->head->count);
+ limit = ext2fs_le16_to_cpu(frame->head->limit);
+ frame->entries = (struct ext2_dx_entry *)(frame->head);
+ if (!count || count > limit) {
+ errcode = EXT2_ET_DIR_CORRUPTED;
+ goto out_err;
+ }
+
+ dx_search_entry(frame, count, info->hash);
+ }
+ return 0;
+out_err:
+ dx_release(info);
+ return errcode;
+}
struct link_struct {
ext2_filsys fs;
@@ -31,7 +178,9 @@ struct link_struct {
struct ext2_super_block *sb;
};
-static int link_proc(struct ext2_dir_entry *dirent,
+static int link_proc(ext2_ino_t dir EXT2FS_ATTR((unused)),
+ int entru EXT2FS_ATTR((unused)),
+ struct ext2_dir_entry *dirent,
int offset,
int blocksize,
char *buf,
@@ -71,40 +220,6 @@ static int link_proc(struct ext2_dir_ent
}
/*
- * Since ext2fs_link blows away htree data, we need to be
- * careful -- if metadata_csum is enabled and we're passed in
- * a dirent that contains htree data, we need to create the
- * fake entry at the end of the block that hides the checksum.
- */
-
- /* De-convert a dx_node block */
- if (csum_size &&
- curr_rec_len == ls->fs->blocksize &&
- !dirent->inode) {
- curr_rec_len -= csum_size;
- ls->err = ext2fs_set_rec_len(ls->fs, curr_rec_len, dirent);
- if (ls->err)
- return DIRENT_ABORT;
- t = EXT2_DIRENT_TAIL(buf, ls->fs->blocksize);
- ext2fs_initialize_dirent_tail(ls->fs, t);
- ret = DIRENT_CHANGED;
- }
-
- /* De-convert a dx_root block */
- if (csum_size &&
- curr_rec_len == ls->fs->blocksize - EXT2_DIR_REC_LEN(1) &&
- offset == EXT2_DIR_REC_LEN(1) &&
- dirent->name[0] == '.' && dirent->name[1] == '.') {
- curr_rec_len -= csum_size;
- ls->err = ext2fs_set_rec_len(ls->fs, curr_rec_len, dirent);
- if (ls->err)
- return DIRENT_ABORT;
- t = EXT2_DIRENT_TAIL(buf, ls->fs->blocksize);
- ext2fs_initialize_dirent_tail(ls->fs, t);
- ret = DIRENT_CHANGED;
- }
-
- /*
* If the directory entry is used, see if we can split the
* directory entry to make room for the new name. If so,
* truncate it and return.
@@ -144,6 +259,341 @@ static int link_proc(struct ext2_dir_ent
return DIRENT_ABORT|DIRENT_CHANGED;
}
+static errcode_t add_dirent_to_buf(ext2_filsys fs, e2_blkcnt_t blockcnt,
+ char *buf, ext2_ino_t dir,
+ struct ext2_inode *diri, const char *name,
+ ext2_ino_t ino, int flags, blk64_t *pblkp)
+{
+ struct dir_context ctx;
+ struct link_struct ls;
+ errcode_t retval;
+
+ retval = load_logical_dir_block(fs, dir, diri, blockcnt, pblkp, buf);
+ if (retval)
+ return retval;
+ ctx.errcode = 0;
+ ctx.func = link_proc;
+ ctx.dir = dir;
+ ctx.flags = DIRENT_FLAG_INCLUDE_EMPTY;
+ ctx.buf = buf;
+ ctx.priv_data = &ls;
+
+ ls.fs = fs;
+ ls.name = name;
+ ls.namelen = strlen(name);
+ ls.inode = ino;
+ ls.flags = flags;
+ ls.done = 0;
+ ls.sb = fs->super;
+ ls.blocksize = fs->blocksize;
+ ls.err = 0;
+
+ ext2fs_process_dir_block(fs, pblkp, blockcnt, 0, 0, &ctx);
+ if (ctx.errcode)
+ return ctx.errcode;
+ if (ls.err)
+ return ls.err;
+ if (!ls.done)
+ return EXT2_ET_DIR_NO_SPACE;
+ return 0;
+}
+
+struct dx_hash_map {
+ __u32 hash;
+ int size;
+ int off;
+};
+
+static EXT2_QSORT_TYPE dx_hash_map_cmp(const void *ap, const void *bp)
+{
+ const struct dx_hash_map *a = ap, *b = bp;
+
+ if (a->hash < b->hash)
+ return -1;
+ if (a->hash > b->hash)
+ return 1;
+ return 0;
+}
+
+static errcode_t dx_move_dirents(ext2_filsys fs, struct dx_hash_map *map,
+ int count, void *from, void *to)
+{
+ struct ext2_dir_entry *de;
+ int i;
+ int rec_len;
+ errcode_t retval;
+ int csum_size = 0;
+ void *base = to;
+
+ if (ext2fs_has_feature_metadata_csum(fs->super))
+ csum_size = sizeof(struct ext2_dir_entry_tail);
+
+ for (i = 0; i < count; i++) {
+ de = from + map[i].off;
+ rec_len = EXT2_DIR_REC_LEN(ext2fs_dirent_name_len(de));
+ memcpy(to, de, rec_len);
+ retval = ext2fs_set_rec_len(fs, rec_len, to);
+ if (retval)
+ return retval;
+ to += rec_len;
+ }
+ /*
+ * Update rec_len of the last dir entry to stretch to the end of block
+ */
+ to -= rec_len;
+ rec_len = fs->blocksize - (to - base) - csum_size;
+ retval = ext2fs_set_rec_len(fs, rec_len, to);
+ if (retval)
+ return retval;
+ if (csum_size)
+ ext2fs_initialize_dirent_tail(fs,
+ EXT2_DIRENT_TAIL(base, fs->blocksize));
+ return 0;
+}
+
+static errcode_t dx_insert_entry(ext2_filsys fs, ext2_ino_t dir,
+ struct dx_lookup_info *info, int level,
+ __u32 hash, blk64_t lblk)
+{
+ int pcount;
+ struct ext2_dx_entry *top, *new;
+
+ pcount = ext2fs_le16_to_cpu(info->frames[level].head->count);
+ top = info->frames[level].entries + pcount;
+ new = info->frames[level].at + 1;
+ memmove(new + 1, new, (char *)top - (char *)new);
+ new->hash = ext2fs_cpu_to_le32(hash);
+ new->block = ext2fs_cpu_to_le32(lblk);
+ info->frames[level].head->count = ext2fs_cpu_to_le16(pcount + 1);
+ return ext2fs_write_dir_block4(fs, info->frames[level].pblock,
+ info->frames[level].buf, 0, dir);
+}
+
+static errcode_t dx_split_leaf(ext2_filsys fs, ext2_ino_t dir,
+ struct ext2_inode *diri,
+ struct dx_lookup_info *info, void *buf,
+ blk64_t leaf_pblk, blk64_t new_lblk,
+ blk64_t new_pblk)
+{
+ struct ext2_dir_entry *de;
+ void *buf2;
+ errcode_t retval = 0;
+ int rec_len;
+ int offset, move_size;
+ int i, count = 0;
+ struct dx_hash_map *map;
+ int continued;
+ __u32 minor_hash;
+
+ retval = ext2fs_get_mem(fs->blocksize, &buf2);
+ if (retval)
+ return retval;
+ retval = ext2fs_get_array(fs->blocksize / 12,
+ sizeof(struct dx_hash_map), &map);
+ if (retval) {
+ ext2fs_free_mem(&buf2);
+ return retval;
+ }
+ for (offset = 0; offset < fs->blocksize; offset += rec_len) {
+ de = buf + offset;
+ retval = ext2fs_get_rec_len(fs, de, &rec_len);
+ if (retval)
+ goto out;
+ if (ext2fs_dirent_name_len(de) > 0 && de->inode) {
+ map[count].off = offset;
+ map[count].size = rec_len;
+ retval = ext2fs_dirhash(info->hash_alg, de->name,
+ ext2fs_dirent_name_len(de),
+ fs->super->s_hash_seed,
+ &(map[count].hash),
+ &minor_hash);
+ if (retval)
+ goto out;
+ count++;
+ }
+ }
+ qsort(map, count, sizeof(struct dx_hash_map), dx_hash_map_cmp);
+ move_size = 0;
+ /* Find place to split block */
+ for (i = count - 1; i >= 0; i--) {
+ if (move_size + map[i].size / 2 > fs->blocksize / 2)
+ break;
+ move_size += map[i].size;
+ }
+ /* Let i be the first entry to move */
+ i++;
+ /* Move selected directory entries to new block */
+ retval = dx_move_dirents(fs, map + i, count - i, buf, buf2);
+ if (retval)
+ goto out;
+ retval = ext2fs_write_dir_block4(fs, new_pblk, buf2, 0, dir);
+ if (retval)
+ goto out;
+ /* Repack remaining entries in the old block */
+ retval = dx_move_dirents(fs, map, i, buf, buf2);
+ if (retval)
+ goto out;
+ retval = ext2fs_write_dir_block4(fs, leaf_pblk, buf2, 0, dir);
+ if (retval)
+ goto out;
+ /* Update parent node */
+ continued = map[i].hash == map[i-1].hash;
+ retval = dx_insert_entry(fs, dir, info, info->levels - 1,
+ map[i].hash + continued, new_lblk);
+out:
+ ext2fs_free_mem(&buf2);
+ ext2fs_free_mem(&map);
+ return retval;
+}
+
+static errcode_t dx_grow_tree(ext2_filsys fs, ext2_ino_t dir,
+ struct ext2_inode *diri,
+ struct dx_lookup_info *info, void *buf,
+ blk64_t leaf_pblk)
+{
+ int i;
+ errcode_t retval;
+ ext2_off64_t size = EXT2_I_SIZE(diri);
+ blk64_t lblk, pblk;
+ struct ext2_dir_entry *de;
+ struct ext2_dx_countlimit *head;
+ int csum_size = 0;
+ int count;
+
+ if (ext2fs_has_feature_metadata_csum(fs->super))
+ csum_size = sizeof(struct ext2_dx_tail);
+
+ /* Find level which can accommodate new child */
+ for (i = info->levels - 1; i >= 0; i--)
+ if (ext2fs_le16_to_cpu(info->frames[i].head->count) <
+ ext2fs_le16_to_cpu(info->frames[i].head->limit))
+ break;
+ /* Need to grow tree depth? */
+ if (i < 0 && info->levels >= 2)
+ return EXT2_ET_DIR_NO_SPACE;
+ lblk = size / fs->blocksize;
+ size += fs->blocksize;
+ retval = ext2fs_inode_size_set(fs, diri, size);
+ if (retval)
+ return retval;
+ retval = ext2fs_fallocate(fs,
+ EXT2_FALLOCATE_FORCE_INIT | EXT2_FALLOCATE_ZERO_BLOCKS,
+ dir, diri, 0, lblk, 1);
+ if (retval)
+ return retval;
+ retval = ext2fs_write_inode(fs, dir, diri);
+ if (retval)
+ return retval;
+ retval = ext2fs_bmap2(fs, dir, diri, NULL, 0, lblk, NULL, &pblk);
+ if (retval)
+ return retval;
+ /* Only leaf addition needed? */
+ if (i == info->levels - 1)
+ return dx_split_leaf(fs, dir, diri, info, buf, leaf_pblk,
+ lblk, pblk);
+
+ de = buf;
+ de->inode = 0;
+ ext2fs_dirent_set_name_len(de, 0);
+ ext2fs_dirent_set_file_type(de, 0);
+ retval = ext2fs_set_rec_len(fs, fs->blocksize, de);
+ if (retval)
+ return retval;
+ head = buf + 8;
+ count = ext2fs_le16_to_cpu(info->frames[i+1].head->count);
+ /* Growing tree depth? */
+ if (i < 0) {
+ struct ext2_dx_root_info *root;
+
+ memcpy(head, info->frames[0].entries,
+ count * sizeof(struct ext2_dx_entry));
+ head->limit = ext2fs_cpu_to_le16(
+ (fs->blocksize - (8 + csum_size)) /
+ sizeof(struct ext2_dx_entry));
+ /* head->count gets set by memcpy above to correct value */
+
+ /* Now update tree root */
+ info->frames[0].head->count = ext2fs_cpu_to_le16(1);
+ info->frames[0].entries[0].block = ext2fs_cpu_to_le32(lblk);
+ root = info->frames[0].buf + EXT2_DX_ROOT_OFF;
+ root->indirect_levels++;
+ } else {
+ /* Splitting internal node in two */
+ int count1 = count / 2;
+ int count2 = count - count1;
+ __u32 split_hash = ext2fs_le32_to_cpu(info->frames[i+1].entries[count1].hash);
+
+ memcpy(head, info->frames[i+1].entries + count1,
+ count2 * sizeof(struct ext2_dx_entry));
+ head->count = ext2fs_cpu_to_le16(count2);
+ head->limit = ext2fs_cpu_to_le16(
+ (fs->blocksize - (8 + csum_size)) /
+ sizeof(struct ext2_dx_entry));
+ info->frames[i+1].head->count = ext2fs_cpu_to_le16(count1);
+
+ /* Update parent node */
+ retval = dx_insert_entry(fs, dir, info, i, split_hash, lblk);
+ if (retval)
+ return retval;
+
+ }
+ /* Writeout split block / updated root */
+ retval = ext2fs_write_dir_block4(fs, info->frames[i+1].pblock,
+ info->frames[i+1].buf, 0, dir);
+ if (retval)
+ return retval;
+ /* Writeout new tree block */
+ retval = ext2fs_write_dir_block4(fs, pblk, buf, 0, dir);
+ if (retval)
+ return retval;
+ return 0;
+}
+
+static errcode_t dx_link(ext2_filsys fs, ext2_ino_t dir,
+ struct ext2_inode *diri, const char *name,
+ ext2_ino_t ino, int flags)
+{
+ struct dx_lookup_info dx_info;
+ errcode_t retval;
+ void *blockbuf;
+ int restart = 0;
+ blk64_t leaf_pblk;
+
+ retval = ext2fs_get_mem(fs->blocksize, &blockbuf);
+ if (retval)
+ return retval;
+
+ dx_info.name = name;
+ dx_info.namelen = strlen(name);
+again:
+ retval = dx_lookup(fs, dir, diri, &dx_info);
+ if (retval)
+ goto free_buf;
+
+ retval = add_dirent_to_buf(fs,
+ ext2fs_le32_to_cpu(dx_info.frames[dx_info.levels-1].at->block) & 0x0fffffff,
+ blockbuf, dir, diri, name, ino, flags, &leaf_pblk);
+ /*
+ * Success or error other than ENOSPC...? We are done. We may need upto
+ * two tries to add entry. One to split htree node and another to add
+ * new leaf block.
+ */
+ if (restart >= dx_info.levels || retval != EXT2_ET_DIR_NO_SPACE)
+ goto free_frames;
+ retval = dx_grow_tree(fs, dir, diri, &dx_info, blockbuf, leaf_pblk);
+ if (retval)
+ goto free_frames;
+ /* Restart everything now that the tree is larger */
+ restart++;
+ dx_release(&dx_info);
+ goto again;
+free_frames:
+ dx_release(&dx_info);
+free_buf:
+ ext2fs_free_mem(&blockbuf);
+ return retval;
+}
+
/*
* Note: the low 3 bits of the flags field are used as the directory
* entry filetype.
@@ -163,6 +613,12 @@ errcode_t ext2fs_link(ext2_filsys fs, ex
if (!(fs->flags & EXT2_FLAG_RW))
return EXT2_ET_RO_FILSYS;
+ if ((retval = ext2fs_read_inode(fs, dir, &inode)) != 0)
+ return retval;
+
+ if (inode.i_flags & EXT2_INDEX_FL)
+ return dx_link(fs, dir, &inode, name, ino, flags);
+
ls.fs = fs;
ls.name = name;
ls.namelen = name ? strlen(name) : 0;
@@ -173,8 +629,8 @@ errcode_t ext2fs_link(ext2_filsys fs, ex
ls.blocksize = fs->blocksize;
ls.err = 0;
- retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
- 0, link_proc, &ls);
+ retval = ext2fs_dir_iterate2(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
+ NULL, link_proc, &ls);
if (retval)
return retval;
if (ls.err)
@@ -182,20 +638,5 @@ errcode_t ext2fs_link(ext2_filsys fs, ex
if (!ls.done)
return EXT2_ET_DIR_NO_SPACE;
-
- if ((retval = ext2fs_read_inode(fs, dir, &inode)) != 0)
- return retval;
-
- /*
- * If this function changes to preserve the htree, remove the
- * two hunks in link_proc that shove checksum tails into the
- * former dx_root/dx_node blocks.
- */
- if (inode.i_flags & EXT2_INDEX_FL) {
- inode.i_flags &= ~EXT2_INDEX_FL;
- if ((retval = ext2fs_write_inode(fs, dir, &inode)) != 0)
- return retval;
- }
-
return 0;
}

View File

@ -0,0 +1,128 @@
From a25a84c6aa2a19987b0aeced363c4bf1dcc89ec8 Mon Sep 17 00:00:00 2001
From: Jan Kara <jack@suse.cz>
Date: Thu, 13 Feb 2020 11:15:58 +0100
Subject: [PATCH 1/5] ext2fs: update allocation info earlier in ext2fs_mkdir()
and ext2fs_symlink()
References: bsc#1160979
Currently, ext2fs_mkdir() and ext2fs_symlink() update allocation bitmaps
and other information only close to the end of the function, in
particular after calling to ext2fs_link(). When ext2fs_link() will
support indexed directories, it will also need to allocate blocks and
that would cause filesystem corruption in case allocation info isn't
properly updated. So make sure ext2fs_mkdir() and ext2fs_symlink()
update allocation info before calling into ext2fs_link().
[ Added error handling so the calls to ext2fs_{block,inode}_alloc_stats()
can be undone if the newly created directory or symlink can not be linked
into the directory. -- TYT ]
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
---
lib/ext2fs/mkdir.c | 22 +++++++++++++++-------
lib/ext2fs/symlink.c | 22 +++++++++++++++-------
2 files changed, 30 insertions(+), 14 deletions(-)
Index: e2fsprogs-1.43.8/lib/ext2fs/mkdir.c
===================================================================
--- e2fsprogs-1.43.8.orig/lib/ext2fs/mkdir.c
+++ e2fsprogs-1.43.8/lib/ext2fs/mkdir.c
@@ -43,6 +43,7 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, e
blk64_t blk;
char *block = 0;
int inline_data = 0;
+ int drop_refcount = 0;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@@ -144,6 +145,14 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, e
}
/*
+ * Update accounting....
+ */
+ if (!inline_data)
+ ext2fs_block_alloc_stats2(fs, blk, +1);
+ ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
+ drop_refcount = 1;
+
+ /*
* Link the directory into the filesystem hierarchy
*/
if (name) {
@@ -174,17 +183,16 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, e
if (retval)
goto cleanup;
}
-
- /*
- * Update accounting....
- */
- if (!inline_data)
- ext2fs_block_alloc_stats2(fs, blk, +1);
- ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
+ drop_refcount = 0;
cleanup:
if (block)
ext2fs_free_mem(&block);
+ if (drop_refcount) {
+ if (!inline_data)
+ ext2fs_block_alloc_stats2(fs, blk, -1);
+ ext2fs_inode_alloc_stats2(fs, ino, -1, 1);
+ }
return retval;
}
Index: e2fsprogs-1.43.8/lib/ext2fs/symlink.c
===================================================================
--- e2fsprogs-1.43.8.orig/lib/ext2fs/symlink.c
+++ e2fsprogs-1.43.8/lib/ext2fs/symlink.c
@@ -38,6 +38,7 @@ errcode_t ext2fs_symlink(ext2_filsys fs,
int fastlink, inlinelink;
unsigned int target_len;
char *block_buf = 0;
+ int drop_refcount = 0;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@@ -146,6 +147,14 @@ need_block:
}
/*
+ * Update accounting....
+ */
+ if (!fastlink && !inlinelink)
+ ext2fs_block_alloc_stats2(fs, blk, +1);
+ ext2fs_inode_alloc_stats2(fs, ino, +1, 0);
+ drop_refcount = 1;
+
+ /*
* Link the symlink into the filesystem hierarchy
*/
if (name) {
@@ -161,16 +170,15 @@ need_block:
if (retval)
goto cleanup;
}
-
- /*
- * Update accounting....
- */
- if (!fastlink && !inlinelink)
- ext2fs_block_alloc_stats2(fs, blk, +1);
- ext2fs_inode_alloc_stats2(fs, ino, +1, 0);
+ drop_refcount = 0;
cleanup:
if (block_buf)
ext2fs_free_mem(&block_buf);
+ if (drop_refcount) {
+ if (!fastlink && !inlinelink)
+ ext2fs_block_alloc_stats2(fs, blk, -1);
+ ext2fs_inode_alloc_stats2(fs, ino, -1, 0);
+ }
return retval;
}

View File

@ -1,19 +0,0 @@
Index: e2fsprogs-1.46.4/scrub/e2scrub@.service.in
===================================================================
--- e2fsprogs-1.46.4.orig/scrub/e2scrub@.service.in
+++ e2fsprogs-1.46.4/scrub/e2scrub@.service.in
@@ -10,6 +10,14 @@ PrivateNetwork=true
ProtectSystem=true
ProtectHome=read-only
PrivateTmp=yes
+# added automatically, for details please see
+# https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort
+ProtectHostname=true
+ProtectKernelTunables=true
+ProtectKernelLogs=true
+ProtectControlGroups=true
+RestrictRealtime=true
+# end of automatic additions
AmbientCapabilities=CAP_SYS_ADMIN CAP_SYS_RAWIO
NoNewPrivileges=yes
User=root

View File

@ -1,22 +0,0 @@
Index: e2fsprogs-1.46.3/scrub/e2scrub_all.service.in
===================================================================
--- e2fsprogs-1.46.3.orig/scrub/e2scrub_all.service.in
+++ e2fsprogs-1.46.3/scrub/e2scrub_all.service.in
@@ -6,6 +6,17 @@ ConditionCapability=CAP_SYS_RAWIO
Documentation=man:e2scrub_all(8)
[Service]
+# added automatically, for details please see
+# https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort
+ProtectSystem=full
+ProtectHome=true
+ProtectHostname=true
+ProtectKernelTunables=true
+ProtectKernelModules=true
+ProtectKernelLogs=true
+ProtectControlGroups=true
+RestrictRealtime=true
+# end of automatic additions
Type=oneshot
Environment=SERVICE_MODE=1
ExecStart=@root_sbindir@/e2scrub_all

View File

@ -1,22 +0,0 @@
Index: e2fsprogs-1.46.3/scrub/e2scrub_fail@.service.in
===================================================================
--- e2fsprogs-1.46.3.orig/scrub/e2scrub_fail@.service.in
+++ e2fsprogs-1.46.3/scrub/e2scrub_fail@.service.in
@@ -3,6 +3,17 @@ Description=Online ext4 Metadata Check F
Documentation=man:e2scrub(8)
[Service]
+# added automatically, for details please see
+# https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort
+ProtectSystem=full
+ProtectHome=true
+ProtectHostname=true
+ProtectKernelTunables=true
+ProtectKernelModules=true
+ProtectKernelLogs=true
+ProtectControlGroups=true
+RestrictRealtime=true
+# end of automatic additions
Type=oneshot
ExecStart=@pkglibdir@/e2scrub_fail "%I"
User=mail

View File

@ -1,20 +0,0 @@
Index: e2fsprogs-1.46.3/scrub/e2scrub_reap.service.in
===================================================================
--- e2fsprogs-1.46.3.orig/scrub/e2scrub_reap.service.in
+++ e2fsprogs-1.46.3/scrub/e2scrub_reap.service.in
@@ -11,6 +11,15 @@ PrivateNetwork=true
ProtectSystem=true
ProtectHome=read-only
PrivateTmp=yes
+# added automatically, for details please see
+# https://en.opensuse.org/openSUSE:Security_Features#Systemd_hardening_effort
+ProtectHostname=true
+ProtectKernelTunables=true
+ProtectKernelModules=true
+ProtectKernelLogs=true
+ProtectControlGroups=true
+RestrictRealtime=true
+# end of automatic additions
AmbientCapabilities=CAP_SYS_ADMIN CAP_SYS_RAWIO
NoNewPrivileges=yes
User=root

View File

@ -0,0 +1,36 @@
From: Jan Kara <jack@suse.cz>
Date: Wed, 31 May 2017 14:49:18 +0200
Subject: [PATCH] libext2fs: Fix fsync(2) detection
References: bsc#1038194
For some reason lib/config.h.in was missing a definition of HAVE_FSYNC
and as a result lib/config.h never had HAVE_FSYNC defined. As a result
we never called fsync(2) for example from
lib/ext2fs/unix_io.c:unix_flush() when we finished creating filesystem
and could miss IO errors happening during creating of the filesystem.
Test generic/405 exposes this problem.
Fix the problem by defining HAVE_FSYNC in lib/config.h.in.
Signed-off-by: Jan Kara <jack@suse.cz>
---
lib/config.h.in | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/config.h.in b/lib/config.h.in
index 37d0c461338a..91e869e7d3d7 100644
--- a/lib/config.h.in
+++ b/lib/config.h.in
@@ -470,6 +470,9 @@
/* Define to 1 if you have the `sync_file_range' function. */
#undef HAVE_SYNC_FILE_RANGE
+/* Define to 1 if you have the 'fsync' function. */
+#undef HAVE_FSYNC
+
/* Define to 1 if you have the `sysconf' function. */
#undef HAVE_SYSCONF
--
2.12.3

View File

@ -0,0 +1,56 @@
From ab51d587bb9b229b1fade1afd02e1574c1ba5c76 Mon Sep 17 00:00:00 2001
From: Lukas Czerner <lczerner@redhat.com>
Date: Thu, 21 Apr 2022 19:31:48 +0200
Subject: [PATCH] libext2fs: add sanity check to extent manipulation
References: bsc#1198446 CVE-2022-1304
It is possible to have a corrupted extent tree in such a way that a leaf
node contains zero extents in it. Currently if that happens and we try
to traverse the tree we can end up accessing wrong data, or possibly
even uninitialized memory. Make sure we don't do that.
Additionally make sure that we have a sane number of bytes passed to
memmove() in ext2fs_extent_delete().
Note that e2fsck is currently unable to spot and fix such corruption in
pass1.
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
Reported-by: Nils Bars <nils_bars@t-online.de>
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=2068113
Addresses: CVE-2022-1304
Addresses-Debian-Bug: #1010263
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
lib/ext2fs/extent.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c
index b324c7b0f8c8..1a206a16c13f 100644
--- a/lib/ext2fs/extent.c
+++ b/lib/ext2fs/extent.c
@@ -495,6 +495,10 @@ retry:
ext2fs_le16_to_cpu(eh->eh_entries);
newpath->max_entries = ext2fs_le16_to_cpu(eh->eh_max);
+ /* Make sure there is at least one extent present */
+ if (newpath->left <= 0)
+ return EXT2_ET_EXTENT_NO_DOWN;
+
if (path->left > 0) {
ix++;
newpath->end_blk = ext2fs_le32_to_cpu(ix->ei_block);
@@ -1630,6 +1634,10 @@ errcode_t ext2fs_extent_delete(ext2_extent_handle_t handle, int flags)
cp = path->curr;
+ /* Sanity check before memmove() */
+ if (path->left < 0)
+ return EXT2_ET_EXTENT_LEAF_BAD;
+
if (path->left) {
memmove(cp, cp + sizeof(struct ext3_extent_idx),
path->left * sizeof(struct ext3_extent_idx));
--
2.34.1

View File

@ -0,0 +1,43 @@
From e8236b49d0fb056847da5fb95b2709e63e6be7c6 Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Wed, 4 Jul 2018 00:23:10 -0400
Subject: [PATCH] libext2fs: call fsync(2) to clear stale errors for a new a
unix I/O channel
References: bsc#1145716
Newer versions of Linux will retain errors and allow them to be
returned by fsync() or close(), even if the error happened before the
file descriptor was opened. This was to accomodate Postgres's
"interesting" method of error collection.
Unfortunately, for e2fsck, we never want to see stale errors, as this
can cause xfstests (such generic/347) to fail with a false positive.
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
---
lib/ext2fs/unix_io.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lib/ext2fs/unix_io.c b/lib/ext2fs/unix_io.c
index 53fbd28bf803..18a2e5f75c07 100644
--- a/lib/ext2fs/unix_io.c
+++ b/lib/ext2fs/unix_io.c
@@ -569,6 +569,14 @@ static errcode_t unix_open_channel(const char *name, int fd,
if (safe_getenv("UNIX_IO_FORCE_BOUNCE"))
flags |= IO_FLAG_FORCE_BOUNCE;
+#ifdef __linux__
+ /*
+ * We need to make sure any previous errors in the block
+ * device are thrown away, sigh.
+ */
+ (void) fsync(fd);
+#endif
+
retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
if (retval)
goto cleanup;
--
2.16.4

View File

@ -0,0 +1,40 @@
From 876d9b0c8eac2fd80dd62bfa1b09adea62aa08f3 Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Wed, 3 Jan 2018 01:32:02 -0500
Subject: [PATCH] libext2fs: fix build failure in swapfs.c on big-endian
systems
References: bsc#1077420
Addresses-Debian-Bug: #886119
Reported-by: James Clarke <jrtc27@debian.org>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
---
lib/ext2fs/swapfs.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
index 6e5cff97e505..b13dc4229225 100644
--- a/lib/ext2fs/swapfs.c
+++ b/lib/ext2fs/swapfs.c
@@ -19,6 +19,7 @@
#include "ext2_fs.h"
#include "ext2fs.h"
+#include "ext2fsP.h"
#include <ext2fs/ext2_ext_attr.h>
#ifdef WORDS_BIGENDIAN
@@ -358,7 +359,7 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
if (inode_includes(inode_size, i_projid))
t->i_projid = ext2fs_swab16(f->i_projid);
/* catch new static fields added after i_projid */
- EXT2FS_BUILD_BUG_ON(sizeof(ext2_inode_large) != 160);
+ EXT2FS_BUILD_BUG_ON(sizeof(struct ext2_inode_large) != 160);
i = sizeof(struct ext2_inode) + extra_isize + sizeof(__u32);
if (bufsize < (int) i)
--
2.13.6

View File

@ -0,0 +1,214 @@
From 8dbe7b475ec5e91ed767239f0e85880f416fc384 Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Sun, 1 Sep 2019 00:59:16 -0400
Subject: [PATCH] libsupport: add checks to prevent buffer overrun bugs in
quota code
References: bsc#1152101 CVE-2019-5094
A maliciously corrupted file systems can trigger buffer overruns in
the quota code used by e2fsck. To fix this, add sanity checks to the
quota header fields as well as to block number references in the quota
tree.
Addresses: CVE-2019-5094
Addresses: TALOS-2019-0887
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
---
lib/support/mkquota.c | 1 +
lib/support/quotaio_tree.c | 71 ++++++++++++++++++++++++++++++----------------
lib/support/quotaio_v2.c | 28 ++++++++++++++++++
3 files changed, 76 insertions(+), 24 deletions(-)
diff --git a/lib/support/mkquota.c b/lib/support/mkquota.c
index 0b9e76659118..ddb531247819 100644
--- a/lib/support/mkquota.c
+++ b/lib/support/mkquota.c
@@ -671,6 +671,7 @@ errcode_t quota_compare_and_update(quota_ctx_t qctx, enum quota_type qtype,
err = qh.qh_ops->scan_dquots(&qh, scan_dquots_callback, &scan_data);
if (err) {
log_debug("Error scanning dquots");
+ *usage_inconsistent = 1;
goto out_close_qh;
}
diff --git a/lib/support/quotaio_tree.c b/lib/support/quotaio_tree.c
index a7c2028c1dc7..6cc4fb5b2c10 100644
--- a/lib/support/quotaio_tree.c
+++ b/lib/support/quotaio_tree.c
@@ -540,6 +540,17 @@ struct dquot *qtree_read_dquot(struct quota_handle *h, qid_t id)
return dquot;
}
+static int check_reference(struct quota_handle *h, unsigned int blk)
+{
+ if (blk >= h->qh_info.u.v2_mdqi.dqi_qtree.dqi_blocks) {
+ log_err("Illegal reference (%u >= %u) in %s quota file",
+ blk, h->qh_info.u.v2_mdqi.dqi_qtree.dqi_blocks,
+ quota_type2name(h->qh_type));
+ return -1;
+ }
+ return 0;
+}
+
/*
* Scan all dquots in file and call callback on each
*/
@@ -558,7 +569,7 @@ static int report_block(struct dquot *dquot, unsigned int blk, char *bitmap,
int entries, i;
if (!buf)
- return 0;
+ return -1;
set_bit(bitmap, blk);
read_blk(dquot->dq_h, blk, buf);
@@ -580,23 +591,12 @@ static int report_block(struct dquot *dquot, unsigned int blk, char *bitmap,
return entries;
}
-static void check_reference(struct quota_handle *h, unsigned int blk)
-{
- if (blk >= h->qh_info.u.v2_mdqi.dqi_qtree.dqi_blocks)
- log_err("Illegal reference (%u >= %u) in %s quota file. "
- "Quota file is probably corrupted.\n"
- "Please run e2fsck (8) to fix it.",
- blk,
- h->qh_info.u.v2_mdqi.dqi_qtree.dqi_blocks,
- quota_type2name(h->qh_type));
-}
-
static int report_tree(struct dquot *dquot, unsigned int blk, int depth,
char *bitmap,
int (*process_dquot) (struct dquot *, void *),
void *data)
{
- int entries = 0, i;
+ int entries = 0, ret, i;
dqbuf_t buf = getdqbuf();
__le32 *ref = (__le32 *) buf;
@@ -607,22 +607,40 @@ static int report_tree(struct dquot *dquot, unsigned int blk, int depth,
if (depth == QT_TREEDEPTH - 1) {
for (i = 0; i < QT_BLKSIZE >> 2; i++) {
blk = ext2fs_le32_to_cpu(ref[i]);
- check_reference(dquot->dq_h, blk);
- if (blk && !get_bit(bitmap, blk))
- entries += report_block(dquot, blk, bitmap,
- process_dquot, data);
+ if (check_reference(dquot->dq_h, blk)) {
+ entries = -1;
+ goto errout;
+ }
+ if (blk && !get_bit(bitmap, blk)) {
+ ret = report_block(dquot, blk, bitmap,
+ process_dquot, data);
+ if (ret < 0) {
+ entries = ret;
+ goto errout;
+ }
+ entries += ret;
+ }
}
} else {
for (i = 0; i < QT_BLKSIZE >> 2; i++) {
blk = ext2fs_le32_to_cpu(ref[i]);
if (blk) {
- check_reference(dquot->dq_h, blk);
- entries += report_tree(dquot, blk, depth + 1,
- bitmap, process_dquot,
- data);
+ if (check_reference(dquot->dq_h, blk)) {
+ entries = -1;
+ goto errout;
+ }
+ ret = report_tree(dquot, blk, depth + 1,
+ bitmap, process_dquot,
+ data);
+ if (ret < 0) {
+ entries = ret;
+ goto errout;
+ }
+ entries += ret;
}
}
}
+errout:
freedqbuf(buf);
return entries;
}
@@ -642,6 +660,7 @@ int qtree_scan_dquots(struct quota_handle *h,
int (*process_dquot) (struct dquot *, void *),
void *data)
{
+ int ret;
char *bitmap;
struct v2_mem_dqinfo *v2info = &h->qh_info.u.v2_mdqi;
struct qtree_mem_dqinfo *info = &v2info->dqi_qtree;
@@ -655,10 +674,14 @@ int qtree_scan_dquots(struct quota_handle *h,
ext2fs_free_mem(&dquot);
return -1;
}
- v2info->dqi_used_entries = report_tree(dquot, QT_TREEOFF, 0, bitmap,
- process_dquot, data);
+ ret = report_tree(dquot, QT_TREEOFF, 0, bitmap, process_dquot, data);
+ if (ret < 0)
+ goto errout;
+ v2info->dqi_used_entries = ret;
v2info->dqi_data_blocks = find_set_bits(bitmap, info->dqi_blocks);
+ ret = 0;
+errout:
ext2fs_free_mem(&bitmap);
ext2fs_free_mem(&dquot);
- return 0;
+ return ret;
}
diff --git a/lib/support/quotaio_v2.c b/lib/support/quotaio_v2.c
index 38be2a34ffae..739066761022 100644
--- a/lib/support/quotaio_v2.c
+++ b/lib/support/quotaio_v2.c
@@ -175,6 +175,8 @@ static int v2_check_file(struct quota_handle *h, int type, int fmt)
static int v2_init_io(struct quota_handle *h)
{
struct v2_disk_dqinfo ddqinfo;
+ struct v2_mem_dqinfo *info;
+ __u64 filesize;
h->qh_info.u.v2_mdqi.dqi_qtree.dqi_entry_size =
sizeof(struct v2r1_disk_dqblk);
@@ -185,6 +187,32 @@ static int v2_init_io(struct quota_handle *h)
sizeof(ddqinfo)) != sizeof(ddqinfo))
return -1;
v2_disk2memdqinfo(&h->qh_info, &ddqinfo);
+
+ /* Check to make sure quota file info is sane */
+ info = &h->qh_info.u.v2_mdqi;
+ if (ext2fs_file_get_lsize(h->qh_qf.e2_file, &filesize))
+ return -1;
+ if ((filesize > (1U << 31)) ||
+ (info->dqi_qtree.dqi_blocks >
+ (filesize + QT_BLKSIZE - 1) >> QT_BLKSIZE_BITS)) {
+ log_err("Quota inode %u corrupted: file size %llu; "
+ "dqi_blocks %u", h->qh_qf.ino,
+ filesize, info->dqi_qtree.dqi_blocks);
+ return -1;
+ }
+ if (info->dqi_qtree.dqi_free_blk >= info->dqi_qtree.dqi_blocks) {
+ log_err("Quota inode %u corrupted: free_blk %u; dqi_blocks %u",
+ h->qh_qf.ino, info->dqi_qtree.dqi_free_blk,
+ info->dqi_qtree.dqi_blocks);
+ return -1;
+ }
+ if (info->dqi_qtree.dqi_free_entry >= info->dqi_qtree.dqi_blocks) {
+ log_err("Quota inode %u corrupted: free_entry %u; "
+ "dqi_blocks %u", h->qh_qf.ino,
+ info->dqi_qtree.dqi_free_entry,
+ info->dqi_qtree.dqi_blocks);
+ return -1;
+ }
return 0;
}
--
2.16.4

6
pre_checkin.sh Normal file
View File

@ -0,0 +1,6 @@
#!/bin/sh
sed -e 's/Name:.*/Name: e2fsprogs-mini/' \
-e 's/spec file for package.*/&-mini/' \
-e 's/%define.*build_mini.*/%define build_mini 1/' e2fsprogs.spec > e2fsprogs-mini.spec
cp e2fsprogs.changes e2fsprogs-mini.changes

View File

@ -0,0 +1,158 @@
From 4ed27a5bb9bfabaf437b45aaad315f028da5a6f1 Mon Sep 17 00:00:00 2001
From: Jan Kara <jack@suse.cz>
Date: Thu, 13 Feb 2020 11:16:01 +0100
Subject: [PATCH 4/5] tests: add test to excercise indexed directories with
metadata_csum
References: bsc#1160979
Indexed directories have somewhat different format when metadata_csum is
enabled. Add test to excercise linking in indexed directories and e2fsck
rehash code in this case.
Reviewed-by: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
---
tests/f_large_dir_csum/expect | 32 ++++++++++++++
tests/f_large_dir_csum/is_slow_test | 0
tests/f_large_dir_csum/name | 1 +
tests/f_large_dir_csum/script | 84 +++++++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+)
create mode 100644 tests/f_large_dir_csum/expect
create mode 100644 tests/f_large_dir_csum/is_slow_test
create mode 100644 tests/f_large_dir_csum/name
create mode 100644 tests/f_large_dir_csum/script
Index: e2fsprogs-1.43.8/tests/f_large_dir_csum/expect
===================================================================
--- /dev/null
+++ e2fsprogs-1.43.8/tests/f_large_dir_csum/expect
@@ -0,0 +1,32 @@
+Creating filesystem with 30996 1k blocks and 64 inodes
+Superblock backups stored on blocks:
+ 8193, 24577
+
+Allocating group tables: done
+Writing inode tables: done
+Writing superblocks and filesystem accounting information: done
+
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 3A: Optimizing directories
+Pass 4: Checking reference counts
+Inode 13 ref count is 1, should be 5. Fix? yes
+
+Pass 5: Checking group summary information
+
+test.img: ***** FILE SYSTEM WAS MODIFIED *****
+test.img: 13/64 files (0.0% non-contiguous), 766/30996 blocks
+Exit status is 1
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 3A: Optimizing directories
+Pass 4: Checking reference counts
+Inode 13 ref count is 5, should be 15499. Fix? yes
+
+Pass 5: Checking group summary information
+
+test.img: ***** FILE SYSTEM WAS MODIFIED *****
+test.img: 13/64 files (0.0% non-contiguous), 5971/30996 blocks
+Exit status is 1
Index: e2fsprogs-1.43.8/tests/f_large_dir_csum/name
===================================================================
--- /dev/null
+++ e2fsprogs-1.43.8/tests/f_large_dir_csum/name
@@ -0,0 +1 @@
+optimize 3 level htree directories with metadata checksums
Index: e2fsprogs-1.43.8/tests/f_large_dir_csum/script
===================================================================
--- /dev/null
+++ e2fsprogs-1.43.8/tests/f_large_dir_csum/script
@@ -0,0 +1,84 @@
+OUT=$test_name.log
+EXP=$test_dir/expect
+E2FSCK=../e2fsck/e2fsck
+
+NAMELEN=255
+DIRENT_SZ=8
+BLOCKSZ=1024
+INODESZ=128
+CSUM_SZ=8
+CSUM_TAIL_SZ=12
+DIRENT_PER_LEAF=$(((BLOCKSZ - CSUM_TAIL_SZ) / (NAMELEN + DIRENT_SZ)))
+HEADER=32
+INDEX_SZ=8
+INDEX_L1=$(((BLOCKSZ - HEADER - CSUM_SZ) / INDEX_SZ))
+INDEX_L2=$(((BLOCKSZ - DIRENT_SZ - CSUM_SZ) / INDEX_SZ))
+DIRBLK=$((INDEX_L1 * INDEX_L2))
+ENTRIES=$((DIRBLK * DIRENT_PER_LEAF / 3))
+# directory leaf blocks - get twice as much because the leaves won't be full
+# and there are also other filesystem blocks.
+FSIZE=$((DIRBLK * 2))
+
+$MKE2FS -b 1024 -O extents,64bit,uninit_bg,metadata_csum -N 50 \
+ -I $INODESZ -F $TMPFILE $FSIZE > $OUT.new 2>&1
+RC=$?
+if [ $RC -eq 0 ]; then
+{
+ # First some initial fs setup to create indexed dir
+ echo "mkdir /foo"
+ echo "cd /foo"
+ touch $TMPFILE.tmp
+ echo "write $TMPFILE.tmp foofile"
+ i=0
+ while test $i -lt $DIRENT_PER_LEAF ; do
+ printf "ln foofile f%0254u\n" $i
+ i=$((i + 1));
+ done
+ echo "expand ./"
+ printf "ln foofile f%0254u\n" $i
+} | $DEBUGFS -w $TMPFILE > /dev/null 2>> $OUT.new
+ RC=$?
+ # e2fsck should optimize the dir to become indexed
+ $E2FSCK -yfD $TMPFILE >> $OUT.new 2>&1
+ status=$?
+ echo Exit status is $status >> $OUT.new
+fi
+
+if [ $RC -eq 0 ]; then
+{
+ START=$SECONDS
+ i=$(($DIRENT_PER_LEAF+1))
+ last=$i
+ echo "cd /foo"
+ while test $i -lt $ENTRIES ; do
+ ELAPSED=$((SECONDS - START))
+ if test $((i % 5000)) -eq 0 -a $ELAPSED -gt 10; then
+ RATE=$(((i - last) / ELAPSED))
+ echo "$test_name: $i/$ENTRIES links, ${ELAPSED}s @ $RATE/s" >&2
+ START=$SECONDS
+ last=$i
+ fi
+ printf "ln foofile f%0254u\n" $i
+ i=$((i + 1))
+ done
+} | $DEBUGFS -w $TMPFILE > /dev/null 2>> $OUT.new
+ RC=$?
+fi
+
+if [ $RC -eq 0 ]; then
+ $E2FSCK -yfD $TMPFILE >> $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
+
+ cmp -s $OUT $EXP
+ RC=$?
+fi
+if [ $RC -eq 0 ]; then
+ echo "$test_name: $test_description: ok"
+ touch $test_name.ok
+else
+ echo "$test_name: $test_description: failed"
+ diff -u $EXP $OUT > $test_name.failed
+fi

View File

@ -0,0 +1,391 @@
From 514fde0296c2085fb11685820f3d396d5c41026e Mon Sep 17 00:00:00 2001
From: Jan Kara <jack@suse.cz>
Date: Thu, 13 Feb 2020 11:16:02 +0100
Subject: [PATCH 5/5] tune2fs: update dir checksums when clearing dir_index
feature
References: bsc#1160979
When clearing dir_index feature while metadata_csum is enabled, we have
to rewrite checksums of all indexed directories to update checksums of
internal tree nodes.
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Acked-by: Jan Kara <jack@suse.cz>
---
misc/tune2fs.c | 143 ++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 95 insertions(+), 48 deletions(-)
Index: e2fsprogs-1.43.8/misc/tune2fs.c
===================================================================
--- e2fsprogs-1.43.8.orig/misc/tune2fs.c
+++ e2fsprogs-1.43.8/misc/tune2fs.c
@@ -553,7 +553,8 @@ struct rewrite_dir_context {
char *buf;
errcode_t errcode;
ext2_ino_t dir;
- int is_htree;
+ int is_htree:1;
+ int clear_htree:1;
};
static int rewrite_dir_block(ext2_filsys fs,
@@ -572,8 +573,13 @@ static int rewrite_dir_block(ext2_filsys
if (ctx->errcode)
return BLOCK_ABORT;
- /* if htree node... */
- if (ctx->is_htree)
+ /*
+ * if htree node... Note that if we are clearing htree structures from
+ * the directory, we treat the htree internal block as an ordinary leaf.
+ * The code below will do the right thing and make space for checksum
+ * there.
+ */
+ if (ctx->is_htree && !ctx->clear_htree)
ext2fs_get_dx_countlimit(fs, (struct ext2_dir_entry *)ctx->buf,
&dcl, &dcl_offset);
if (dcl) {
@@ -702,7 +708,8 @@ static errcode_t rewrite_directory(ext2_
if (retval)
return retval;
- ctx.is_htree = (inode->i_flags & EXT2_INDEX_FL);
+ ctx.is_htree = !!(inode->i_flags & EXT2_INDEX_FL);
+ ctx.clear_htree = !ext2fs_has_feature_dir_index(fs->super);
ctx.dir = dir;
ctx.errcode = 0;
retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_READ_ONLY |
@@ -713,121 +720,169 @@ static errcode_t rewrite_directory(ext2_
if (retval)
return retval;
+ if (ctx.is_htree && ctx.clear_htree) {
+ inode->i_flags &= ~EXT2_INDEX_FL;
+ retval = ext2fs_write_inode(fs, dir, inode);
+ if (retval)
+ return retval;
+ }
+
return ctx.errcode;
}
-/*
- * Forcibly set checksums in all inodes.
- */
-static void rewrite_inodes(ext2_filsys fs)
+struct rewrite_context {
+ ext2_filsys fs;
+ struct ext2_inode *zero_inode;
+ char *ea_buf;
+ int inode_size;
+};
+
+static void rewrite_one_inode(struct rewrite_context *ctx, ext2_ino_t ino,
+ struct ext2_inode *inode)
{
- int length = EXT2_INODE_SIZE(fs->super);
- struct ext2_inode *inode, *zero;
- char *ea_buf;
- ext2_inode_scan scan;
- errcode_t retval;
- ext2_ino_t ino;
- blk64_t file_acl_block;
- int inode_dirty;
+ ext2_filsys fs = ctx->fs;
+ int inode_dirty;
+ errcode_t retval;
+ blk64_t file_acl_block;
- if (fs->super->s_creator_os == EXT2_OS_HURD)
- return;
+ if (ext2fs_test_inode_bitmap2(fs->inode_map, ino)) {
+ inode_dirty = 1;
+ } else {
+ if (memcmp(inode, ctx->zero_inode, ctx->inode_size) != 0) {
+ memset(inode, 0, ctx->inode_size);
+ inode_dirty = 1;
+ } else {
+ inode_dirty = 0;
+ }
+ }
- retval = ext2fs_open_inode_scan(fs, 0, &scan);
+ if (inode_dirty) {
+ retval = ext2fs_write_inode_full(fs, ino, inode,
+ ctx->inode_size);
+ if (retval) {
+ com_err("set_csum", retval, "while writing "
+ "inode");
+ exit(1);
+ }
+ }
+
+ retval = rewrite_extents(fs, ino, inode);
if (retval) {
- com_err("set_csum", retval, "while opening inode scan");
+ com_err("rewrite_extents", retval,
+ "while rewriting extents");
exit(1);
}
- retval = ext2fs_get_mem(length, &inode);
+ if (LINUX_S_ISDIR(inode->i_mode) &&
+ ext2fs_inode_has_valid_blocks2(fs, inode)) {
+ retval = rewrite_directory(fs, ino, inode);
+ if (retval) {
+ com_err("rewrite_directory", retval,
+ "while rewriting directories");
+ exit(1);
+ }
+ }
+
+ file_acl_block = ext2fs_file_acl_block(fs, inode);
+ if (!file_acl_block)
+ return;
+ retval = ext2fs_read_ext_attr3(fs, file_acl_block, ctx->ea_buf, ino);
if (retval) {
- com_err("set_csum", retval, "while allocating memory");
+ com_err("rewrite_eablock", retval,
+ "while rewriting extended attribute");
+ exit(1);
+ }
+ retval = ext2fs_write_ext_attr3(fs, file_acl_block, ctx->ea_buf,
+ ino);
+ if (retval) {
+ com_err("rewrite_eablock", retval,
+ "while rewriting extended attribute");
exit(1);
}
+}
+
+#define REWRITE_DIR_FL 0x02 /* Rewrite directories */
+#define REWRITE_NONDIR_FL 0x04 /* Rewrite other inodes */
+#define REWRITE_ALL (REWRITE_DIR_FL | REWRITE_NONDIR_FL)
+
+static void rewrite_inodes_pass(struct rewrite_context *ctx, unsigned int flags)
+{
+ ext2_filsys fs = ctx->fs;
+ struct ext2_inode *inode;
+ ext2_inode_scan scan;
+ errcode_t retval;
+ ext2_ino_t ino;
+ int rewrite;
- retval = ext2fs_get_memzero(length, &zero);
+ if (fs->super->s_creator_os == EXT2_OS_HURD)
+ return;
+
+ retval = ext2fs_open_inode_scan(fs, 0, &scan);
if (retval) {
- com_err("set_csum", retval, "while allocating memory");
+ com_err("set_csum", retval, "while opening inode scan");
exit(1);
}
- retval = ext2fs_get_mem(fs->blocksize, &ea_buf);
+ retval = ext2fs_get_mem(ctx->inode_size, &inode);
if (retval) {
com_err("set_csum", retval, "while allocating memory");
exit(1);
}
do {
- retval = ext2fs_get_next_inode_full(scan, &ino, inode, length);
+ retval = ext2fs_get_next_inode_full(scan, &ino, inode, ctx->inode_size);
if (retval) {
com_err("set_csum", retval, "while getting next inode");
exit(1);
}
if (!ino)
break;
- if (ext2fs_test_inode_bitmap2(fs->inode_map, ino)) {
- inode_dirty = 1;
+ rewrite = 0;
+ if (LINUX_S_ISDIR(inode->i_mode)) {
+ if (flags & REWRITE_DIR_FL)
+ rewrite = 1;
} else {
- if (memcmp(inode, zero, length) != 0) {
- memset(inode, 0, length);
- inode_dirty = 1;
- } else {
- inode_dirty = 0;
- }
+ if (flags & REWRITE_NONDIR_FL)
+ rewrite = 1;
}
+ if (rewrite)
+ rewrite_one_inode(ctx, ino, inode);
+ } while (ino);
- if (inode_dirty) {
- retval = ext2fs_write_inode_full(fs, ino, inode,
- length);
- if (retval) {
- com_err("set_csum", retval, "while writing "
- "inode");
- exit(1);
- }
- }
+ ext2fs_free_mem(&inode);
+ ext2fs_close_inode_scan(scan);
+}
- retval = rewrite_extents(fs, ino, inode);
- if (retval) {
- com_err("rewrite_extents", retval,
- "while rewriting extents");
- exit(1);
- }
+/*
+ * Forcibly rewrite checksums in inodes specified by 'flags'
+ */
+static void rewrite_inodes(ext2_filsys fs, unsigned int flags)
+{
+ struct rewrite_context ctx = {
+ .fs = fs,
+ .inode_size = EXT2_INODE_SIZE(fs->super),
+ };
+ errcode_t retval;
- if (LINUX_S_ISDIR(inode->i_mode) &&
- ext2fs_inode_has_valid_blocks2(fs, inode)) {
- retval = rewrite_directory(fs, ino, inode);
- if (retval) {
- com_err("rewrite_directory", retval,
- "while rewriting directories");
- exit(1);
- }
- }
+ retval = ext2fs_get_memzero(ctx.inode_size, &ctx.zero_inode);
+ if (retval) {
+ com_err("set_csum", retval, "while allocating memory");
+ exit(1);
+ }
- file_acl_block = ext2fs_file_acl_block(fs, inode);
- if (!file_acl_block)
- continue;
- retval = ext2fs_read_ext_attr3(fs, file_acl_block, ea_buf, ino);
- if (retval) {
- com_err("rewrite_eablock", retval,
- "while rewriting extended attribute");
- exit(1);
- }
- retval = ext2fs_write_ext_attr3(fs, file_acl_block, ea_buf,
- ino);
- if (retval) {
- com_err("rewrite_eablock", retval,
- "while rewriting extended attribute");
- exit(1);
- }
- } while (ino);
+ retval = ext2fs_get_mem(fs->blocksize, &ctx.ea_buf);
+ if (retval) {
+ com_err("set_csum", retval, "while allocating memory");
+ exit(1);
+ }
- ext2fs_free_mem(&zero);
- ext2fs_free_mem(&inode);
- ext2fs_free_mem(&ea_buf);
- ext2fs_close_inode_scan(scan);
+ rewrite_inodes_pass(&ctx, flags);
+
+ ext2fs_free_mem(&ctx.zero_inode);
+ ext2fs_free_mem(&ctx.ea_buf);
}
-static void rewrite_metadata_checksums(ext2_filsys fs)
+static void rewrite_metadata_checksums(ext2_filsys fs, unsigned int flags)
{
errcode_t retval;
dgrp_t i;
@@ -842,7 +897,7 @@ static void rewrite_metadata_checksums(e
"while reading bitmaps");
exit(1);
}
- rewrite_inodes(fs);
+ rewrite_inodes(fs, flags);
ext2fs_mark_ib_dirty(fs);
ext2fs_mark_bb_dirty(fs);
ext2fs_mmp_update2(fs, 1);
@@ -1141,6 +1196,23 @@ mmp_error:
uuid_generate((unsigned char *) sb->s_hash_seed);
}
+ if (FEATURE_OFF(E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX) &&
+ ext2fs_has_feature_metadata_csum(sb)) {
+ check_fsck_needed(fs,
+ _("Disabling directory index on filesystem with "
+ "checksums could take some time."));
+ if (mount_flags & EXT2_MF_MOUNTED) {
+ fputs(_("Cannot disable dir_index on a mounted "
+ "filesystem!\n"), stderr);
+ exit(1);
+ }
+ /*
+ * Clearing dir_index on checksummed filesystem requires
+ * rewriting all directories to update checksums.
+ */
+ rewrite_checksums |= REWRITE_DIR_FL;
+ }
+
if (FEATURE_OFF(E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
if (ext2fs_check_desc(fs)) {
fputs(_("Clearing the flex_bg flag would "
@@ -1184,7 +1256,7 @@ mmp_error:
"The larger fields afforded by this feature "
"enable full-strength checksumming. "
"Run resize2fs -b to rectify.\n"));
- rewrite_checksums = 1;
+ rewrite_checksums = REWRITE_ALL;
/* metadata_csum supersedes uninit_bg */
ext2fs_clear_feature_gdt_csum(fs->super);
@@ -1212,7 +1284,7 @@ mmp_error:
"filesystem!\n"), stderr);
exit(1);
}
- rewrite_checksums = 1;
+ rewrite_checksums = REWRITE_ALL;
/* Enable uninit_bg unless the user expressly turned it off */
memcpy(test_features, old_features, sizeof(test_features));
@@ -1375,7 +1447,7 @@ mmp_error:
return 1;
}
- rewrite_checksums = 1;
+ rewrite_checksums = REWRITE_ALL;
}
if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
@@ -3148,7 +3220,7 @@ retry_open:
ext2fs_mark_super_dirty(fs);
if (ext2fs_has_feature_metadata_csum(fs->super) &&
!ext2fs_has_feature_csum_seed(fs->super))
- rewrite_checksums = 1;
+ rewrite_checksums = REWRITE_ALL;
}
if (I_flag) {
@@ -3180,7 +3252,7 @@ retry_open:
if (retval == 0) {
printf(_("Setting inode size %lu\n"),
new_inode_size);
- rewrite_checksums = 1;
+ rewrite_checksums = REWRITE_ALL;
} else {
printf("%s", _("Failed to change inode size\n"));
rc = 1;
@@ -3189,7 +3261,7 @@ retry_open:
}
if (rewrite_checksums)
- rewrite_metadata_checksums(fs);
+ rewrite_metadata_checksums(fs, rewrite_checksums);
if (l_flag)
list_super(sb);