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 | |
| 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>
| -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 */ |
