X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lib%2Fext2fs%2Fswapfs.c;h=5e6b22f46f9508cd86b8da2af8170860dfb8750e;hb=f8a9d77cea1fc924f59f24955a1c8d6878410f5c;hp=b9d8f55796605ef1c793c072c13019331cfe40df;hpb=cf0be23436880a7c9658e2e24259e93cdcb4cc86;p=tools%2Fe2fsprogs.git diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c index b9d8f55..5e6b22f 100644 --- a/lib/ext2fs/swapfs.c +++ b/lib/ext2fs/swapfs.c @@ -19,12 +19,13 @@ #include "ext2_fs.h" #include "ext2fs.h" +#include "ext2fsP.h" #include -#ifdef WORDS_BIGENDIAN void ext2fs_swap_super(struct ext2_super_block * sb) { - int i; + int i; + sb->s_inodes_count = ext2fs_swab32(sb->s_inodes_count); sb->s_blocks_count = ext2fs_swab32(sb->s_blocks_count); sb->s_r_blocks_count = ext2fs_swab32(sb->s_r_blocks_count); @@ -56,52 +57,83 @@ void ext2fs_swap_super(struct ext2_super_block * sb) sb->s_feature_compat = ext2fs_swab32(sb->s_feature_compat); sb->s_feature_incompat = ext2fs_swab32(sb->s_feature_incompat); sb->s_feature_ro_compat = ext2fs_swab32(sb->s_feature_ro_compat); + /* sb->s_uuid is __u8 and does not need swabbing */ + /* sb->s_volume_name is char and does not need swabbing */ + /* sb->s_last_mounted is char and does not need swabbing */ sb->s_algorithm_usage_bitmap = ext2fs_swab32(sb->s_algorithm_usage_bitmap); + /* sb->s_prealloc_blocks is __u8 and does not need swabbing */ + /* sb->s_prealloc_dir_blocks is __u8 and does not need swabbing */ sb->s_reserved_gdt_blocks = ext2fs_swab16(sb->s_reserved_gdt_blocks); + /* sb->s_journal_uuid is __u8 and does not need swabbing */ sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum); sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev); sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan); + for (i = 0; i < 4; i++) + sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]); + /* sb->s_def_hash_version is __u8 and does not need swabbing */ + /* sb->s_jnl_backup_type is __u8 and does not need swabbing */ sb->s_desc_size = ext2fs_swab16(sb->s_desc_size); sb->s_default_mount_opts = ext2fs_swab32(sb->s_default_mount_opts); sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg); sb->s_mkfs_time = ext2fs_swab32(sb->s_mkfs_time); + /* if journal backup is for a valid extent-based journal... */ + if (ext2fs_extent_header_verify(sb->s_jnl_blocks, + sizeof(sb->s_jnl_blocks)) == 0) { + /* ... swap only the journal i_size and i_size_high, + * and the extent data is not swapped on read */ + i = 15; + } else { + /* direct/indirect journal: swap it all */ + i = 0; + } + for (; i < 17; i++) + sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]); sb->s_blocks_count_hi = ext2fs_swab32(sb->s_blocks_count_hi); sb->s_r_blocks_count_hi = ext2fs_swab32(sb->s_r_blocks_count_hi); sb->s_free_blocks_hi = ext2fs_swab32(sb->s_free_blocks_hi); sb->s_min_extra_isize = ext2fs_swab16(sb->s_min_extra_isize); sb->s_want_extra_isize = ext2fs_swab16(sb->s_want_extra_isize); sb->s_flags = ext2fs_swab32(sb->s_flags); + sb->s_raid_stride = ext2fs_swab16(sb->s_raid_stride); sb->s_mmp_update_interval = ext2fs_swab16(sb->s_mmp_update_interval); sb->s_mmp_block = ext2fs_swab64(sb->s_mmp_block); + sb->s_raid_stripe_width = ext2fs_swab32(sb->s_raid_stripe_width); + /* sb->s_log_groups_per_flex is __u8 and does not need swabbing */ + /* sb->s_checksum_type is __u8 and does not need swabbing */ + /* sb->s_encryption_level is __u8 and does not need swabbing */ + /* sb->s_reserved_pad is __u8 and does not need swabbing */ sb->s_kbytes_written = ext2fs_swab64(sb->s_kbytes_written); sb->s_snapshot_inum = ext2fs_swab32(sb->s_snapshot_inum); sb->s_snapshot_id = ext2fs_swab32(sb->s_snapshot_id); sb->s_snapshot_r_blocks_count = ext2fs_swab64(sb->s_snapshot_r_blocks_count); sb->s_snapshot_list = ext2fs_swab32(sb->s_snapshot_list); + sb->s_error_count = ext2fs_swab32(sb->s_error_count); + sb->s_first_error_time = ext2fs_swab32(sb->s_first_error_time); + sb->s_first_error_ino = ext2fs_swab32(sb->s_first_error_ino); + sb->s_first_error_block = ext2fs_swab64(sb->s_first_error_block); + /* sb->s_first_error_func is __u8 and does not need swabbing */ + sb->s_last_error_time = ext2fs_swab32(sb->s_last_error_time); + sb->s_last_error_ino = ext2fs_swab32(sb->s_last_error_ino); + sb->s_last_error_block = ext2fs_swab64(sb->s_last_error_block); + /* sb->s_last_error_func is __u8 and does not need swabbing */ + /* sb->s_mount_opts is __u8 and does not need swabbing */ sb->s_usr_quota_inum = ext2fs_swab32(sb->s_usr_quota_inum); sb->s_grp_quota_inum = ext2fs_swab32(sb->s_grp_quota_inum); - sb->s_overhead_blocks = ext2fs_swab32(sb->s_overhead_blocks); - sb->s_checksum = ext2fs_swab32(sb->s_checksum); - - for (i=0; i < 4; i++) - sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]); - - /* if journal backup is for a valid extent-based journal... */ - if (ext2fs_extent_header_verify(sb->s_jnl_blocks, - sizeof(sb->s_jnl_blocks)) == 0) { - /* ... swap only the journal i_size and i_size_high, - * and the extent data is not swapped on read */ - i = 15; - } else { - /* direct/indirect journal: swap it all */ - i = 0; - } - for (; i < 17; i++) - sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]); + sb->s_overhead_clusters = ext2fs_swab32(sb->s_overhead_clusters); sb->s_backup_bgs[0] = ext2fs_swab32(sb->s_backup_bgs[0]); sb->s_backup_bgs[1] = ext2fs_swab32(sb->s_backup_bgs[1]); + /* sb->s_encrypt_algos is __u8 and does not need swabbing */ + /* sb->s_encrypt_pw_salt is __u8 and does not need swabbing */ + sb->s_lpf_ino = ext2fs_swab32(sb->s_lpf_ino); + sb->s_prj_quota_inum = ext2fs_swab32(sb->s_prj_quota_inum); sb->s_checksum_seed = ext2fs_swab32(sb->s_checksum_seed); + /* s_*_time_hi are __u8 and does not need swabbing */ + sb->s_encoding = ext2fs_swab16(sb->s_encoding); + sb->s_encoding_flags = ext2fs_swab16(sb->s_encoding_flags); + /* catch when new fields are used from s_reserved */ + EXT2FS_BUILD_BUG_ON(sizeof(sb->s_reserved) != 95 * sizeof(__le32)); + sb->s_checksum = ext2fs_swab32(sb->s_checksum); } void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp) @@ -143,6 +175,7 @@ void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp) ext2fs_swab16(gdp4->bg_block_bitmap_csum_hi); gdp4->bg_inode_bitmap_csum_hi = ext2fs_swab16(gdp4->bg_inode_bitmap_csum_hi); + EXT2FS_BUILD_BUG_ON(sizeof(gdp4->bg_reserved) != sizeof(__u32)); } void ext2fs_swap_group_desc(struct ext2_group_desc *gdp) @@ -211,8 +244,8 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t, int bufsize) { unsigned i, extra_isize, attr_magic; - int has_extents, has_inline_data, islnk, fast_symlink; - int inode_size; + int has_extents = 0, has_inline_data = 0, islnk = 0, fast_symlink = 0; + unsigned int inode_size; __u32 *eaf, *eat; /* @@ -326,7 +359,9 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t, if (inode_includes(inode_size, i_version_hi)) t->i_version_hi = ext2fs_swab32(f->i_version_hi); if (inode_includes(inode_size, i_projid)) - t->i_projid = ext2fs_swab16(f->i_projid); + t->i_projid = ext2fs_swab32(f->i_projid); + /* catch new static fields added after i_projid */ + EXT2FS_BUILD_BUG_ON(sizeof(struct ext2_inode_large) != 160); i = sizeof(struct ext2_inode) + extra_isize + sizeof(__u32); if (bufsize < (int) i) @@ -381,10 +416,11 @@ errcode_t ext2fs_dirent_swab_in2(ext2_filsys fs, char *buf, errcode_t retval; char *p, *end; struct ext2_dir_entry *dirent; - unsigned int name_len, rec_len; + unsigned int name_len, rec_len, left; p = (char *) buf; end = (char *) buf + size; + left = size; while (p < end-8) { dirent = (struct ext2_dir_entry *) p; dirent->inode = ext2fs_swab32(dirent->inode); @@ -398,9 +434,15 @@ errcode_t ext2fs_dirent_swab_in2(ext2_filsys fs, char *buf, return retval; if ((rec_len < 8) || (rec_len % 4)) { rec_len = 8; - retval = EXT2_ET_DIR_CORRUPTED; + if (!(fs->flags & EXT2_FLAG_IGNORE_SWAP_DIRENT)) + return EXT2_ET_DIR_CORRUPTED; } else if (((name_len & 0xFF) + 8) > rec_len) - retval = EXT2_ET_DIR_CORRUPTED; + if (!(fs->flags & EXT2_FLAG_IGNORE_SWAP_DIRENT)) + return EXT2_ET_DIR_CORRUPTED; + if (rec_len > left) + if (!(fs->flags & EXT2_FLAG_IGNORE_SWAP_DIRENT)) + return EXT2_ET_DIR_CORRUPTED; + left -= rec_len; p += rec_len; } @@ -436,6 +478,9 @@ errcode_t ext2fs_dirent_swab_out2(ext2_filsys fs, char *buf, dirent->inode = ext2fs_swab32(dirent->inode); dirent->rec_len = ext2fs_swab16(dirent->rec_len); dirent->name_len = ext2fs_swab16(dirent->name_len); + if (rec_len > size) + return EXT2_ET_DIR_CORRUPTED; + size -= rec_len; if (flags & EXT2_DIRBLOCK_V2_STRUCT) dirent->name_len = ext2fs_swab16(dirent->name_len); @@ -443,5 +488,3 @@ errcode_t ext2fs_dirent_swab_out2(ext2_filsys fs, char *buf, return 0; } - -#endif