From 0550870b1c590be6beb09b57762ec43b5516f7d1 Mon Sep 17 00:00:00 2001 From: Ma Haijun Date: Wed, 8 Jan 2014 08:15:33 +0800 Subject: fs/ext4: fix calling put_ext4 with truncated offset 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 --- fs/ext4/ext4_common.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'fs/ext4/ext4_common.c') diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c index 352943ec5..cff50d8c1 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; } -- cgit v1.2.3-70-g09d2