[U-Boot] [PATCH] fs/ext4: fix calling put_ext4 with truncated offset
Ma Haijun
mahaijuns at gmail.com
Wed Jan 8 01:15:33 CET 2014
Curently, we are using 32 bit multiplication to calculate the offset,
so the result will always be 32 bit.
This can silently cause file system corruption when performing a write
operation on partition larger than 4 GiB.
This patch address the issue by simply promoting the terms to 64 bit,
and let compilers decide how to do the multiplication efficiently.
Signed-off-by: Ma Haijun <mahaijuns at gmail.com>
---
fs/ext4/ext4_common.c | 34 +++++++++++++++++-----------------
fs/ext4/ext4_journal.c | 8 ++++----
fs/ext4/ext4_write.c | 14 +++++++-------
3 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 352943e..cff50d8 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -445,9 +445,9 @@ restart:
goto fail;
}
put_ext4(((uint64_t)
- (g_parent_inode->b.
+ ((uint64_t)g_parent_inode->b.
blocks.dir_blocks[direct_blk_idx] *
- fs->blksz)), zero_buffer, fs->blksz);
+ (uint64_t)fs->blksz)), zero_buffer, fs->blksz);
g_parent_inode->size =
g_parent_inode->size + fs->blksz;
g_parent_inode->blockcnt =
@@ -864,8 +864,8 @@ long int ext4fs_get_new_blk_no(void)
for (i = 0; i < fs->no_blkgrp; i++) {
if (bgd[i].free_blocks) {
if (bgd[i].bg_flags & EXT4_BG_BLOCK_UNINIT) {
- put_ext4(((uint64_t) (bgd[i].block_id *
- fs->blksz)),
+ put_ext4(((uint64_t) ((uint64_t)bgd[i].block_id *
+ (uint64_t)fs->blksz)),
zero_buffer, fs->blksz);
bgd[i].bg_flags =
bgd[i].
@@ -929,8 +929,8 @@ restart:
if (bgd[bg_idx].bg_flags & EXT4_BG_BLOCK_UNINIT) {
memset(zero_buffer, '\0', fs->blksz);
- put_ext4(((uint64_t) (bgd[bg_idx].block_id *
- fs->blksz)), zero_buffer, fs->blksz);
+ put_ext4(((uint64_t) ((uint64_t)bgd[bg_idx].block_id *
+ (uint64_t)fs->blksz)), zero_buffer, fs->blksz);
memcpy(fs->blk_bmaps[bg_idx], zero_buffer, fs->blksz);
bgd[bg_idx].bg_flags = bgd[bg_idx].bg_flags &
~EXT4_BG_BLOCK_UNINIT;
@@ -996,8 +996,8 @@ int ext4fs_get_new_inode_no(void)
bgd[i].free_inodes;
if (bgd[i].bg_flags & EXT4_BG_INODE_UNINIT) {
put_ext4(((uint64_t)
- (bgd[i].inode_id *
- fs->blksz)),
+ ((uint64_t)bgd[i].inode_id *
+ (uint64_t)fs->blksz)),
zero_buffer, fs->blksz);
bgd[i].bg_flags = bgd[i].bg_flags &
~EXT4_BG_INODE_UNINIT;
@@ -1037,8 +1037,8 @@ restart:
ibmap_idx = fs->curr_inode_no / inodes_per_grp;
if (bgd[ibmap_idx].bg_flags & EXT4_BG_INODE_UNINIT) {
memset(zero_buffer, '\0', fs->blksz);
- put_ext4(((uint64_t) (bgd[ibmap_idx].inode_id *
- fs->blksz)), zero_buffer,
+ put_ext4(((uint64_t) ((uint64_t)bgd[ibmap_idx].inode_id *
+ (uint64_t)fs->blksz)), zero_buffer,
fs->blksz);
bgd[ibmap_idx].bg_flags =
bgd[ibmap_idx].bg_flags & ~EXT4_BG_INODE_UNINIT;
@@ -1143,7 +1143,7 @@ static void alloc_single_indirect_block(struct ext2_inode *file_inode,
}
/* write the block to disk */
- put_ext4(((uint64_t) (si_blockno * fs->blksz)),
+ put_ext4(((uint64_t) ((uint64_t)si_blockno * (uint64_t)fs->blksz)),
si_start_addr, fs->blksz);
file_inode->b.blocks.indir_block = si_blockno;
}
@@ -1242,7 +1242,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
break;
}
/* write the block table */
- put_ext4(((uint64_t) (di_blockno_child * fs->blksz)),
+ put_ext4(((uint64_t) ((uint64_t)di_blockno_child * (uint64_t)fs->blksz)),
di_child_buff_start, fs->blksz);
free(di_child_buff_start);
di_child_buff_start = NULL;
@@ -1250,7 +1250,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
if (*total_remaining_blocks == 0)
break;
}
- put_ext4(((uint64_t) (di_blockno_parent * fs->blksz)),
+ put_ext4(((uint64_t) ((uint64_t)di_blockno_parent * (uint64_t)fs->blksz)),
di_block_start_addr, fs->blksz);
file_inode->b.blocks.double_indir_block = di_blockno_parent;
}
@@ -1348,8 +1348,8 @@ static void alloc_triple_indirect_block(struct ext2_inode *file_inode,
break;
}
/* write the child block */
- put_ext4(((uint64_t) (ti_child_blockno *
- fs->blksz)),
+ put_ext4(((uint64_t) ((uint64_t)ti_child_blockno *
+ (uint64_t)fs->blksz)),
ti_cbuff_start_addr, fs->blksz);
free(ti_cbuff_start_addr);
@@ -1357,7 +1357,7 @@ static void alloc_triple_indirect_block(struct ext2_inode *file_inode,
break;
}
/* write the parent block */
- put_ext4(((uint64_t) (ti_parent_blockno * fs->blksz)),
+ put_ext4(((uint64_t) ((uint64_t)ti_parent_blockno * (uint64_t)fs->blksz)),
ti_pbuff_start_addr, fs->blksz);
free(ti_pbuff_start_addr);
@@ -1365,7 +1365,7 @@ static void alloc_triple_indirect_block(struct ext2_inode *file_inode,
break;
}
/* write the grand parent block */
- put_ext4(((uint64_t) (ti_gp_blockno * fs->blksz)),
+ put_ext4(((uint64_t) ((uint64_t)ti_gp_blockno * (uint64_t)fs->blksz)),
ti_gp_buff_start_addr, fs->blksz);
file_inode->b.blocks.triple_indir_block = ti_gp_blockno;
}
diff --git a/fs/ext4/ext4_journal.c b/fs/ext4/ext4_journal.c
index d4a46ed..3f61335 100644
--- a/fs/ext4/ext4_journal.c
+++ b/fs/ext4/ext4_journal.c
@@ -371,7 +371,7 @@ void recover_transaction(int prev_desc_logical_no)
blknr = read_allocated_block(&inode_journal, i);
ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
fs->blksz, metadata_buff);
- put_ext4((uint64_t)(be32_to_cpu(tag->block) * fs->blksz),
+ put_ext4((uint64_t)((uint64_t)be32_to_cpu(tag->block) * (uint64_t)fs->blksz),
metadata_buff, (uint32_t) fs->blksz);
} while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG));
fail:
@@ -531,7 +531,7 @@ end:
blknr = read_allocated_block(&inode_journal,
EXT2_JOURNAL_SUPERBLOCK);
- put_ext4((uint64_t) (blknr * fs->blksz),
+ put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz),
(struct journal_superblock_t *)temp_buff,
(uint32_t) fs->blksz);
ext4fs_free_revoke_blks();
@@ -590,7 +590,7 @@ static void update_descriptor_block(long int blknr)
tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_LAST_TAG);
memcpy(temp - sizeof(struct ext3_journal_block_tag), &tag,
sizeof(struct ext3_journal_block_tag));
- put_ext4((uint64_t) (blknr * fs->blksz), buf, (uint32_t) fs->blksz);
+ put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz);
free(temp_buff);
free(buf);
@@ -625,7 +625,7 @@ static void update_commit_block(long int blknr)
return;
}
memcpy(buf, &jdb, sizeof(struct journal_header_t));
- put_ext4((uint64_t) (blknr * fs->blksz), buf, (uint32_t) fs->blksz);
+ put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz);
free(temp_buff);
free(buf);
diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
index 1e1924c..b674b6f 100644
--- a/fs/ext4/ext4_write.c
+++ b/fs/ext4/ext4_write.c
@@ -40,18 +40,18 @@ static void ext4fs_update(void)
/* update block groups */
for (i = 0; i < fs->no_blkgrp; i++) {
fs->bgd[i].bg_checksum = ext4fs_checksum_update(i);
- put_ext4((uint64_t)(fs->bgd[i].block_id * fs->blksz),
+ put_ext4((uint64_t)((uint64_t)fs->bgd[i].block_id * (uint64_t)fs->blksz),
fs->blk_bmaps[i], fs->blksz);
}
/* update inode table groups */
for (i = 0; i < fs->no_blkgrp; i++) {
- put_ext4((uint64_t) (fs->bgd[i].inode_id * fs->blksz),
+ put_ext4((uint64_t) ((uint64_t)fs->bgd[i].inode_id * (uint64_t)fs->blksz),
fs->inode_bmaps[i], fs->blksz);
}
/* update the block group descriptor table */
- put_ext4((uint64_t)(fs->gdtable_blkno * fs->blksz),
+ put_ext4((uint64_t)((uint64_t)fs->gdtable_blkno * (uint64_t)fs->blksz),
(struct ext2_block_group *)fs->gdtable,
(fs->blksz * fs->no_blk_pergdt));
@@ -709,7 +709,7 @@ void ext4fs_deinit(void)
temp_buff);
jsb = (struct journal_superblock_t *)temp_buff;
jsb->s_start = cpu_to_be32(0);
- put_ext4((uint64_t) (blknr * fs->blksz),
+ put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz),
(struct journal_superblock_t *)temp_buff, fs->blksz);
free(temp_buff);
}
@@ -793,7 +793,7 @@ static int ext4fs_write_file(struct ext2_inode *file_inode,
delayed_next += blockend >> log2blksz;
} else { /* spill */
put_ext4((uint64_t)
- (delayed_start << log2blksz),
+ ((uint64_t)delayed_start << log2blksz),
delayed_buf,
(uint32_t) delayed_extent);
previous_block_number = blknr;
@@ -814,7 +814,7 @@ static int ext4fs_write_file(struct ext2_inode *file_inode,
} else {
if (previous_block_number != -1) {
/* spill */
- put_ext4((uint64_t) (delayed_start <<
+ put_ext4((uint64_t) ((uint64_t)delayed_start <<
log2blksz),
delayed_buf,
(uint32_t) delayed_extent);
@@ -826,7 +826,7 @@ static int ext4fs_write_file(struct ext2_inode *file_inode,
}
if (previous_block_number != -1) {
/* spill */
- put_ext4((uint64_t) (delayed_start << log2blksz),
+ put_ext4((uint64_t) ((uint64_t)delayed_start << log2blksz),
delayed_buf, (uint32_t) delayed_extent);
previous_block_number = -1;
}
--
1.8.3.2
More information about the U-Boot
mailing list