mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
ext4: don't allow overlapping system zones
commit bf9a379d09 upstream.
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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
d01b5fc061
commit
f175d63724
@@ -57,7 +57,7 @@ static int add_system_zone(struct ext4_sb_info *sbi,
|
||||
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 = &sbi->system_blks.rb_node, *node;
|
||||
struct rb_node *parent = NULL, *new_node = NULL;
|
||||
|
||||
@@ -68,30 +68,20 @@ static int add_system_zone(struct ext4_sb_info *sbi,
|
||||
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;
|
||||
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, &sbi->system_blks);
|
||||
}
|
||||
rb_link_node(new_node, parent, n);
|
||||
rb_insert_color(new_node, &sbi->system_blks);
|
||||
|
||||
/* Can we merge to the left? */
|
||||
node = rb_prev(new_node);
|
||||
|
||||
Reference in New Issue
Block a user