Skip to content
Snippets Groups Projects
Commit 0550870b authored by Ma Haijun's avatar Ma Haijun Committed by Tom Rini
Browse files

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: default avatarMa Haijun <mahaijuns@gmail.com>
parent f1782883
Branches
Tags
No related merge requests found
...@@ -445,9 +445,9 @@ restart: ...@@ -445,9 +445,9 @@ restart:
goto fail; goto fail;
} }
put_ext4(((uint64_t) put_ext4(((uint64_t)
(g_parent_inode->b. ((uint64_t)g_parent_inode->b.
blocks.dir_blocks[direct_blk_idx] * 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 =
g_parent_inode->size + fs->blksz; g_parent_inode->size + fs->blksz;
g_parent_inode->blockcnt = g_parent_inode->blockcnt =
...@@ -864,8 +864,8 @@ long int ext4fs_get_new_blk_no(void) ...@@ -864,8 +864,8 @@ long int ext4fs_get_new_blk_no(void)
for (i = 0; i < fs->no_blkgrp; i++) { for (i = 0; i < fs->no_blkgrp; i++) {
if (bgd[i].free_blocks) { if (bgd[i].free_blocks) {
if (bgd[i].bg_flags & EXT4_BG_BLOCK_UNINIT) { if (bgd[i].bg_flags & EXT4_BG_BLOCK_UNINIT) {
put_ext4(((uint64_t) (bgd[i].block_id * put_ext4(((uint64_t) ((uint64_t)bgd[i].block_id *
fs->blksz)), (uint64_t)fs->blksz)),
zero_buffer, fs->blksz); zero_buffer, fs->blksz);
bgd[i].bg_flags = bgd[i].bg_flags =
bgd[i]. bgd[i].
...@@ -929,8 +929,8 @@ restart: ...@@ -929,8 +929,8 @@ restart:
if (bgd[bg_idx].bg_flags & EXT4_BG_BLOCK_UNINIT) { if (bgd[bg_idx].bg_flags & EXT4_BG_BLOCK_UNINIT) {
memset(zero_buffer, '\0', fs->blksz); memset(zero_buffer, '\0', fs->blksz);
put_ext4(((uint64_t) (bgd[bg_idx].block_id * put_ext4(((uint64_t) ((uint64_t)bgd[bg_idx].block_id *
fs->blksz)), zero_buffer, fs->blksz); (uint64_t)fs->blksz)), zero_buffer, fs->blksz);
memcpy(fs->blk_bmaps[bg_idx], zero_buffer, fs->blksz); memcpy(fs->blk_bmaps[bg_idx], zero_buffer, fs->blksz);
bgd[bg_idx].bg_flags = bgd[bg_idx].bg_flags & bgd[bg_idx].bg_flags = bgd[bg_idx].bg_flags &
~EXT4_BG_BLOCK_UNINIT; ~EXT4_BG_BLOCK_UNINIT;
...@@ -996,8 +996,8 @@ int ext4fs_get_new_inode_no(void) ...@@ -996,8 +996,8 @@ int ext4fs_get_new_inode_no(void)
bgd[i].free_inodes; bgd[i].free_inodes;
if (bgd[i].bg_flags & EXT4_BG_INODE_UNINIT) { if (bgd[i].bg_flags & EXT4_BG_INODE_UNINIT) {
put_ext4(((uint64_t) put_ext4(((uint64_t)
(bgd[i].inode_id * ((uint64_t)bgd[i].inode_id *
fs->blksz)), (uint64_t)fs->blksz)),
zero_buffer, fs->blksz); zero_buffer, fs->blksz);
bgd[i].bg_flags = bgd[i].bg_flags & bgd[i].bg_flags = bgd[i].bg_flags &
~EXT4_BG_INODE_UNINIT; ~EXT4_BG_INODE_UNINIT;
...@@ -1037,8 +1037,8 @@ restart: ...@@ -1037,8 +1037,8 @@ restart:
ibmap_idx = fs->curr_inode_no / inodes_per_grp; ibmap_idx = fs->curr_inode_no / inodes_per_grp;
if (bgd[ibmap_idx].bg_flags & EXT4_BG_INODE_UNINIT) { if (bgd[ibmap_idx].bg_flags & EXT4_BG_INODE_UNINIT) {
memset(zero_buffer, '\0', fs->blksz); memset(zero_buffer, '\0', fs->blksz);
put_ext4(((uint64_t) (bgd[ibmap_idx].inode_id * put_ext4(((uint64_t) ((uint64_t)bgd[ibmap_idx].inode_id *
fs->blksz)), zero_buffer, (uint64_t)fs->blksz)), zero_buffer,
fs->blksz); fs->blksz);
bgd[ibmap_idx].bg_flags = bgd[ibmap_idx].bg_flags =
bgd[ibmap_idx].bg_flags & ~EXT4_BG_INODE_UNINIT; bgd[ibmap_idx].bg_flags & ~EXT4_BG_INODE_UNINIT;
...@@ -1143,7 +1143,7 @@ static void alloc_single_indirect_block(struct ext2_inode *file_inode, ...@@ -1143,7 +1143,7 @@ static void alloc_single_indirect_block(struct ext2_inode *file_inode,
} }
/* write the block to disk */ /* 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); si_start_addr, fs->blksz);
file_inode->b.blocks.indir_block = si_blockno; file_inode->b.blocks.indir_block = si_blockno;
} }
...@@ -1242,7 +1242,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode, ...@@ -1242,7 +1242,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
break; break;
} }
/* write the block table */ /* 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); di_child_buff_start, fs->blksz);
free(di_child_buff_start); free(di_child_buff_start);
di_child_buff_start = NULL; di_child_buff_start = NULL;
...@@ -1250,7 +1250,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode, ...@@ -1250,7 +1250,7 @@ static void alloc_double_indirect_block(struct ext2_inode *file_inode,
if (*total_remaining_blocks == 0) if (*total_remaining_blocks == 0)
break; 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); di_block_start_addr, fs->blksz);
file_inode->b.blocks.double_indir_block = di_blockno_parent; 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, ...@@ -1348,8 +1348,8 @@ static void alloc_triple_indirect_block(struct ext2_inode *file_inode,
break; break;
} }
/* write the child block */ /* write the child block */
put_ext4(((uint64_t) (ti_child_blockno * put_ext4(((uint64_t) ((uint64_t)ti_child_blockno *
fs->blksz)), (uint64_t)fs->blksz)),
ti_cbuff_start_addr, fs->blksz); ti_cbuff_start_addr, fs->blksz);
free(ti_cbuff_start_addr); free(ti_cbuff_start_addr);
...@@ -1357,7 +1357,7 @@ static void alloc_triple_indirect_block(struct ext2_inode *file_inode, ...@@ -1357,7 +1357,7 @@ static void alloc_triple_indirect_block(struct ext2_inode *file_inode,
break; break;
} }
/* write the parent block */ /* 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); ti_pbuff_start_addr, fs->blksz);
free(ti_pbuff_start_addr); free(ti_pbuff_start_addr);
...@@ -1365,7 +1365,7 @@ static void alloc_triple_indirect_block(struct ext2_inode *file_inode, ...@@ -1365,7 +1365,7 @@ static void alloc_triple_indirect_block(struct ext2_inode *file_inode,
break; break;
} }
/* write the grand parent block */ /* 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); ti_gp_buff_start_addr, fs->blksz);
file_inode->b.blocks.triple_indir_block = ti_gp_blockno; file_inode->b.blocks.triple_indir_block = ti_gp_blockno;
} }
......
...@@ -371,7 +371,7 @@ void recover_transaction(int prev_desc_logical_no) ...@@ -371,7 +371,7 @@ void recover_transaction(int prev_desc_logical_no)
blknr = read_allocated_block(&inode_journal, i); blknr = read_allocated_block(&inode_journal, i);
ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
fs->blksz, metadata_buff); 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); metadata_buff, (uint32_t) fs->blksz);
} while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG)); } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG));
fail: fail:
...@@ -531,7 +531,7 @@ end: ...@@ -531,7 +531,7 @@ end:
blknr = read_allocated_block(&inode_journal, blknr = read_allocated_block(&inode_journal,
EXT2_JOURNAL_SUPERBLOCK); 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, (struct journal_superblock_t *)temp_buff,
(uint32_t) fs->blksz); (uint32_t) fs->blksz);
ext4fs_free_revoke_blks(); ext4fs_free_revoke_blks();
...@@ -590,7 +590,7 @@ static void update_descriptor_block(long int blknr) ...@@ -590,7 +590,7 @@ static void update_descriptor_block(long int blknr)
tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_LAST_TAG); tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_LAST_TAG);
memcpy(temp - sizeof(struct ext3_journal_block_tag), &tag, memcpy(temp - sizeof(struct ext3_journal_block_tag), &tag,
sizeof(struct ext3_journal_block_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(temp_buff);
free(buf); free(buf);
...@@ -625,7 +625,7 @@ static void update_commit_block(long int blknr) ...@@ -625,7 +625,7 @@ static void update_commit_block(long int blknr)
return; return;
} }
memcpy(buf, &jdb, sizeof(struct journal_header_t)); 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(temp_buff);
free(buf); free(buf);
......
...@@ -40,18 +40,18 @@ static void ext4fs_update(void) ...@@ -40,18 +40,18 @@ static void ext4fs_update(void)
/* update block groups */ /* update block groups */
for (i = 0; i < fs->no_blkgrp; i++) { for (i = 0; i < fs->no_blkgrp; i++) {
fs->bgd[i].bg_checksum = ext4fs_checksum_update(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); fs->blk_bmaps[i], fs->blksz);
} }
/* update inode table groups */ /* update inode table groups */
for (i = 0; i < fs->no_blkgrp; i++) { 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); fs->inode_bmaps[i], fs->blksz);
} }
/* update the block group descriptor table */ /* 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, (struct ext2_block_group *)fs->gdtable,
(fs->blksz * fs->no_blk_pergdt)); (fs->blksz * fs->no_blk_pergdt));
...@@ -709,7 +709,7 @@ void ext4fs_deinit(void) ...@@ -709,7 +709,7 @@ void ext4fs_deinit(void)
temp_buff); temp_buff);
jsb = (struct journal_superblock_t *)temp_buff; jsb = (struct journal_superblock_t *)temp_buff;
jsb->s_start = cpu_to_be32(0); 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); (struct journal_superblock_t *)temp_buff, fs->blksz);
free(temp_buff); free(temp_buff);
} }
...@@ -793,7 +793,7 @@ static int ext4fs_write_file(struct ext2_inode *file_inode, ...@@ -793,7 +793,7 @@ static int ext4fs_write_file(struct ext2_inode *file_inode,
delayed_next += blockend >> log2blksz; delayed_next += blockend >> log2blksz;
} else { /* spill */ } else { /* spill */
put_ext4((uint64_t) put_ext4((uint64_t)
(delayed_start << log2blksz), ((uint64_t)delayed_start << log2blksz),
delayed_buf, delayed_buf,
(uint32_t) delayed_extent); (uint32_t) delayed_extent);
previous_block_number = blknr; previous_block_number = blknr;
...@@ -814,7 +814,7 @@ static int ext4fs_write_file(struct ext2_inode *file_inode, ...@@ -814,7 +814,7 @@ static int ext4fs_write_file(struct ext2_inode *file_inode,
} else { } else {
if (previous_block_number != -1) { if (previous_block_number != -1) {
/* spill */ /* spill */
put_ext4((uint64_t) (delayed_start << put_ext4((uint64_t) ((uint64_t)delayed_start <<
log2blksz), log2blksz),
delayed_buf, delayed_buf,
(uint32_t) delayed_extent); (uint32_t) delayed_extent);
...@@ -826,7 +826,7 @@ static int ext4fs_write_file(struct ext2_inode *file_inode, ...@@ -826,7 +826,7 @@ static int ext4fs_write_file(struct ext2_inode *file_inode,
} }
if (previous_block_number != -1) { if (previous_block_number != -1) {
/* spill */ /* spill */
put_ext4((uint64_t) (delayed_start << log2blksz), put_ext4((uint64_t) ((uint64_t)delayed_start << log2blksz),
delayed_buf, (uint32_t) delayed_extent); delayed_buf, (uint32_t) delayed_extent);
previous_block_number = -1; previous_block_number = -1;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment