]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
debian: update debian/patches with for bugfix e2fsprogs release
authorTheodore Ts'o <tytso@mit.edu>
Mon, 9 Jun 2025 22:22:39 +0000 (18:22 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 10 Jun 2025 01:22:03 +0000 (21:22 -0400)
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
21 files changed:
debian/patches/0001-e2fsck-fix-logic-bug-when-there-are-no-references-to.patch [new file with mode: 0644]
debian/patches/0002-test-fix-expect-files-which-changed-after-EA-bugfix.patch [new file with mode: 0644]
debian/patches/0003-libext2fs-teach-ext2fs_extent_set_bmap-to-update-ext.patch [new file with mode: 0644]
debian/patches/0004-e2image.8-add-missing-comma.patch [new file with mode: 0644]
debian/patches/0005-debugfs-byteswap-dirsearch-dirent-buf-on-big-endian-.patch [new file with mode: 0644]
debian/patches/0006-fuse2fs-refuse-unsupported-features.patch [new file with mode: 0644]
debian/patches/0007-fuse2fs-return-EOPNOTSUPP-when-we-don-t-recognize-a-.patch [new file with mode: 0644]
debian/patches/0008-fuse2fs-remove-posix-acl-translation.patch [new file with mode: 0644]
debian/patches/0009-fuse2fs-clamp-timestamps-that-are-being-written-to-d.patch [new file with mode: 0644]
debian/patches/0010-fuse2fs-update-new-child-timestamps-during-mkdir-sym.patch [new file with mode: 0644]
debian/patches/0011-fuse2fs-disable-renameat2.patch [new file with mode: 0644]
debian/patches/0012-debugfs-abort-reading-a-file-on-failure-when-dumping.patch [new file with mode: 0644]
debian/patches/0013-mke2fs-disallow-O-verity-without-extents.patch [new file with mode: 0644]
debian/patches/0014-e2fsck-fix-e2fsck-E-unshare_blocks-when-there-are-no.patch [new file with mode: 0644]
debian/patches/0015-e2freefrag-require-that-the-chunksize-must-be-greate.patch [new file with mode: 0644]
debian/patches/0016-mke2fs-add-range-checks-for-E-desc_size.patch [new file with mode: 0644]
debian/patches/0017-debugfs-return-after-printing-the-usage-message-in-t.patch [new file with mode: 0644]
debian/patches/0020-mke2fs-fix-a-misindentation-in-the-man-page.patch [new file with mode: 0644]
debian/patches/0021-libext2fs-fix-a-extent-tree-corruption-bug-in-ext2fs.patch [new file with mode: 0644]
debian/patches/0022-libext2fs-fix-integer-overflow-in-ext2fs_punch-when-.patch [new file with mode: 0644]
debian/patches/series [new file with mode: 0644]

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 (file)
index 0000000..e60bd31
--- /dev/null
@@ -0,0 +1,36 @@
+From: Theodore Ts'o <tytso@mit.edu>
+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 (file)
index 0000000..be06486
--- /dev/null
@@ -0,0 +1,44 @@
+From: Theodore Ts'o <tytso@mit.edu>
+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 (file)
index 0000000..7709fbf
--- /dev/null
@@ -0,0 +1,123 @@
+From: Theodore Ts'o <tytso@mit.edu>
+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 (file)
index 0000000..90340a3
--- /dev/null
@@ -0,0 +1,21 @@
+From: Jakub Wilk <jwilk@jwilk.net>
+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 (file)
index 0000000..487bd56
--- /dev/null
@@ -0,0 +1,40 @@
+From: Brian Foster <bfoster@redhat.com>
+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 (file)
index 0000000..29b0104
--- /dev/null
@@ -0,0 +1,45 @@
+From: "Darrick J. Wong" <djwong@kernel.org>
+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 (file)
index 0000000..19c912d
--- /dev/null
@@ -0,0 +1,28 @@
+From: "Darrick J. Wong" <djwong@kernel.org>
+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 (file)
index 0000000..c6bd91f
--- /dev/null
@@ -0,0 +1,347 @@
+From: "Darrick J. Wong" <djwong@kernel.org>
+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 <linux/fs.h>
+ # include <linux/falloc.h>
+ # include <linux/xattr.h>
+-# ifdef HAVE_SYS_ACL_H
+-#  define TRANSLATE_LINUX_ACLS
+-# endif
+-#endif
+-#ifdef TRANSLATE_LINUX_ACLS
+-# include <sys/acl.h>
+ #endif
+ #include <sys/ioctl.h>
+ #include <unistd.h>
+@@ -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 (file)
index 0000000..d00b7cc
--- /dev/null
@@ -0,0 +1,107 @@
+From: "Darrick J. Wong" <djwong@kernel.org>
+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 (file)
index 0000000..35de549
--- /dev/null
@@ -0,0 +1,34 @@
+From: "Darrick J. Wong" <djwong@kernel.org>
+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 (file)
index 0000000..7d325bd
--- /dev/null
@@ -0,0 +1,33 @@
+From: "Darrick J. Wong" <djwong@kernel.org>
+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 (file)
index 0000000..9962c1c
--- /dev/null
@@ -0,0 +1,36 @@
+From: Theodore Ts'o <tytso@mit.edu>
+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 (file)
index 0000000..e94fd89
--- /dev/null
@@ -0,0 +1,34 @@
+From: Allison Karlitskaya <allison.karlitskaya@redhat.com>
+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 (file)
index 0000000..215693b
--- /dev/null
@@ -0,0 +1,33 @@
+From: Theodore Ts'o <tytso@mit.edu>
+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 (file)
index 0000000..bd6af94
--- /dev/null
@@ -0,0 +1,28 @@
+From: Theodore Ts'o <tytso@mit.edu>
+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 (file)
index 0000000..9f48511
--- /dev/null
@@ -0,0 +1,30 @@
+From: Theodore Ts'o <tytso@mit.edu>
+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 (file)
index 0000000..63bc7bb
--- /dev/null
@@ -0,0 +1,45 @@
+From: Theodore Ts'o <tytso@mit.edu>
+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 (file)
index 0000000..64c6124
--- /dev/null
@@ -0,0 +1,26 @@
+From: Benno Schulenberg <bensberg@telfort.nl>
+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 (file)
index 0000000..16c4ce8
--- /dev/null
@@ -0,0 +1,66 @@
+From: Theodore Ts'o <tytso@mit.edu>
+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 (file)
index 0000000..9e60f44
--- /dev/null
@@ -0,0 +1,46 @@
+From: Theodore Ts'o <tytso@mit.edu>
+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 (file)
index 0000000..36a9830
--- /dev/null
@@ -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