diff options
author | Dmitry Monakhov <dmonakhov@openvz.org> | 2014-04-13 15:41:13 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2014-04-13 15:41:13 -0400 |
commit | a18ed359bdddcded4f97ff5e2f07793ff9336913 (patch) | |
tree | e97441cbb56686a6d6b30cb562435f01ca6ddb8a /fs | |
parent | 8dc79ec4c0537e1b83c0739af82a7babefb30012 (diff) |
ext4: always check ext4_ext_find_extent result
Where are some places where logic guaranties us that extent we are
searching exits, but this may not be true due to on-disk data
corruption. If such corruption happens we must prevent possible
null pointer dereferences.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/extents.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 38be06354b88..64b400356cad 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -3313,6 +3313,11 @@ static int ext4_split_extent(handle_t *handle, | |||
3313 | return PTR_ERR(path); | 3313 | return PTR_ERR(path); |
3314 | depth = ext_depth(inode); | 3314 | depth = ext_depth(inode); |
3315 | ex = path[depth].p_ext; | 3315 | ex = path[depth].p_ext; |
3316 | if (!ex) { | ||
3317 | EXT4_ERROR_INODE(inode, "unexpected hole at %lu", | ||
3318 | (unsigned long) map->m_lblk); | ||
3319 | return -EIO; | ||
3320 | } | ||
3316 | uninitialized = ext4_ext_is_uninitialized(ex); | 3321 | uninitialized = ext4_ext_is_uninitialized(ex); |
3317 | split_flag1 = 0; | 3322 | split_flag1 = 0; |
3318 | 3323 | ||
@@ -3694,6 +3699,12 @@ static int ext4_convert_initialized_extents(handle_t *handle, | |||
3694 | } | 3699 | } |
3695 | depth = ext_depth(inode); | 3700 | depth = ext_depth(inode); |
3696 | ex = path[depth].p_ext; | 3701 | ex = path[depth].p_ext; |
3702 | if (!ex) { | ||
3703 | EXT4_ERROR_INODE(inode, "unexpected hole at %lu", | ||
3704 | (unsigned long) map->m_lblk); | ||
3705 | err = -EIO; | ||
3706 | goto out; | ||
3707 | } | ||
3697 | } | 3708 | } |
3698 | 3709 | ||
3699 | err = ext4_ext_get_access(handle, inode, path + depth); | 3710 | err = ext4_ext_get_access(handle, inode, path + depth); |
@@ -5340,6 +5351,12 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, | |||
5340 | return PTR_ERR(path); | 5351 | return PTR_ERR(path); |
5341 | depth = path->p_depth; | 5352 | depth = path->p_depth; |
5342 | extent = path[depth].p_ext; | 5353 | extent = path[depth].p_ext; |
5354 | if (!extent) { | ||
5355 | EXT4_ERROR_INODE(inode, "unexpected hole at %lu", | ||
5356 | (unsigned long) start); | ||
5357 | return -EIO; | ||
5358 | } | ||
5359 | |||
5343 | current_block = le32_to_cpu(extent->ee_block); | 5360 | current_block = le32_to_cpu(extent->ee_block); |
5344 | if (start > current_block) { | 5361 | if (start > current_block) { |
5345 | /* Hole, move to the next extent */ | 5362 | /* Hole, move to the next extent */ |