今天我在 ext4 树中发现了一个 Linux 内核补丁。
A missing cast means that when we are truncating a file which is less than 60 bytes, we don't trunate the wrong area of memory, and in fact we can end up truncating the next inode in the inode table, or worse yet, some other kernel data structure.
- Addresses-Coverity-Id: #751987
- Signed-off-by: "Theodore Ts'o"
- Cc: stable@vger.kernel.org
fs/ext4/inline.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index c417e52..ed29e72 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -1928,9 +1928,11 @@ void ext4_inline_data_truncate(struct inode *inode, int *has_inline)
}
/* Clear the content within i_blocks. */
- if (i_size < EXT4_MIN_INLINE_DATA_SIZE)
- memset(ext4_raw_inode(&is.iloc)->i_block + i_size, 0,
- EXT4_MIN_INLINE_DATA_SIZE - i_size);
+ if (i_size < EXT4_MIN_INLINE_DATA_SIZE) {
+ void *p = (void *) ext4_raw_inode(&is.iloc)->i_block;
+ memset(p + i_size, 0,
+ EXT4_MIN_INLINE_DATA_SIZE - i_size);
+ }
EXT4_I(inode)->i_inline_size = i_size <
EXT4_MIN_INLINE_DATA_SIZE ?
注意。 i_block 的
类型是__le32
的数组。 i_size
的类型是 long long。
我的问题是:老版本是按4字节计算,新版本是按1字节计算吗?
我的理解正确吗?
最佳答案
因此,让我们采用原始代码,并使其类型对读者非常明确。如果我们这样做,那么我们将查看以下两段代码:
原代码:
__le32 *p = (void *) ext4_raw_inode(&is.iloc)->i_block; memset(p + i_size, 0, EXT4_MIN_INLINE_DATA_SIZE - i_size);
新代码:
void *p = (void *) ext4_raw_inode(&is.iloc)->i_block; memset(p + i_size, 0, EXT4_MIN_INLINE_DATA_SIZE - i_size);
现在,很明显 p + i_size
的值将根据 p
的类型而有所不同,此补丁已修复。
关于gcc中的C void指针计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20980037/