Blame SOURCES/e2fsprogs-1.42.9-e2image-fix-metadata-image-handling-on-big-endian-sy.patch

3b974a
From 8f575d0b2c297f09491093b9e7ba6b914639be71 Mon Sep 17 00:00:00 2001
3b974a
From: Lukas Czerner <lczerner@redhat.com>
3b974a
Date: Mon, 9 Apr 2018 11:58:15 -0400
3b974a
Subject: [PATCH 4/7] e2image: fix metadata image handling on big endian
3b974a
 systems
3b974a
3b974a
Currently e2image metadata image handling and creating is completely
3b974a
broken on big endian systems. It just does not care about endianness at
3b974a
all. This was uncovered With addition of i_bitmaps test, which is the
3b974a
first test that actually tests e2image metadata image.
3b974a
3b974a
Fix it by making sure that all on-disk metadata that we write and read
3b974a
to/from the metadata image is properly converted.
3b974a
3b974a
RHBZ: 1711880
3b974a
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
3b974a
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
3b974a
---
3b974a
 lib/ext2fs/imager.c     | 41 +++++++++++++++++++++++++++++++++++++++++
3b974a
 lib/ext2fs/inode.c      |  2 +-
3b974a
 lib/ext2fs/openfs.c     |  4 ++--
3b974a
 lib/ext2fs/rw_bitmaps.c |  4 ++--
3b974a
 misc/e2image.c          | 22 +++++++++++-----------
3b974a
 5 files changed, 57 insertions(+), 16 deletions(-)
3b974a
3b974a
diff --git a/lib/ext2fs/imager.c b/lib/ext2fs/imager.c
3b974a
index b643cc6f..6caca65b 100644
3b974a
--- a/lib/ext2fs/imager.c
3b974a
+++ b/lib/ext2fs/imager.c
3b974a
@@ -194,6 +194,11 @@ errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd,
3b974a
 	char		*buf, *cp;
3b974a
 	ssize_t		actual;
3b974a
 	errcode_t	retval;
3b974a
+#ifdef WORDS_BIGENDIAN
3b974a
+	unsigned int	groups_per_block;
3b974a
+	struct		ext2_group_desc *gdp;
3b974a
+	int		j;
3b974a
+#endif
3b974a
 
3b974a
 	buf = malloc(fs->blocksize);
3b974a
 	if (!buf)
3b974a
@@ -203,7 +208,17 @@ errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd,
3b974a
 	 * Write out the superblock
3b974a
 	 */
3b974a
 	memset(buf, 0, fs->blocksize);
3b974a
+#ifdef WORDS_BIGENDIAN
3b974a
+	/*
3b974a
+	 * We're writing out superblock so let's convert
3b974a
+	 * it to little endian and then back if needed
3b974a
+	 */
3b974a
+	ext2fs_swap_super(fs->super);
3b974a
 	memcpy(buf, fs->super, SUPERBLOCK_SIZE);
3b974a
+	ext2fs_swap_super(fs->super);
3b974a
+#else
3b974a
+	memcpy(buf, fs->super, SUPERBLOCK_SIZE);
3b974a
+#endif
3b974a
 	actual = write(fd, buf, fs->blocksize);
3b974a
 	if (actual == -1) {
3b974a
 		retval = errno;
3b974a
@@ -217,8 +232,34 @@ errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd,
3b974a
 	/*
3b974a
 	 * Now write out the block group descriptors
3b974a
 	 */
3b974a
+
3b974a
 	cp = (char *) fs->group_desc;
3b974a
+
3b974a
+#ifdef WORDS_BIGENDIAN
3b974a
+	/*
3b974a
+	 * Convert group descriptors to little endian and back
3b974a
+	 * if needed
3b974a
+	 */
3b974a
+	groups_per_block = EXT2_DESC_PER_BLOCK(fs->super);
3b974a
+	gdp = (struct ext2_group_desc *) cp;
3b974a
+	for (j=0; j < groups_per_block*fs->desc_blocks; j++) {
3b974a
+		gdp = ext2fs_group_desc(fs, fs->group_desc, j);
3b974a
+		ext2fs_swap_group_desc2(fs, gdp);
3b974a
+	}
3b974a
+#endif
3b974a
+
3b974a
 	actual = write(fd, cp, fs->blocksize * fs->desc_blocks);
3b974a
+
3b974a
+
3b974a
+#ifdef WORDS_BIGENDIAN
3b974a
+	groups_per_block = EXT2_DESC_PER_BLOCK(fs->super);
3b974a
+	gdp = (struct ext2_group_desc *) cp;
3b974a
+	for (j=0; j < groups_per_block*fs->desc_blocks; j++) {
3b974a
+		gdp = ext2fs_group_desc(fs, fs->group_desc, j);
3b974a
+		ext2fs_swap_group_desc2(fs, gdp);
3b974a
+	}
3b974a
+#endif
3b974a
+
3b974a
 	if (actual == -1) {
3b974a
 		retval = errno;
3b974a
 		goto errout;
3b974a
diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c
3b974a
index 573a8fa5..4297ec12 100644
3b974a
--- a/lib/ext2fs/inode.c
3b974a
+++ b/lib/ext2fs/inode.c
3b974a
@@ -560,7 +560,7 @@ errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
3b974a
 	}
3b974a
 	if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
3b974a
 		inodes_per_block = fs->blocksize / EXT2_INODE_SIZE(fs->super);
3b974a
-		block_nr = fs->image_header->offset_inode / fs->blocksize;
3b974a
+		block_nr = ext2fs_le32_to_cpu(fs->image_header->offset_inode) / fs->blocksize;
3b974a
 		block_nr += (ino - 1) / inodes_per_block;
3b974a
 		offset = ((ino - 1) % inodes_per_block) *
3b974a
 			EXT2_INODE_SIZE(fs->super);
3b974a
diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c
3b974a
index 200f7815..384dbf0f 100644
3b974a
--- a/lib/ext2fs/openfs.c
3b974a
+++ b/lib/ext2fs/openfs.c
3b974a
@@ -177,10 +177,10 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
3b974a
 					     fs->image_header);
3b974a
 		if (retval)
3b974a
 			goto cleanup;
3b974a
-		if (fs->image_header->magic_number != EXT2_ET_MAGIC_E2IMAGE)
3b974a
+		if (ext2fs_le32_to_cpu(fs->image_header->magic_number) != EXT2_ET_MAGIC_E2IMAGE)
3b974a
 			return EXT2_ET_MAGIC_E2IMAGE;
3b974a
 		superblock = 1;
3b974a
-		block_size = fs->image_header->fs_blocksize;
3b974a
+		block_size = ext2fs_le32_to_cpu(fs->image_header->fs_blocksize);
3b974a
 	}
3b974a
 
3b974a
 	/*
3b974a
diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c
3b974a
index ad1d8c80..0e7986b0 100644
3b974a
--- a/lib/ext2fs/rw_bitmaps.c
3b974a
+++ b/lib/ext2fs/rw_bitmaps.c
3b974a
@@ -205,7 +205,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
3b974a
 	ext2fs_free_mem(&buf;;
3b974a
 
3b974a
 	if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
3b974a
-		blk = (fs->image_header->offset_inodemap / fs->blocksize);
3b974a
+		blk = (ext2fs_le32_to_cpu(fs->image_header->offset_inodemap) / fs->blocksize);
3b974a
 		ino_cnt = fs->super->s_inodes_count;
3b974a
 		while (inode_nbytes > 0) {
3b974a
 			retval = io_channel_read_blk64(fs->image_io, blk++,
3b974a
@@ -223,7 +223,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
3b974a
 			ino_cnt -= fs->blocksize << 3;
3b974a
 			inode_nbytes -= fs->blocksize;
3b974a
 		}
3b974a
-		blk = (fs->image_header->offset_blockmap /
3b974a
+		blk = (ext2fs_le32_to_cpu(fs->image_header->offset_blockmap) /
3b974a
 		       fs->blocksize);
3b974a
 		blk_cnt = EXT2_GROUPS_TO_CLUSTERS(fs->super,
3b974a
 						  fs->group_desc_count);
3b974a
diff --git a/misc/e2image.c b/misc/e2image.c
3b974a
index 98dafa3d..41e54636 100644
3b974a
--- a/misc/e2image.c
3b974a
+++ b/misc/e2image.c
3b974a
@@ -232,7 +232,7 @@ static void write_image_file(ext2_filsys fs, int fd)
3b974a
 	write_header(fd, NULL, sizeof(struct ext2_image_hdr), fs->blocksize);
3b974a
 	memset(&hdr, 0, sizeof(struct ext2_image_hdr));
3b974a
 
3b974a
-	hdr.offset_super = seek_relative(fd, 0);
3b974a
+	hdr.offset_super = ext2fs_cpu_to_le32(seek_relative(fd, 0));
3b974a
 	retval = ext2fs_image_super_write(fs, fd, 0);
3b974a
 	if (retval) {
3b974a
 		com_err(program_name, retval, "%s",
3b974a
@@ -240,7 +240,7 @@ static void write_image_file(ext2_filsys fs, int fd)
3b974a
 		exit(1);
3b974a
 	}
3b974a
 
3b974a
-	hdr.offset_inode = seek_relative(fd, 0);
3b974a
+	hdr.offset_inode = ext2fs_cpu_to_le32(seek_relative(fd, 0));
3b974a
 	retval = ext2fs_image_inode_write(fs, fd,
3b974a
 				  (fd != 1) ? IMAGER_FLAG_SPARSEWRITE : 0);
3b974a
 	if (retval) {
3b974a
@@ -249,7 +249,7 @@ static void write_image_file(ext2_filsys fs, int fd)
3b974a
 		exit(1);
3b974a
 	}
3b974a
 
3b974a
-	hdr.offset_blockmap = seek_relative(fd, 0);
3b974a
+	hdr.offset_blockmap = ext2fs_cpu_to_le32(seek_relative(fd, 0));
3b974a
 	retval = ext2fs_image_bitmap_write(fs, fd, 0);
3b974a
 	if (retval) {
3b974a
 		com_err(program_name, retval, "%s",
3b974a
@@ -257,7 +257,7 @@ static void write_image_file(ext2_filsys fs, int fd)
3b974a
 		exit(1);
3b974a
 	}
3b974a
 
3b974a
-	hdr.offset_inodemap = seek_relative(fd, 0);
3b974a
+	hdr.offset_inodemap = ext2fs_cpu_to_le32(seek_relative(fd, 0));
3b974a
 	retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP);
3b974a
 	if (retval) {
3b974a
 		com_err(program_name, retval, "%s",
3b974a
@@ -265,23 +265,23 @@ static void write_image_file(ext2_filsys fs, int fd)
3b974a
 		exit(1);
3b974a
 	}
3b974a
 
3b974a
-	hdr.magic_number = EXT2_ET_MAGIC_E2IMAGE;
3b974a
+	hdr.magic_number = ext2fs_cpu_to_le32(EXT2_ET_MAGIC_E2IMAGE);
3b974a
 	strcpy(hdr.magic_descriptor, "Ext2 Image 1.0");
3b974a
 	gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname));
3b974a
 	strncpy(hdr.fs_device_name, device_name, sizeof(hdr.fs_device_name)-1);
3b974a
 	hdr.fs_device_name[sizeof(hdr.fs_device_name) - 1] = 0;
3b974a
-	hdr.fs_blocksize = fs->blocksize;
3b974a
+	hdr.fs_blocksize = ext2fs_cpu_to_le32(fs->blocksize);
3b974a
 
3b974a
 	if (stat(device_name, &st) == 0)
3b974a
-		hdr.fs_device = st.st_rdev;
3b974a
+		hdr.fs_device = ext2fs_cpu_to_le32(st.st_rdev);
3b974a
 
3b974a
 	if (fstat(fd, &st) == 0) {
3b974a
-		hdr.image_device = st.st_dev;
3b974a
-		hdr.image_inode = st.st_ino;
3b974a
+		hdr.image_device = ext2fs_cpu_to_le32(st.st_dev);
3b974a
+		hdr.image_inode = ext2fs_cpu_to_le32(st.st_ino);
3b974a
 	}
3b974a
 	memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid));
3b974a
 
3b974a
-	hdr.image_time = time(0);
3b974a
+	hdr.image_time = ext2fs_cpu_to_le32(time(0));
3b974a
 	write_header(fd, &hdr, sizeof(struct ext2_image_hdr), fs->blocksize);
3b974a
 }
3b974a
 
3b974a
@@ -1406,7 +1406,7 @@ static void install_image(char *device, char *image_fn, int type)
3b974a
 
3b974a
 	ext2fs_rewrite_to_io(fs, io);
3b974a
 
3b974a
-	seek_set(fd, fs->image_header->offset_inode);
3b974a
+	seek_set(fd, ext2fs_le32_to_cpu(fs->image_header->offset_inode));
3b974a
 
3b974a
 	retval = ext2fs_image_inode_read(fs, fd, 0);
3b974a
 	if (retval) {
3b974a
-- 
3b974a
2.21.1
3b974a