Skip to content

Commit

Permalink
ext4: don't allow overlapping system zones
Browse files Browse the repository at this point in the history
[ Upstream commit bf9a379 ]

Currently, add_system_zone() just silently merges two added system zones
that overlap. However the overlap should not happen and it generally
suggests that some unrelated metadata overlap which indicates the fs is
corrupted. We should have caught such problems earlier (e.g. in
ext4_check_descriptors()) but add this check as another line of defense.
In later patch we also use this for stricter checking of journal inode
extent tree.

Reviewed-by: Lukas Czerner <lczerner@redhat.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20200728130437.7804-3-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
jankara authored and gregkh committed Aug 26, 2020
1 parent ea54176 commit 3473fa1
Showing 1 changed file with 13 additions and 23 deletions.
36 changes: 13 additions & 23 deletions fs/ext4/block_validity.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static int add_system_zone(struct ext4_system_blocks *system_blks,
ext4_fsblk_t start_blk,
unsigned int count)
{
struct ext4_system_zone *new_entry = NULL, *entry;
struct ext4_system_zone *new_entry, *entry;
struct rb_node **n = &system_blks->root.rb_node, *node;
struct rb_node *parent = NULL, *new_node = NULL;

Expand All @@ -79,30 +79,20 @@ static int add_system_zone(struct ext4_system_blocks *system_blks,
n = &(*n)->rb_left;
else if (start_blk >= (entry->start_blk + entry->count))
n = &(*n)->rb_right;
else {
if (start_blk + count > (entry->start_blk +
entry->count))
entry->count = (start_blk + count -
entry->start_blk);
new_node = *n;
new_entry = rb_entry(new_node, struct ext4_system_zone,
node);
break;
}
else /* Unexpected overlap of system zones. */
return -EFSCORRUPTED;
}

if (!new_entry) {
new_entry = kmem_cache_alloc(ext4_system_zone_cachep,
GFP_KERNEL);
if (!new_entry)
return -ENOMEM;
new_entry->start_blk = start_blk;
new_entry->count = count;
new_node = &new_entry->node;

rb_link_node(new_node, parent, n);
rb_insert_color(new_node, &system_blks->root);
}
new_entry = kmem_cache_alloc(ext4_system_zone_cachep,
GFP_KERNEL);
if (!new_entry)
return -ENOMEM;
new_entry->start_blk = start_blk;
new_entry->count = count;
new_node = &new_entry->node;

rb_link_node(new_node, parent, n);
rb_insert_color(new_node, &system_blks->root);

/* Can we merge to the left? */
node = rb_prev(new_node);
Expand Down

0 comments on commit 3473fa1

Please sign in to comment.