diff --git a/0001-e2fsprogs-fix-metadata-image-handling-on-big-endian-.patch b/0001-e2fsprogs-fix-metadata-image-handling-on-big-endian-.patch new file mode 100644 index 0000000..d576a1b --- /dev/null +++ b/0001-e2fsprogs-fix-metadata-image-handling-on-big-endian-.patch @@ -0,0 +1,225 @@ +From eb8758e89150306a0c699ab7ad3d774ca38d0363 Mon Sep 17 00:00:00 2001 +From: Lukas Czerner +Date: Thu, 5 Apr 2018 16:02:28 +0200 +Subject: [PATCH] e2fsprogs: fix metadata image handling on big endian systems + +Currently e2image metadata image handling and creating is completely +broken on big endian systems. It just does not care about endianness at +all. This was uncovered With addition of i_bitmaps test, which is the +first test that actually tests e2image metadata image. + +Fix it by making sure that all on-disk metadata that we write and read +to/from the metadata image is properly converted. + +Signed-off-by: Lukas Czerner +--- + lib/ext2fs/imager.c | 41 +++++++++++++++++++++++++++++++++++++++++ + lib/ext2fs/inode.c | 2 +- + lib/ext2fs/openfs.c | 4 ++-- + lib/ext2fs/rw_bitmaps.c | 4 ++-- + misc/e2image.c | 22 +++++++++++----------- + 5 files changed, 57 insertions(+), 16 deletions(-) + +diff --git a/lib/ext2fs/imager.c b/lib/ext2fs/imager.c +index efb85b9..7fd06f7 100644 +--- a/lib/ext2fs/imager.c ++++ b/lib/ext2fs/imager.c +@@ -195,6 +195,11 @@ errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, + char *buf, *cp; + ssize_t actual; + errcode_t retval; ++#ifdef WORDS_BIGENDIAN ++ unsigned int groups_per_block; ++ struct ext2_group_desc *gdp; ++ int j; ++#endif + + buf = malloc(fs->blocksize); + if (!buf) +@@ -204,7 +209,17 @@ errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, + * Write out the superblock + */ + memset(buf, 0, fs->blocksize); ++#ifdef WORDS_BIGENDIAN ++ /* ++ * We're writing out superblock so let's convert ++ * it to little endian and then back if needed ++ */ ++ ext2fs_swap_super(fs->super); + memcpy(buf, fs->super, SUPERBLOCK_SIZE); ++ ext2fs_swap_super(fs->super); ++#else ++ memcpy(buf, fs->super, SUPERBLOCK_SIZE); ++#endif + actual = write(fd, buf, fs->blocksize); + if (actual == -1) { + retval = errno; +@@ -218,8 +233,34 @@ errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, + /* + * Now write out the block group descriptors + */ ++ + cp = (char *) fs->group_desc; ++ ++#ifdef WORDS_BIGENDIAN ++ /* ++ * Convert group descriptors to little endian and back ++ * if needed ++ */ ++ groups_per_block = EXT2_DESC_PER_BLOCK(fs->super); ++ gdp = (struct ext2_group_desc *) cp; ++ for (j=0; j < groups_per_block*fs->desc_blocks; j++) { ++ gdp = ext2fs_group_desc(fs, fs->group_desc, j); ++ ext2fs_swap_group_desc2(fs, gdp); ++ } ++#endif ++ + actual = write(fd, cp, fs->blocksize * fs->desc_blocks); ++ ++ ++#ifdef WORDS_BIGENDIAN ++ groups_per_block = EXT2_DESC_PER_BLOCK(fs->super); ++ gdp = (struct ext2_group_desc *) cp; ++ for (j=0; j < groups_per_block*fs->desc_blocks; j++) { ++ gdp = ext2fs_group_desc(fs, fs->group_desc, j); ++ ext2fs_swap_group_desc2(fs, gdp); ++ } ++#endif ++ + if (actual == -1) { + retval = errno; + goto errout; +diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c +index ad01a9f..015cfe4 100644 +--- a/lib/ext2fs/inode.c ++++ b/lib/ext2fs/inode.c +@@ -770,7 +770,7 @@ errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino, + } + if (fs->flags & EXT2_FLAG_IMAGE_FILE) { + inodes_per_block = fs->blocksize / EXT2_INODE_SIZE(fs->super); +- block_nr = fs->image_header->offset_inode / fs->blocksize; ++ block_nr = ext2fs_le32_to_cpu(fs->image_header->offset_inode) / fs->blocksize; + block_nr += (ino - 1) / inodes_per_block; + offset = ((ino - 1) % inodes_per_block) * + EXT2_INODE_SIZE(fs->super); +diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c +index 385d6e8..532e70f 100644 +--- a/lib/ext2fs/openfs.c ++++ b/lib/ext2fs/openfs.c +@@ -185,10 +185,10 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, + fs->image_header); + if (retval) + goto cleanup; +- if (fs->image_header->magic_number != EXT2_ET_MAGIC_E2IMAGE) ++ if (ext2fs_le32_to_cpu(fs->image_header->magic_number) != EXT2_ET_MAGIC_E2IMAGE) + return EXT2_ET_MAGIC_E2IMAGE; + superblock = 1; +- block_size = fs->image_header->fs_blocksize; ++ block_size = ext2fs_le32_to_cpu(fs->image_header->fs_blocksize); + } + + /* +diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c +index 0b532db..e86bacd 100644 +--- a/lib/ext2fs/rw_bitmaps.c ++++ b/lib/ext2fs/rw_bitmaps.c +@@ -253,7 +253,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) + ext2fs_free_mem(&buf); + + if (fs->flags & EXT2_FLAG_IMAGE_FILE) { +- blk = (fs->image_header->offset_inodemap / fs->blocksize); ++ blk = (ext2fs_le32_to_cpu(fs->image_header->offset_inodemap) / fs->blocksize); + ino_cnt = fs->super->s_inodes_count; + while (inode_bitmap && ino_cnt > 0) { + retval = io_channel_read_blk64(fs->image_io, blk++, +@@ -270,7 +270,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) + ino_itr += cnt; + ino_cnt -= cnt; + } +- blk = (fs->image_header->offset_blockmap / ++ blk = (ext2fs_le32_to_cpu(fs->image_header->offset_blockmap) / + fs->blocksize); + blk_cnt = EXT2_GROUPS_TO_CLUSTERS(fs->super, + fs->group_desc_count); +diff --git a/misc/e2image.c b/misc/e2image.c +index 5a18bb4..83ae633 100644 +--- a/misc/e2image.c ++++ b/misc/e2image.c +@@ -240,7 +240,7 @@ static void write_image_file(ext2_filsys fs, int fd) + write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize); + memset(&hdr, 0, sizeof(struct ext2_image_hdr)); + +- hdr.offset_super = seek_relative(fd, 0); ++ hdr.offset_super = ext2fs_cpu_to_le32(seek_relative(fd, 0)); + retval = ext2fs_image_super_write(fs, fd, 0); + if (retval) { + com_err(program_name, retval, "%s", +@@ -248,7 +248,7 @@ static void write_image_file(ext2_filsys fs, int fd) + exit(1); + } + +- hdr.offset_inode = seek_relative(fd, 0); ++ hdr.offset_inode = ext2fs_cpu_to_le32(seek_relative(fd, 0)); + retval = ext2fs_image_inode_write(fs, fd, + (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0); + if (retval) { +@@ -257,7 +257,7 @@ static void write_image_file(ext2_filsys fs, int fd) + exit(1); + } + +- hdr.offset_blockmap = seek_relative(fd, 0); ++ hdr.offset_blockmap = ext2fs_cpu_to_le32(seek_relative(fd, 0)); + retval = ext2fs_image_bitmap_write(fs, fd, 0); + if (retval) { + com_err(program_name, retval, "%s", +@@ -265,7 +265,7 @@ static void write_image_file(ext2_filsys fs, int fd) + exit(1); + } + +- hdr.offset_inodemap = seek_relative(fd, 0); ++ hdr.offset_inodemap = ext2fs_cpu_to_le32(seek_relative(fd, 0)); + retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP); + if (retval) { + com_err(program_name, retval, "%s", +@@ -273,23 +273,23 @@ static void write_image_file(ext2_filsys fs, int fd) + exit(1); + } + +- hdr.magic_number = EXT2_ET_MAGIC_E2IMAGE; ++ hdr.magic_number = ext2fs_cpu_to_le32(EXT2_ET_MAGIC_E2IMAGE); + strcpy(hdr.magic_descriptor, "Ext2 Image 1.0"); + gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname)); + strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1); + hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0; +- hdr.fs_blocksize = fs->blocksize; ++ hdr.fs_blocksize = ext2fs_cpu_to_le32(fs->blocksize); + + if (stat(device_name, &st) == 0) +- hdr.fs_device = st.st_rdev; ++ hdr.fs_device = ext2fs_cpu_to_le32(st.st_rdev); + + if (fstat(fd, &st) == 0) { +- hdr.image_device = st.st_dev; +- hdr.image_inode = st.st_ino; ++ hdr.image_device = ext2fs_cpu_to_le32(st.st_dev); ++ hdr.image_inode = ext2fs_cpu_to_le32(st.st_ino); + } + memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid)); + +- hdr.image_time = time(0); ++ hdr.image_time = ext2fs_cpu_to_le32(time(0)); + write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize); + } + +@@ -1423,7 +1423,7 @@ static void install_image(char *device, char *image_fn, int type) + + ext2fs_rewrite_to_io(fs, io); + +- seek_set(fd, fs->image_header->offset_inode); ++ seek_set(fd, ext2fs_le32_to_cpu(fs->image_header->offset_inode)); + + retval = ext2fs_image_inode_read(fs, fd, 0); + if (retval) { +-- +2.7.5 + diff --git a/e2fsprogs.spec b/e2fsprogs.spec index f212120..15652f1 100644 --- a/e2fsprogs.spec +++ b/e2fsprogs.spec @@ -11,6 +11,7 @@ Source1: ext2_types-wrapper.h Source2: e2fsck.conf Patch1: e2fsprogs-1.44.1-tests_use_mke2fs_and_debugfs_from_the_build_tree.patch +Patch2: 0001-e2fsprogs-fix-metadata-image-handling-on-big-endian-.patch Url: http://e2fsprogs.sourceforge.net/ Requires: e2fsprogs-libs%{?_isa} = %{version}-%{release} @@ -148,6 +149,8 @@ It was originally inspired by the Multics SubSystem library. %setup -q # tests: use mke2fs and debugfs from the build tree %patch1 -p1 +# e2fsprogs: fix metadata image handling on big endian systems +%patch2 -p1 %build @@ -331,6 +334,7 @@ exit 0 - New upstream release - tests: use mke2fs and debugfs from the build tree - remove custom patch to ignose sb feature differences +- e2fsprogs: fix metadata image handling on big endian systems * Mon Mar 12 2018 Lukas Czerner 1.44.0-2 - e2fsck: fix endianness problem when reading htree nodes