|
|
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 |
|