From: Theodore Ts'o Date: Mon, 9 Jun 2025 22:22:39 +0000 (-0400) Subject: debian: update debian/patches with for bugfix e2fsprogs release X-Git-Tag: archive/debian/1.47.2-2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7851fd04563010909f7d995d871dd56ca2554394;p=thirdparty%2Fe2fsprogs.git debian: update debian/patches with for bugfix e2fsprogs release Signed-off-by: Theodore Ts'o --- diff --git a/debian/patches/0001-e2fsck-fix-logic-bug-when-there-are-no-references-to.patch b/debian/patches/0001-e2fsck-fix-logic-bug-when-there-are-no-references-to.patch new file mode 100644 index 00000000..e60bd312 --- /dev/null +++ b/debian/patches/0001-e2fsck-fix-logic-bug-when-there-are-no-references-to.patch @@ -0,0 +1,36 @@ +From: Theodore Ts'o +Subject: e2fsck: fix logic bug when there are no references to an EA inode + +There was a boolean logic error which, among other things, could cause +an attempt to modify an inode in e2fsck -n mode: + +e2fsck 1.47.2 (1-Jan-2025) +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +ext2fs_write_inode: Attempt to write to filesystem opened read-only while writing inode 14 in pass4 +e2fsck: aborted + +Fixes: 849a9e6e133a ("e2fsck: add more checks for ea inode consistency") +Origin: https://github.com/tytso/e2fsprogs/commit/92b6e93936d7a0f6d7ce7a9f142e2c0ee9afbeaf +--- + e2fsck/pass4.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c +index cf0cf7c47..cee3be64b 100644 +--- a/e2fsck/pass4.c ++++ b/e2fsck/pass4.c +@@ -120,7 +120,7 @@ static void check_ea_inode(e2fsck_t ctx, ext2_ino_t i, ext2_ino_t *last_ino, + * will get attached to lost+found so clear EA_INODE_FL. + * Otherwise this is likely a spuriously set flag so clear it. + */ +- if (*link_counted == 0 || ++ if (*link_counted == 0 && + fix_problem(ctx, PR_4_EA_INODE_SPURIOUS_FLAG, &pctx)) { + /* Clear EA_INODE_FL (likely a normal file) */ + inode->i_flags &= ~EXT4_EA_INODE_FL; +-- +2.47.2 + diff --git a/debian/patches/0002-test-fix-expect-files-which-changed-after-EA-bugfix.patch b/debian/patches/0002-test-fix-expect-files-which-changed-after-EA-bugfix.patch new file mode 100644 index 00000000..be064861 --- /dev/null +++ b/debian/patches/0002-test-fix-expect-files-which-changed-after-EA-bugfix.patch @@ -0,0 +1,44 @@ +From: Theodore Ts'o +Subject: test: fix expect files which changed after EA bugfix + +The logic bug which was fixed in commit 92b6e93936d7 ("e2fsck: fix +logic bug when there are no references...") resulted in some silent +fixes that were never logged, and in some cases, corruption that was +not cleaned up. Fix the tests so that they pass as expected. + +Fixes: 92b6e93936d7 ("e2fsck: fix logic bug when there are no references..." +Origin: https://github.com/tytso/e2fsprogs/commit/ddd4f796d9dfdb80e5639ca8411e8e4891d3c7f1 +--- + tests/f_ea_inode_disconnected/expect.1 | 2 ++ + tests/f_ea_inode_self_ref/expect.1 | 2 -- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/f_ea_inode_disconnected/expect.1 b/tests/f_ea_inode_disconnected/expect.1 +index afc77aea6..539dc5ef9 100644 +--- a/tests/f_ea_inode_disconnected/expect.1 ++++ b/tests/f_ea_inode_disconnected/expect.1 +@@ -2,6 +2,8 @@ Pass 1: Checking inodes, blocks, and sizes + Pass 2: Checking directory structure + Pass 3: Checking directory connectivity + Pass 4: Checking reference counts ++Regular filesystem inode 13 has EA_INODE flag set. Clear? yes ++ + Unattached inode 13 + Connect to /lost+found? yes + +diff --git a/tests/f_ea_inode_self_ref/expect.1 b/tests/f_ea_inode_self_ref/expect.1 +index 35bea1417..f94c04d96 100644 +--- a/tests/f_ea_inode_self_ref/expect.1 ++++ b/tests/f_ea_inode_self_ref/expect.1 +@@ -7,8 +7,6 @@ Clear? yes + Pass 2: Checking directory structure + Pass 3: Checking directory connectivity + Pass 4: Checking reference counts +-Regular filesystem inode 16 has EA_INODE flag set. Clear? yes +- + Pass 5: Checking group summary information + Block bitmap differences: -20 + Fix? yes +-- +2.47.2 + diff --git a/debian/patches/0003-libext2fs-teach-ext2fs_extent_set_bmap-to-update-ext.patch b/debian/patches/0003-libext2fs-teach-ext2fs_extent_set_bmap-to-update-ext.patch new file mode 100644 index 00000000..7709fbf5 --- /dev/null +++ b/debian/patches/0003-libext2fs-teach-ext2fs_extent_set_bmap-to-update-ext.patch @@ -0,0 +1,123 @@ +From: Theodore Ts'o +Subject: libext2fs: teach ext2fs_extent_set_bmap() to update extents more optimally + +When programs like resize2fs or e2fsck relocates all of the blocks in +an extent one at a time, the ext2fs_extent_set_bmap() works by +initially adding a new extent and then moving mapping from the old +extent to the new extent. For example: + +t=1 EXTENTS: (0-2) 1152-1154 + +t=2 EXTENTS: (0) 1136, (1-2) 1153-1154 + +t=3 EXTENTS: (0-1) 1136-1137, (2) 1154 + +Unfortunately, previously, when the last block is updated, the +resulting extent tree will have two extents instead of one, like this: + +t=4 EXTENTS: (0-1) 1136-1137, (2) 1138 + +With this commit, the resulting extent tree will be more optimally +represented with a single extent: + +t=4 EXTENTS: (0-2) 1136-1138 + +The optimization in this commit solves the prolem reproted at: +https://github.com/tytso/e2fsprogs/issues/146 + +In that case, the file had a very large, complex (fragmented) extent +tree, and resize2fs needed to relcate all of its blocks as part of a +off-line shrink, the lack of the optimization led to an extent block +overflowing, resulting in the old extent (the one which originally +mapped logical block 2507128 to physical block 389065080) and the new +extent landing in two different leaf blocks: + + 2/ 2 1/ 1 2507128 - 2507128 640097 - 640097 1 + 2/ 2 1/135 2507128 - 2507128 389065080 - 389065080 1 + +This resulted a corrupted extent tree block and data loss. + +Origin: https://github.com/tytso/e2fsprogs/commit/ea825a53bcb214de7356c2ebd8a10d005613bec3 +--- + lib/ext2fs/extent.c | 25 ++++++++++++++++++++++++- + tests/f_badcluster/expect | 8 ++++---- + 2 files changed, 28 insertions(+), 5 deletions(-) + +diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c +index 82e75ccd7..c4b95741e 100644 +--- a/lib/ext2fs/extent.c ++++ b/lib/ext2fs/extent.c +@@ -1444,8 +1444,31 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle, + printf("(re/un)mapping only block in extent\n"); + #endif + if (physical) { +- retval = ext2fs_extent_replace(handle, 0, &newextent); ++ if (has_prev && ++ (logical == (prev_extent.e_lblk + ++ prev_extent.e_len)) && ++ (physical == (prev_extent.e_pblk + ++ prev_extent.e_len)) && ++ (new_uninit == prev_uninit) && ++ ((int) prev_extent.e_len < max_len-1)) { ++ retval = ext2fs_extent_get(handle, ++ EXT2_EXTENT_PREV_LEAF, &prev_extent); ++ if (retval) ++ goto done; ++ prev_extent.e_len++; ++ retval = ext2fs_extent_replace(handle, 0, ++ &prev_extent); ++ retval = ext2fs_extent_get(handle, ++ EXT2_EXTENT_NEXT_LEAF, ++ &extent); ++ if (retval) ++ goto done; ++ goto delete_node; ++ ++ } else ++ retval = ext2fs_extent_replace(handle, 0, &newextent); + } else { ++ delete_node: + retval = ext2fs_extent_delete(handle, 0); + if (retval) + goto done; +diff --git a/tests/f_badcluster/expect b/tests/f_badcluster/expect +index b44e65d00..fe1c1718f 100644 +--- a/tests/f_badcluster/expect ++++ b/tests/f_badcluster/expect +@@ -119,7 +119,7 @@ ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014 + atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014 + mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014 + EXTENTS: +-(0-1):1136-1137, (2):1138 ++(0-2):1136-1138 + debugfs: stat /b + Inode: 13 Type: regular Mode: 0644 Flags: 0x80000 + Generation: 1117152158 Version: 0x00000001 +@@ -143,7 +143,7 @@ ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014 + atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014 + mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014 + EXTENTS: +-(0-1):1216-1217, (2):1218 ++(0-2):1216-1218 + debugfs: stat /d + Inode: 15 Type: regular Mode: 0644 Flags: 0x80000 + Generation: 1117152160 Version: 0x00000001 +@@ -178,7 +178,7 @@ ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014 + atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014 + mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014 + EXTENTS: +-(0):1232, (1):1233, (2):1234 ++(0-2):1232-1234 + debugfs: stat /g + Inode: 18 Type: regular Mode: 0644 Flags: 0x80000 + Generation: 1117152163 Version: 0x00000001 +@@ -190,5 +190,5 @@ ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014 + atime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014 + mtime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014 + EXTENTS: +-(0-2):1680-1682, (3):1683 ++(0-3):1680-1683 + debugfs: quit +-- +2.47.2 + diff --git a/debian/patches/0004-e2image.8-add-missing-comma.patch b/debian/patches/0004-e2image.8-add-missing-comma.patch new file mode 100644 index 00000000..90340a32 --- /dev/null +++ b/debian/patches/0004-e2image.8-add-missing-comma.patch @@ -0,0 +1,21 @@ +From: Jakub Wilk +Subject: e2image.8: add missing comma +Origin: https://github.com/tytso/e2fsprogs/commit/5a6ec683252be78ccda7dec7dac530f2ebc46ce6 +--- + misc/e2image.8.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/misc/e2image.8.in b/misc/e2image.8.in +index 384ef3023..0be1c751e 100644 +--- a/misc/e2image.8.in ++++ b/misc/e2image.8.in +@@ -326,5 +326,5 @@ http://e2fsprogs.sourceforge.net. + + .SH SEE ALSO + .BR dumpe2fs (8), +-.BR debugfs (8) ++.BR debugfs (8), + .BR e2fsck (8) +-- +2.47.2 + diff --git a/debian/patches/0005-debugfs-byteswap-dirsearch-dirent-buf-on-big-endian-.patch b/debian/patches/0005-debugfs-byteswap-dirsearch-dirent-buf-on-big-endian-.patch new file mode 100644 index 00000000..487bd56b --- /dev/null +++ b/debian/patches/0005-debugfs-byteswap-dirsearch-dirent-buf-on-big-endian-.patch @@ -0,0 +1,40 @@ +From: Brian Foster +Subject: debugfs: byteswap dirsearch dirent buf on big endian systems + +fstests test ext4/048 fails on big endian systems due to broken +debugfs dirsearch functionality. On an s390x system and 4k block +size, the dirsearch command seems to hang indefinitely. On the same +system with a 1k block size, the command fails to locate an existing +entry and causes the test to fail due to unexpected results. + +The cause of the dirsearch failure is lack of byte swapping of the +on-disk (little endian) dirent buffer before attempting to iterate +entries in the given block. This leads to garbage record and name +length values, for example. To resolve this problem, byte swap the +directory buffer on big endian systems. + +Origin: https://github.com/tytso/e2fsprogs/commit/4be42019388d76c933e3b2ea80284aaf5b8eaecb +--- + debugfs/htree.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/debugfs/htree.c b/debugfs/htree.c +index a10081507..4ea8f30b3 100644 +--- a/debugfs/htree.c ++++ b/debugfs/htree.c +@@ -482,6 +482,12 @@ static int search_dir_block(ext2_filsys fs, blk64_t *blocknr, + return BLOCK_ABORT; + } + ++#ifdef WORDS_BIGENDIAN ++ errcode = ext2fs_dirent_swab_in(fs, p->buf, 0); ++ if (errcode) ++ return BLOCK_ABORT; ++#endif ++ + while (offset < fs->blocksize) { + dirent = (struct ext2_dir_entry *) (p->buf + offset); + errcode = ext2fs_get_rec_len(fs, dirent, &rec_len); +-- +2.47.2 + diff --git a/debian/patches/0006-fuse2fs-refuse-unsupported-features.patch b/debian/patches/0006-fuse2fs-refuse-unsupported-features.patch new file mode 100644 index 00000000..29b01045 --- /dev/null +++ b/debian/patches/0006-fuse2fs-refuse-unsupported-features.patch @@ -0,0 +1,45 @@ +From: "Darrick J. Wong" +Subject: fuse2fs: refuse unsupported features + +Don't mount a filesystem with superblock features that we don't actually +know how to support. + +Origin: https://github.com/tytso/e2fsprogs/commit/ccbc6f24fed095b28f9faa7b575159e49787fae0 +--- + misc/fuse2fs.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c +index a6390ab5d..2e0463201 100644 +--- a/misc/fuse2fs.c ++++ b/misc/fuse2fs.c +@@ -3863,6 +3863,26 @@ int main(int argc, char *argv[]) + + ret = 3; + ++ if (ext2fs_has_feature_quota(global_fs->super)) { ++ printf(_("%s: quotas not supported."), fctx.device); ++ goto out; ++ } ++ if (ext2fs_has_feature_verity(global_fs->super)) { ++ printf(_("%s: verity not supported."), fctx.device); ++ goto out; ++ } ++ if (ext2fs_has_feature_encrypt(global_fs->super)) { ++ printf(_("%s: encryption not supported."), fctx.device); ++ goto out; ++ } ++ if (ext2fs_has_feature_casefold(global_fs->super)) { ++ printf(_("%s: casefolding not supported."), fctx.device); ++ goto out; ++ } ++ ++ if (ext2fs_has_feature_shared_blocks(global_fs->super)) ++ fctx.ro = 1; ++ + if (ext2fs_has_feature_journal_needs_recovery(global_fs->super)) { + if (fctx.norecovery) { + printf(_("%s: mounting read-only without " +-- +2.47.2 + diff --git a/debian/patches/0007-fuse2fs-return-EOPNOTSUPP-when-we-don-t-recognize-a-.patch b/debian/patches/0007-fuse2fs-return-EOPNOTSUPP-when-we-don-t-recognize-a-.patch new file mode 100644 index 00000000..19c912d6 --- /dev/null +++ b/debian/patches/0007-fuse2fs-return-EOPNOTSUPP-when-we-don-t-recognize-a-.patch @@ -0,0 +1,28 @@ +From: "Darrick J. Wong" +Subject: fuse2fs: return -EOPNOTSUPP when we don't recognize a fallocate mode + +If we don't recognize a set bit in the mode parameter to fallocate, +return EOPNOTSUPP to communicate that we don't support that mode instead +of EINVAL. This avoids unnecessary failures in generic/521. + +Origin: https://github.com/tytso/e2fsprogs/commit/7775293c08d2255e90b1e003ee532d826af52d95 +--- + misc/fuse2fs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c +index 2e0463201..1ec7cd22f 100644 +--- a/misc/fuse2fs.c ++++ b/misc/fuse2fs.c +@@ -3616,7 +3616,7 @@ static int op_fallocate(const char *path EXT2FS_ATTR((unused)), int mode, + + /* Catch unknown flags */ + if (mode & ~(FL_PUNCH_HOLE_FLAG | FL_KEEP_SIZE_FLAG)) +- return -EINVAL; ++ return -EOPNOTSUPP; + + pthread_mutex_lock(&ff->bfl); + if (!fs_writeable(fs)) { +-- +2.47.2 + diff --git a/debian/patches/0008-fuse2fs-remove-posix-acl-translation.patch b/debian/patches/0008-fuse2fs-remove-posix-acl-translation.patch new file mode 100644 index 00000000..c6bd91fc --- /dev/null +++ b/debian/patches/0008-fuse2fs-remove-posix-acl-translation.patch @@ -0,0 +1,347 @@ +From: "Darrick J. Wong" +Subject: fuse2fs: remove posix acl translation + +Remove the POSIX ACL format translation since libext2fs takes care of +that now. + +Fixes: 0ee1eaf70c257e ("libext2fs: translate internal ext4 acl to Posix ACL in ext2fs_xattr_[sg]et()") +Origin: https://github.com/tytso/e2fsprogs/commit/0111bdb70a9c460052387111414a2e2dc8c06822 +--- + misc/fuse2fs.c | 267 +------------------------------------------------ + 1 file changed, 4 insertions(+), 263 deletions(-) + +diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c +index 1ec7cd22f..eeb496d1b 100644 +--- a/misc/fuse2fs.c ++++ b/misc/fuse2fs.c +@@ -17,12 +17,6 @@ + # include + # include + # include +-# ifdef HAVE_SYS_ACL_H +-# define TRANSLATE_LINUX_ACLS +-# endif +-#endif +-#ifdef TRANSLATE_LINUX_ACLS +-# include + #endif + #include + #include +@@ -119,206 +113,6 @@ errcode_t ext2fs_run_ext3_journal(ext2_filsys *fs); + int journal_enable_debug = -1; + #endif + +-/* ACL translation stuff */ +-#ifdef TRANSLATE_LINUX_ACLS +-/* +- * Copied from acl_ea.h in libacl source; ACLs have to be sent to and from fuse +- * in this format... at least on Linux. +- */ +-#define ACL_EA_ACCESS "system.posix_acl_access" +-#define ACL_EA_DEFAULT "system.posix_acl_default" +- +-#define ACL_EA_VERSION 0x0002 +- +-typedef struct { +- u_int16_t e_tag; +- u_int16_t e_perm; +- u_int32_t e_id; +-} acl_ea_entry; +- +-typedef struct { +- u_int32_t a_version; +-#if __GNUC_PREREQ (4, 8) +-#pragma GCC diagnostic push +-#pragma GCC diagnostic ignored "-Wpedantic" +-#endif +- acl_ea_entry a_entries[0]; +-#if __GNUC_PREREQ (4, 8) +-#pragma GCC diagnostic pop +-#endif +-} acl_ea_header; +- +-static inline size_t acl_ea_size(int count) +-{ +- return sizeof(acl_ea_header) + count * sizeof(acl_ea_entry); +-} +- +-static inline int acl_ea_count(size_t size) +-{ +- if (size < sizeof(acl_ea_header)) +- return -1; +- size -= sizeof(acl_ea_header); +- if (size % sizeof(acl_ea_entry)) +- return -1; +- return size / sizeof(acl_ea_entry); +-} +- +-/* +- * ext4 ACL structures, copied from fs/ext4/acl.h. +- */ +-#define EXT4_ACL_VERSION 0x0001 +- +-typedef struct { +- __u16 e_tag; +- __u16 e_perm; +- __u32 e_id; +-} ext4_acl_entry; +- +-typedef struct { +- __u16 e_tag; +- __u16 e_perm; +-} ext4_acl_entry_short; +- +-typedef struct { +- __u32 a_version; +-} ext4_acl_header; +- +-static inline size_t ext4_acl_size(int count) +-{ +- if (count <= 4) { +- return sizeof(ext4_acl_header) + +- count * sizeof(ext4_acl_entry_short); +- } else { +- return sizeof(ext4_acl_header) + +- 4 * sizeof(ext4_acl_entry_short) + +- (count - 4) * sizeof(ext4_acl_entry); +- } +-} +- +-static inline int ext4_acl_count(size_t size) +-{ +- ssize_t s; +- +- size -= sizeof(ext4_acl_header); +- s = size - 4 * sizeof(ext4_acl_entry_short); +- if (s < 0) { +- if (size % sizeof(ext4_acl_entry_short)) +- return -1; +- return size / sizeof(ext4_acl_entry_short); +- } +- if (s % sizeof(ext4_acl_entry)) +- return -1; +- return s / sizeof(ext4_acl_entry) + 4; +-} +- +-static errcode_t fuse_to_ext4_acl(acl_ea_header *facl, size_t facl_sz, +- ext4_acl_header **eacl, size_t *eacl_sz) +-{ +- int i, facl_count; +- ext4_acl_header *h; +- size_t h_sz; +- ext4_acl_entry *e; +- acl_ea_entry *a; +- unsigned char *hptr; +- errcode_t err; +- +- facl_count = acl_ea_count(facl_sz); +- h_sz = ext4_acl_size(facl_count); +- if (facl_count < 0 || facl->a_version != ACL_EA_VERSION) +- return EXT2_ET_INVALID_ARGUMENT; +- +- err = ext2fs_get_mem(h_sz, &h); +- if (err) +- return err; +- +- h->a_version = ext2fs_cpu_to_le32(EXT4_ACL_VERSION); +- hptr = (unsigned char *) (h + 1); +- for (i = 0, a = facl->a_entries; i < facl_count; i++, a++) { +- e = (ext4_acl_entry *) hptr; +- e->e_tag = ext2fs_cpu_to_le16(a->e_tag); +- e->e_perm = ext2fs_cpu_to_le16(a->e_perm); +- +- switch (a->e_tag) { +- case ACL_USER: +- case ACL_GROUP: +- e->e_id = ext2fs_cpu_to_le32(a->e_id); +- hptr += sizeof(ext4_acl_entry); +- break; +- case ACL_USER_OBJ: +- case ACL_GROUP_OBJ: +- case ACL_MASK: +- case ACL_OTHER: +- hptr += sizeof(ext4_acl_entry_short); +- break; +- default: +- err = EXT2_ET_INVALID_ARGUMENT; +- goto out; +- } +- } +- +- *eacl = h; +- *eacl_sz = h_sz; +- return err; +-out: +- ext2fs_free_mem(&h); +- return err; +-} +- +-static errcode_t ext4_to_fuse_acl(acl_ea_header **facl, size_t *facl_sz, +- ext4_acl_header *eacl, size_t eacl_sz) +-{ +- int i, eacl_count; +- acl_ea_header *f; +- ext4_acl_entry *e; +- acl_ea_entry *a; +- size_t f_sz; +- unsigned char *hptr; +- errcode_t err; +- +- eacl_count = ext4_acl_count(eacl_sz); +- f_sz = acl_ea_size(eacl_count); +- if (eacl_count < 0 || +- eacl->a_version != ext2fs_cpu_to_le32(EXT4_ACL_VERSION)) +- return EXT2_ET_INVALID_ARGUMENT; +- +- err = ext2fs_get_mem(f_sz, &f); +- if (err) +- return err; +- +- f->a_version = ACL_EA_VERSION; +- hptr = (unsigned char *) (eacl + 1); +- for (i = 0, a = f->a_entries; i < eacl_count; i++, a++) { +- e = (ext4_acl_entry *) hptr; +- a->e_tag = ext2fs_le16_to_cpu(e->e_tag); +- a->e_perm = ext2fs_le16_to_cpu(e->e_perm); +- +- switch (a->e_tag) { +- case ACL_USER: +- case ACL_GROUP: +- a->e_id = ext2fs_le32_to_cpu(e->e_id); +- hptr += sizeof(ext4_acl_entry); +- break; +- case ACL_USER_OBJ: +- case ACL_GROUP_OBJ: +- case ACL_MASK: +- case ACL_OTHER: +- hptr += sizeof(ext4_acl_entry_short); +- break; +- default: +- err = EXT2_ET_INVALID_ARGUMENT; +- goto out; +- } +- } +- +- *facl = f; +- *facl_sz = f_sz; +- return err; +-out: +- ext2fs_free_mem(&f); +- return err; +-} +-#endif /* TRANSLATE_LINUX_ACLS */ +- + /* + * ext2_file_t contains a struct inode, so we can't leave files open. + * Use this as a proxy instead. +@@ -2432,30 +2226,6 @@ static int op_statfs(const char *path EXT2FS_ATTR((unused)), + return 0; + } + +-typedef errcode_t (*xattr_xlate_get)(void **cooked_buf, size_t *cooked_sz, +- const void *raw_buf, size_t raw_sz); +-typedef errcode_t (*xattr_xlate_set)(const void *cooked_buf, size_t cooked_sz, +- const void **raw_buf, size_t *raw_sz); +-struct xattr_translate { +- const char *prefix; +- xattr_xlate_get get; +- xattr_xlate_set set; +-}; +- +-#define XATTR_TRANSLATOR(p, g, s) \ +- {.prefix = (p), \ +- .get = (xattr_xlate_get)(g), \ +- .set = (xattr_xlate_set)(s)} +- +-static struct xattr_translate xattr_translators[] = { +-#ifdef TRANSLATE_LINUX_ACLS +- XATTR_TRANSLATOR(ACL_EA_ACCESS, ext4_to_fuse_acl, fuse_to_ext4_acl), +- XATTR_TRANSLATOR(ACL_EA_DEFAULT, ext4_to_fuse_acl, fuse_to_ext4_acl), +-#endif +- XATTR_TRANSLATOR(NULL, NULL, NULL), +-}; +-#undef XATTR_TRANSLATOR +- + static int op_getxattr(const char *path, const char *key, char *value, + size_t len) + { +@@ -2463,9 +2233,8 @@ static int op_getxattr(const char *path, const char *key, char *value, + struct fuse2fs *ff = (struct fuse2fs *)ctxt->private_data; + ext2_filsys fs; + struct ext2_xattr_handle *h; +- struct xattr_translate *xt; +- void *ptr, *cptr; +- size_t plen, clen; ++ void *ptr; ++ size_t plen; + ext2_ino_t ino; + errcode_t err; + int ret = 0; +@@ -2507,17 +2276,6 @@ static int op_getxattr(const char *path, const char *key, char *value, + goto out2; + } + +- for (xt = xattr_translators; xt->prefix != NULL; xt++) { +- if (strncmp(key, xt->prefix, strlen(xt->prefix)) == 0) { +- err = xt->get(&cptr, &clen, ptr, plen); +- if (err) +- goto out3; +- ext2fs_free_mem(&ptr); +- ptr = cptr; +- plen = clen; +- } +- } +- + if (!len) { + ret = plen; + } else if (len < plen) { +@@ -2527,7 +2285,6 @@ static int op_getxattr(const char *path, const char *key, char *value, + ret = plen; + } + +-out3: + ext2fs_free_mem(&ptr); + out2: + err = ext2fs_xattrs_close(&h); +@@ -2645,9 +2402,6 @@ static int op_setxattr(const char *path EXT2FS_ATTR((unused)), + struct fuse2fs *ff = (struct fuse2fs *)ctxt->private_data; + ext2_filsys fs; + struct ext2_xattr_handle *h; +- struct xattr_translate *xt; +- const void *cvalue; +- size_t clen; + ext2_ino_t ino; + errcode_t err; + int ret = 0; +@@ -2686,26 +2440,13 @@ static int op_setxattr(const char *path EXT2FS_ATTR((unused)), + goto out2; + } + +- cvalue = value; +- clen = len; +- for (xt = xattr_translators; xt->prefix != NULL; xt++) { +- if (strncmp(key, xt->prefix, strlen(xt->prefix)) == 0) { +- err = xt->set(value, len, &cvalue, &clen); +- if (err) +- goto out3; +- } +- } +- +- err = ext2fs_xattr_set(h, key, cvalue, clen); ++ err = ext2fs_xattr_set(h, key, value, len); + if (err) { + ret = translate_error(fs, ino, err); +- goto out3; ++ goto out2; + } + + ret = update_ctime(fs, ino, NULL); +-out3: +- if (cvalue != value) +- ext2fs_free_mem(&cvalue); + out2: + err = ext2fs_xattrs_close(&h); + if (!ret && err) +-- +2.47.2 + diff --git a/debian/patches/0009-fuse2fs-clamp-timestamps-that-are-being-written-to-d.patch b/debian/patches/0009-fuse2fs-clamp-timestamps-that-are-being-written-to-d.patch new file mode 100644 index 00000000..d00b7ccf --- /dev/null +++ b/debian/patches/0009-fuse2fs-clamp-timestamps-that-are-being-written-to-d.patch @@ -0,0 +1,107 @@ +From: "Darrick J. Wong" +Subject: fuse2fs: clamp timestamps that are being written to disk + +Clamp the timestamps that we write to disk to the minimum and maximum +values permitted given the ondisk format. This fixes y2038 support, as +tested by generic/402. + +Origin: https://github.com/tytso/e2fsprogs/commit/e13395876d63cebf008101b934ee9e5cdaae0150 +--- + lib/ext2fs/ext2_fs.h | 4 ++++ + misc/fuse2fs.c | 39 ++++++++++++++++++++++++++++++++------- + 2 files changed, 36 insertions(+), 7 deletions(-) + +diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h +index 3a5eb7387..fcd420556 100644 +--- a/lib/ext2fs/ext2_fs.h ++++ b/lib/ext2fs/ext2_fs.h +@@ -801,6 +801,10 @@ struct ext2_super_block { + + #define EXT2_GOOD_OLD_INODE_SIZE 128 + ++#define EXT4_EXTRA_TIMESTAMP_MAX (((int64_t)1 << 34) - 1 + INT32_MIN) ++#define EXT4_NON_EXTRA_TIMESTAMP_MAX INT32_MAX ++#define EXT4_TIMESTAMP_MIN INT32_MIN ++ + /* + * Journal inode backup types + */ +diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c +index eeb496d1b..238804dd4 100644 +--- a/misc/fuse2fs.c ++++ b/misc/fuse2fs.c +@@ -209,21 +209,43 @@ static inline void ext4_decode_extra_time(struct timespec *time, __u32 extra) + time->tv_nsec = ((extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS; + } + ++#define EXT4_CLAMP_TIMESTAMP(xtime, timespec, raw_inode) \ ++do { \ ++ if ((timespec)->tv_sec < EXT4_TIMESTAMP_MIN) \ ++ (timespec)->tv_sec = EXT4_TIMESTAMP_MIN; \ ++ if ((timespec)->tv_sec < EXT4_TIMESTAMP_MIN) \ ++ (timespec)->tv_sec = EXT4_TIMESTAMP_MIN; \ ++ \ ++ if (EXT4_FITS_IN_INODE(raw_inode, xtime ## _extra)) { \ ++ if ((timespec)->tv_sec > EXT4_EXTRA_TIMESTAMP_MAX) \ ++ (timespec)->tv_sec = EXT4_EXTRA_TIMESTAMP_MAX; \ ++ } else { \ ++ if ((timespec)->tv_sec > EXT4_NON_EXTRA_TIMESTAMP_MAX) \ ++ (timespec)->tv_sec = EXT4_NON_EXTRA_TIMESTAMP_MAX; \ ++ } \ ++} while (0) ++ + #define EXT4_INODE_SET_XTIME(xtime, timespec, raw_inode) \ + do { \ +- (raw_inode)->xtime = (timespec)->tv_sec; \ ++ typeof(*(timespec)) _ts = *(timespec); \ ++ \ ++ EXT4_CLAMP_TIMESTAMP(xtime, &_ts, raw_inode); \ ++ (raw_inode)->xtime = _ts.tv_sec; \ + if (EXT4_FITS_IN_INODE(raw_inode, xtime ## _extra)) \ + (raw_inode)->xtime ## _extra = \ +- ext4_encode_extra_time(timespec); \ ++ ext4_encode_extra_time(&_ts); \ + } while (0) + + #define EXT4_EINODE_SET_XTIME(xtime, timespec, raw_inode) \ + do { \ ++ typeof(*(timespec)) _ts = *(timespec); \ ++ \ ++ EXT4_CLAMP_TIMESTAMP(xtime, &_ts, raw_inode); \ + if (EXT4_FITS_IN_INODE(raw_inode, xtime)) \ +- (raw_inode)->xtime = (timespec)->tv_sec; \ ++ (raw_inode)->xtime = _ts.tv_sec; \ + if (EXT4_FITS_IN_INODE(raw_inode, xtime ## _extra)) \ + (raw_inode)->xtime ## _extra = \ +- ext4_encode_extra_time(timespec); \ ++ ext4_encode_extra_time(&_ts); \ + } while (0) + + #define EXT4_INODE_GET_XTIME(xtime, timespec, raw_inode) \ +@@ -2843,7 +2865,10 @@ static int op_utimens(const char *path, const struct timespec ctv[2] + ret = translate_error(fs, 0, err); + goto out; + } +- dbg_printf("%s: ino=%d\n", __func__, ino); ++ dbg_printf("%s: ino=%d atime=%lld.%ld mtime=%lld.%ld\n", __func__, ++ ino, ++ (long long int)ctv[0].tv_sec, ctv[0].tv_nsec, ++ (long long int)ctv[1].tv_sec, ctv[1].tv_nsec); + + ret = check_inum_access(fs, ino, W_OK); + if (ret) +@@ -2867,9 +2892,9 @@ static int op_utimens(const char *path, const struct timespec ctv[2] + #endif /* UTIME_NOW */ + #ifdef UTIME_OMIT + if (tv[0].tv_nsec != UTIME_OMIT) +- EXT4_INODE_SET_XTIME(i_atime, tv, &inode); ++ EXT4_INODE_SET_XTIME(i_atime, &tv[0], &inode); + if (tv[1].tv_nsec != UTIME_OMIT) +- EXT4_INODE_SET_XTIME(i_mtime, tv + 1, &inode); ++ EXT4_INODE_SET_XTIME(i_mtime, &tv[1], &inode); + #endif /* UTIME_OMIT */ + ret = update_ctime(fs, ino, &inode); + if (ret) +-- +2.47.2 + diff --git a/debian/patches/0010-fuse2fs-update-new-child-timestamps-during-mkdir-sym.patch b/debian/patches/0010-fuse2fs-update-new-child-timestamps-during-mkdir-sym.patch new file mode 100644 index 00000000..35de549f --- /dev/null +++ b/debian/patches/0010-fuse2fs-update-new-child-timestamps-during-mkdir-sym.patch @@ -0,0 +1,34 @@ +From: "Darrick J. Wong" +Subject: fuse2fs: update new child timestamps during mkdir/symlink + +These two file creation functions fail to update the timestamps of the +new child file, unlike the others (mknod/creat). Fix that. + +Origin: https://github.com/tytso/e2fsprogs/commit/f73fbf8e2cee1f2d49f4e7573eadb9f1cf141879 +--- + misc/fuse2fs.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c +index 238804dd4..d123eebb1 100644 +--- a/misc/fuse2fs.c ++++ b/misc/fuse2fs.c +@@ -976,6 +976,7 @@ static int op_mkdir(const char *path, mode_t mode) + inode.i_mode = LINUX_S_IFDIR | (mode & ~S_ISUID) | + parent_sgid; + inode.i_generation = ff->next_generation++; ++ init_times(&inode); + + err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode, + sizeof(inode)); +@@ -1349,6 +1350,7 @@ static int op_symlink(const char *src, const char *dest) + inode.i_gid = ctxt->gid; + ext2fs_set_i_gid_high(inode, ctxt->gid >> 16); + inode.i_generation = ff->next_generation++; ++ init_times(&inode); + + err = ext2fs_write_inode_full(fs, child, (struct ext2_inode *)&inode, + sizeof(inode)); +-- +2.47.2 + diff --git a/debian/patches/0011-fuse2fs-disable-renameat2.patch b/debian/patches/0011-fuse2fs-disable-renameat2.patch new file mode 100644 index 00000000..7d325bd5 --- /dev/null +++ b/debian/patches/0011-fuse2fs-disable-renameat2.patch @@ -0,0 +1,33 @@ +From: "Darrick J. Wong" +Subject: fuse2fs: disable renameat2 + +Apparently fuse munged rename and renameat2 together into the same +upcall, so we actually have to filter out nonzero flags because +otherwise we do a regular rename for a RENAME_EXCHANGE/WHITEOUT, which +is not what the user asked for. + +Origin: https://github.com/tytso/e2fsprogs/commit/b431abbc8fe0fd1de4e414aae3520c4c19411048 +--- + misc/fuse2fs.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c +index d123eebb1..36e1173e2 100644 +--- a/misc/fuse2fs.c ++++ b/misc/fuse2fs.c +@@ -1405,6 +1405,12 @@ static int op_rename(const char *from, const char *to + struct update_dotdot ud; + int ret = 0; + ++#if FUSE_VERSION >= FUSE_MAKE_VERSION(3, 0) ++ /* renameat2 is not supported */ ++ if (flags) ++ return -ENOSYS; ++#endif ++ + FUSE2FS_CHECK_CONTEXT(ff); + fs = ff->fs; + dbg_printf("%s: renaming %s to %s\n", __func__, from, to); +-- +2.47.2 + diff --git a/debian/patches/0012-debugfs-abort-reading-a-file-on-failure-when-dumping.patch b/debian/patches/0012-debugfs-abort-reading-a-file-on-failure-when-dumping.patch new file mode 100644 index 00000000..9962c1cc --- /dev/null +++ b/debian/patches/0012-debugfs-abort-reading-a-file-on-failure-when-dumping.patch @@ -0,0 +1,36 @@ +From: Theodore Ts'o +Subject: debugfs: abort reading a file on failure when dumping out a file + +If ext2fs_file_read() fails --- perhaps due to a corrupted file +system, or an I/O error --- avoid looping forever in dump_file(). + +This issue was pointed out in [1] by Quentin Kaiser but the commit +description was too confusing and specific to the user's particular +situation. + +[1] https://github.com/tytso/e2fsprogs/pull/149 + +Origin: https://github.com/tytso/e2fsprogs/commit/51d68472456d22b6e64159244be63bce51473691 +--- + debugfs/dump.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/debugfs/dump.c b/debugfs/dump.c +index 4ab7cadcb..cc81a5086 100644 +--- a/debugfs/dump.c ++++ b/debugfs/dump.c +@@ -122,8 +122,10 @@ static void dump_file(const char *cmdname, ext2_ino_t ino, int fd, + } + while (1) { + retval = ext2fs_file_read(e2_file, buf, blocksize, &got); +- if (retval) ++ if (retval) { + com_err(cmdname, retval, "while reading ext2 file"); ++ return; ++ } + if (got == 0) + break; + nbytes = write(fd, buf, got); +-- +2.47.2 + diff --git a/debian/patches/0013-mke2fs-disallow-O-verity-without-extents.patch b/debian/patches/0013-mke2fs-disallow-O-verity-without-extents.patch new file mode 100644 index 00000000..e94fd892 --- /dev/null +++ b/debian/patches/0013-mke2fs-disallow-O-verity-without-extents.patch @@ -0,0 +1,34 @@ +From: Allison Karlitskaya +Subject: mke2fs: disallow -O verity without extents + +Similar to 64-bit support, fs-verity support requires extents, so don't +allow to create a filesystem that has -O verity unless it also supports +extents. + +Origin: https://github.com/tytso/e2fsprogs/commit/03fa1a5ee55d0653f5931cea3cab760599bab216 +--- + misc/mke2fs.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/misc/mke2fs.c b/misc/mke2fs.c +index f24076bc1..017838d43 100644 +--- a/misc/mke2fs.c ++++ b/misc/mke2fs.c +@@ -2385,6 +2385,14 @@ profile_error: + exit(1); + } + ++ /* fs-verity support requires extents */ ++ if (ext2fs_has_feature_verity(&fs_param) && ++ !ext2fs_has_feature_extents(&fs_param)) { ++ printf("%s", _("Extents MUST be enabled for fs-verity " ++ "support. Pass -O extents to rectify.\n")); ++ exit(1); ++ } ++ + /* Set first meta blockgroup via an environment variable */ + /* (this is mostly for debugging purposes) */ + if (ext2fs_has_feature_meta_bg(&fs_param) && +-- +2.47.2 + diff --git a/debian/patches/0014-e2fsck-fix-e2fsck-E-unshare_blocks-when-there-are-no.patch b/debian/patches/0014-e2fsck-fix-e2fsck-E-unshare_blocks-when-there-are-no.patch new file mode 100644 index 00000000..215693b3 --- /dev/null +++ b/debian/patches/0014-e2fsck-fix-e2fsck-E-unshare_blocks-when-there-are-no.patch @@ -0,0 +1,33 @@ +From: Theodore Ts'o +Subject: e2fsck: fix e2fsck -E unshare_blocks when there are no shared blocks + +If there are no shared blocks in a ext4 file system, e2fsck -E +unshare_blocks will not actually clear the shared_blocks feature flag +since e2fsck_pass1_dupblocks() is never called. Fix this by adding a +check in e2fsck_pass1() to clear the shared blocks flag. + +Bug: https://github.com/tytso/e2fsprogs/issues/218 +Origin: https://github.com/tytso/e2fsprogs/commit/707af4359e132bc415c3f6339f4ced9f23b28c0b +--- + e2fsck/pass1.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c +index eb73922d3..e7d5d0ae9 100644 +--- a/e2fsck/pass1.c ++++ b/e2fsck/pass1.c +@@ -2169,6 +2169,11 @@ void e2fsck_pass1(e2fsck_t ctx) + fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx); + } + e2fsck_pass1_dupblocks(ctx, block_buf); ++ } else if ((ctx->options & E2F_OPT_UNSHARE_BLOCKS) && ++ ext2fs_has_feature_shared_blocks(fs->super) && ++ !(ctx->options & E2F_OPT_NO)) { ++ ext2fs_clear_feature_shared_blocks(fs->super); ++ ext2fs_mark_super_dirty(fs); + } + ctx->flags |= E2F_FLAG_ALLOC_OK; + endit: +-- +2.47.2 + diff --git a/debian/patches/0015-e2freefrag-require-that-the-chunksize-must-be-greate.patch b/debian/patches/0015-e2freefrag-require-that-the-chunksize-must-be-greate.patch new file mode 100644 index 00000000..bd6af948 --- /dev/null +++ b/debian/patches/0015-e2freefrag-require-that-the-chunksize-must-be-greate.patch @@ -0,0 +1,28 @@ +From: Theodore Ts'o +Subject: e2freefrag: require that the chunksize must be greater than 0 + +"e2freefrag -c 0" doesn't make much sense, so abort with an error +message if the user specifies a zero chunksize. + +Addresses-Coverity-Bug: 1633767 +Origin: https://github.com/tytso/e2fsprogs/commit/3e059df08de94abde1ddd82008d0658584a35e5e +--- + misc/e2freefrag.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/misc/e2freefrag.c b/misc/e2freefrag.c +index 63a3d4351..c66e8f22f 100644 +--- a/misc/e2freefrag.c ++++ b/misc/e2freefrag.c +@@ -405,7 +405,7 @@ int main(int argc, char *argv[]) + switch (c) { + case 'c': + chunk_info.chunkbytes = strtoull(optarg, &end, 0); +- if (*end != '\0') { ++ if (*end != '\0' || chunk_info.chunkbytes == 0) { + fprintf(stderr, "%s: bad chunk size '%s'\n", + progname, optarg); + usage(progname); +-- +2.47.2 + diff --git a/debian/patches/0016-mke2fs-add-range-checks-for-E-desc_size.patch b/debian/patches/0016-mke2fs-add-range-checks-for-E-desc_size.patch new file mode 100644 index 00000000..9f48511c --- /dev/null +++ b/debian/patches/0016-mke2fs-add-range-checks-for-E-desc_size.patch @@ -0,0 +1,30 @@ +From: Theodore Ts'o +Subject: mke2fs: add range checks for -E desc_size + +Prevent the user from specifying group descriptor that result in +invalid/corrupted file systems. + +Origin: https://github.com/tytso/e2fsprogs/commit/326e8ab43503dd9f44338754c84cb03a725ecc49 +--- + misc/mke2fs.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/misc/mke2fs.c b/misc/mke2fs.c +index 017838d43..1b7399a51 100644 +--- a/misc/mke2fs.c ++++ b/misc/mke2fs.c +@@ -883,7 +883,10 @@ static void parse_extended_opts(struct ext2_super_block *param, + continue; + } + ulong = strtoul(arg, &p, 0); +- if (*p || (ulong & (ulong - 1))) { ++ if (*p || ++ (ulong < EXT2_MIN_DESC_SIZE_64BIT) || ++ (ulong > EXT2_MAX_DESC_SIZE) || ++ (ulong & (ulong - 1))) { + fprintf(stderr, + _("Invalid desc_size: '%s'\n"), arg); + r_usage++; +-- +2.47.2 + diff --git a/debian/patches/0017-debugfs-return-after-printing-the-usage-message-in-t.patch b/debian/patches/0017-debugfs-return-after-printing-the-usage-message-in-t.patch new file mode 100644 index 00000000..63bc7bb9 --- /dev/null +++ b/debian/patches/0017-debugfs-return-after-printing-the-usage-message-in-t.patch @@ -0,0 +1,45 @@ +From: Theodore Ts'o +Subject: debugfs: return after printing the usage message in the e2freefrag command + +Origin: https://github.com/tytso/e2fsprogs/commit/0c675a67c5684252e3a228c824b0accb9f3ab5d7 +--- + misc/e2freefrag.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/misc/e2freefrag.c b/misc/e2freefrag.c +index c66e8f22f..05f703966 100644 +--- a/misc/e2freefrag.c ++++ b/misc/e2freefrag.c +@@ -409,6 +409,9 @@ int main(int argc, char *argv[]) + fprintf(stderr, "%s: bad chunk size '%s'\n", + progname, optarg); + usage(progname); ++#ifdef DEBUFS ++ return; ++#endif + } + if (chunk_info.chunkbytes & + (chunk_info.chunkbytes - 1)) { +@@ -421,6 +424,9 @@ int main(int argc, char *argv[]) + case 'h': + default: + usage(progname); ++#ifdef DEBUGFS ++ return; ++#endif + break; + } + } +@@ -429,6 +435,9 @@ int main(int argc, char *argv[]) + if (optind == argc) { + fprintf(stderr, "%s: missing device name.\n", progname); + usage(progname); ++#ifdef DEBUGFS ++ return; ++#endif + } + + device_name = argv[optind]; +-- +2.47.2 + diff --git a/debian/patches/0020-mke2fs-fix-a-misindentation-in-the-man-page.patch b/debian/patches/0020-mke2fs-fix-a-misindentation-in-the-man-page.patch new file mode 100644 index 00000000..64c61246 --- /dev/null +++ b/debian/patches/0020-mke2fs-fix-a-misindentation-in-the-man-page.patch @@ -0,0 +1,26 @@ +From: Benno Schulenberg +Subject: mke2fs: fix a misindentation in the man page + +Problem existed since commit 3c22bf7e70 from twelve years ago. + +Origin: https://github.com/tytso/e2fsprogs/commit/4d6cfa2557de7d0878fed3203ac36d3e91df183f +--- + misc/mke2fs.8.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in +index 4ff564baa..13ddef47b 100644 +--- a/misc/mke2fs.8.in ++++ b/misc/mke2fs.8.in +@@ -714,7 +714,7 @@ by commas, that are to be enabled. To disable a feature, simply + prefix the feature name with a caret ('^') character. + Features with dependencies will not be removed successfully. + The pseudo-file system feature "none" will clear all file system features. +-.TP ++.sp + For more information about the features which can be set, please see + the manual page + .BR ext4 (5). +-- +2.47.2 + diff --git a/debian/patches/0021-libext2fs-fix-a-extent-tree-corruption-bug-in-ext2fs.patch b/debian/patches/0021-libext2fs-fix-a-extent-tree-corruption-bug-in-ext2fs.patch new file mode 100644 index 00000000..16c4ce80 --- /dev/null +++ b/debian/patches/0021-libext2fs-fix-a-extent-tree-corruption-bug-in-ext2fs.patch @@ -0,0 +1,66 @@ +From: Theodore Ts'o +Subject: libext2fs: fix a extent tree corruption bug in ext2fs_extent_set_bmap() + +In the case where we are moving a particular logical block mapping +from a particular extent tree entry, to the immediately precending +entry (when the physical block or uninitialized flag is changing so it +can be coalesced with the precending entry) and the precending entry +is in a different extent tree block, the resulting extent tree can get +corrupted. + +Fix this by removing the original logical block mapping before adding +the new logical block mapping. Per the warning in the comments before +ext2fs_extents_fix_parents(): + + Note a subtlety of this function -- if there happen to be two extents + mapping the same lblk and someone calls fix_parents on the second of + the two extents, the position of the extent handle after the call will + be the second extent if nothing happened, or the first extent if + something did. A caller in this situation must use + ext2fs_extent_goto() after calling this function. Or simply don't map + the same lblk with two extents, ever. + +Origin: https://github.com/tytso/e2fsprogs/commit/b914701223255c116745a11f30563652c9fdbb4b +--- + lib/ext2fs/extent.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c +index c4b95741e..1b2b84f23 100644 +--- a/lib/ext2fs/extent.c ++++ b/lib/ext2fs/extent.c +@@ -1531,6 +1531,15 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle, + #ifdef DEBUG + printf("(re/un)mapping first block in extent\n"); + #endif ++ extent.e_pblk++; ++ extent.e_lblk++; ++ extent.e_len--; ++ retval = ext2fs_extent_replace(handle, 0, &extent); ++ if (retval) ++ goto done; ++ retval = ext2fs_extent_fix_parents(handle); ++ if (retval) ++ goto done; + if (physical) { + if (has_prev && + (logical == (prev_extent.e_lblk + +@@ -1560,15 +1569,6 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle, + if (retval) + goto done; + } +- extent.e_pblk++; +- extent.e_lblk++; +- extent.e_len--; +- retval = ext2fs_extent_replace(handle, 0, &extent); +- if (retval) +- goto done; +- retval = ext2fs_extent_fix_parents(handle); +- if (retval) +- goto done; + } else { + __u32 save_length; + blk64_t save_lblk; +-- +2.47.2 + diff --git a/debian/patches/0022-libext2fs-fix-integer-overflow-in-ext2fs_punch-when-.patch b/debian/patches/0022-libext2fs-fix-integer-overflow-in-ext2fs_punch-when-.patch new file mode 100644 index 00000000..9e60f44c --- /dev/null +++ b/debian/patches/0022-libext2fs-fix-integer-overflow-in-ext2fs_punch-when-.patch @@ -0,0 +1,46 @@ +From: Theodore Ts'o +Subject: libext2fs: fix integer overflow in ext2fs_punch() when releasing more than 2**31 blocks +Origin: https://github.com/tytso/e2fsprogs/commit/34b2a4a1f9794498ca403393003cc5840c240d42 +Bug-Debian: http://bugs.debian.org/1106241 +--- + lib/ext2fs/punch.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/lib/ext2fs/punch.c b/lib/ext2fs/punch.c +index e2543e1e7..80c699eb0 100644 +--- a/lib/ext2fs/punch.c ++++ b/lib/ext2fs/punch.c +@@ -193,10 +193,10 @@ static void dbg_print_extent(char *desc, struct ext2fs_extent *extent) + static errcode_t punch_extent_blocks(ext2_filsys fs, ext2_ino_t ino, + struct ext2_inode *inode, + blk64_t lfree_start, blk64_t free_start, +- __u32 free_count, int *freed) ++ __u32 free_count, blk64_t *freed) + { + blk64_t pblk; +- int freed_now = 0; ++ __u32 freed_now = 0; + __u32 cluster_freed; + errcode_t retval = 0; + +@@ -271,7 +271,7 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino, + errcode_t retval; + blk64_t free_start, next, lfree_start; + __u32 free_count, newlen; +- int freed = 0; ++ blk64_t freed = 0; + int op; + + retval = ext2fs_extent_open2(fs, ino, inode, &handle); +@@ -442,7 +442,7 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino, + if (retval) + goto errout; + } +- dbg_printf("Freed %d blocks\n", freed); ++ dbg_printf("Freed %llu blocks\n", freed); + retval = ext2fs_iblk_sub_blocks(fs, inode, freed); + errout: + ext2fs_extent_free(handle); +-- +2.47.2 + diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 00000000..36a98306 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,20 @@ +0001-e2fsck-fix-logic-bug-when-there-are-no-references-to.patch +0002-test-fix-expect-files-which-changed-after-EA-bugfix.patch +0003-libext2fs-teach-ext2fs_extent_set_bmap-to-update-ext.patch +0004-e2image.8-add-missing-comma.patch +0005-debugfs-byteswap-dirsearch-dirent-buf-on-big-endian-.patch +0006-fuse2fs-refuse-unsupported-features.patch +0007-fuse2fs-return-EOPNOTSUPP-when-we-don-t-recognize-a-.patch +0008-fuse2fs-remove-posix-acl-translation.patch +0009-fuse2fs-clamp-timestamps-that-are-being-written-to-d.patch +0010-fuse2fs-update-new-child-timestamps-during-mkdir-sym.patch +0011-fuse2fs-disable-renameat2.patch +0012-debugfs-abort-reading-a-file-on-failure-when-dumping.patch +0013-mke2fs-disallow-O-verity-without-extents.patch +0014-e2fsck-fix-e2fsck-E-unshare_blocks-when-there-are-no.patch +0015-e2freefrag-require-that-the-chunksize-must-be-greate.patch +0016-mke2fs-add-range-checks-for-E-desc_size.patch +0017-debugfs-return-after-printing-the-usage-message-in-t.patch +0020-mke2fs-fix-a-misindentation-in-the-man-page.patch +0021-libext2fs-fix-a-extent-tree-corruption-bug-in-ext2fs.patch +0022-libext2fs-fix-integer-overflow-in-ext2fs_punch-when-.patch