memory: cleanup side effects of memory_region_init_foo() on failure

if MemoryRegion intialization fails it's left in semi-initialized state,
where it's size is not 0 and attached as child to owner object.
And this leds to crash in following use-case:
    (monitor) object_add memory-backend-file,id=mem1,size=99999G,mem-path=/tmp/foo,discard-data=yes
    memory.c:2083: memory_region_get_ram_ptr: Assertion `mr->ram_block' failed
    Aborted (core dumped)
it happens due to assumption that memory region is intialized when
memory_region_size() != 0
and therefore it's ok to access it in
file_backend_unparent()
    if (memory_region_size() != 0)
        memory_region_get_ram_ptr()

which happens when object_add fails and unparents failed backend making
file_backend_unparent() access invalid memory region.

Fix it by making sure that memory_region_init_foo() APIs cleanup externally
visible side effects on failure (like set size to 0 and unparenting object)
This commit is contained in:
Igor Mammedov 2018-10-04 04:10:57 -04:00 committed by Lioncash
parent 0242d19e79
commit 68356c69fc
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
15 changed files with 21 additions and 17 deletions

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_aarch64
#define object_set_link_property object_set_link_property_aarch64
#define object_type_get_instance_size object_type_get_instance_size_aarch64
#define object_unparent object_unparent_aarch64
#define omap_cachemaint_write omap_cachemaint_write_aarch64
#define omap_cp_reginfo omap_cp_reginfo_aarch64
#define omap_threadid_write omap_threadid_write_aarch64

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_aarch64eb
#define object_set_link_property object_set_link_property_aarch64eb
#define object_type_get_instance_size object_type_get_instance_size_aarch64eb
#define object_unparent object_unparent_aarch64eb
#define omap_cachemaint_write omap_cachemaint_write_aarch64eb
#define omap_cp_reginfo omap_cp_reginfo_aarch64eb
#define omap_threadid_write omap_threadid_write_aarch64eb

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_arm
#define object_set_link_property object_set_link_property_arm
#define object_type_get_instance_size object_type_get_instance_size_arm
#define object_unparent object_unparent_arm
#define omap_cachemaint_write omap_cachemaint_write_arm
#define omap_cp_reginfo omap_cp_reginfo_arm
#define omap_threadid_write omap_threadid_write_arm

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_armeb
#define object_set_link_property object_set_link_property_armeb
#define object_type_get_instance_size object_type_get_instance_size_armeb
#define object_unparent object_unparent_armeb
#define omap_cachemaint_write omap_cachemaint_write_armeb
#define omap_cp_reginfo omap_cp_reginfo_armeb
#define omap_threadid_write omap_threadid_write_armeb

View file

@ -2115,7 +2115,6 @@ symbols = (
'object_resolve_path_type',
'object_set_link_property',
'object_type_get_instance_size',
'object_unparent',
'omap_cachemaint_write',
'omap_cp_reginfo',
'omap_threadid_write',

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_m68k
#define object_set_link_property object_set_link_property_m68k
#define object_type_get_instance_size object_type_get_instance_size_m68k
#define object_unparent object_unparent_m68k
#define omap_cachemaint_write omap_cachemaint_write_m68k
#define omap_cp_reginfo omap_cp_reginfo_m68k
#define omap_threadid_write omap_threadid_write_m68k

View file

@ -1382,6 +1382,7 @@ void memory_region_init_ram_nomigrate(struct uc_struct *uc,
uint32_t perms,
Error **errp)
{
Error *err = NULL;
memory_region_init(uc, mr, owner, name, size);
mr->ram = true;
if (!(perms & UC_PROT_WRITE)) {
@ -1390,8 +1391,13 @@ void memory_region_init_ram_nomigrate(struct uc_struct *uc,
mr->perms = perms;
mr->terminates = true;
mr->destructor = memory_region_destructor_ram;
mr->ram_block = qemu_ram_alloc(size, mr, errp);
mr->ram_block = qemu_ram_alloc(size, mr, &err);
mr->dirty_log_mask = tcg_enabled(uc) ? (1 << DIRTY_MEMORY_CODE) : 0;
if (err) {
mr->size = int128_zero();
object_unparent(uc, OBJECT(mr));
error_propagate(errp, err);
}
}
void memory_region_init_ram_ptr(struct uc_struct *uc, MemoryRegion *mr,
@ -1422,13 +1428,19 @@ void memory_region_init_resizeable_ram(struct uc_struct *uc,
void *host),
Error **errp)
{
Error *err = NULL;
memory_region_init(uc, mr, owner, name, size);
mr->ram = true;
mr->terminates = true;
mr->destructor = memory_region_destructor_ram;
mr->ram_block = qemu_ram_alloc_resizeable(size, max_size, resized,
mr, errp);
mr, &err);
mr->dirty_log_mask = tcg_enabled(uc) ? (1 << DIRTY_MEMORY_CODE) : 0;
if (err) {
mr->size = int128_zero();
object_unparent(uc, OBJECT(mr));
error_propagate(errp, err);
}
}
void memory_region_init_rom_nomigrate(struct uc_struct *uc,
@ -1438,13 +1450,19 @@ void memory_region_init_rom_nomigrate(struct uc_struct *uc,
uint64_t size,
Error **errp)
{
Error *err = NULL;
memory_region_init(uc, mr, owner, name, size);
mr->ram = true;
mr->readonly = true;
mr->terminates = true;
mr->destructor = memory_region_destructor_ram;
mr->ram_block = qemu_ram_alloc(size, mr, errp);
mr->ram_block = qemu_ram_alloc(size, mr, &err);
mr->dirty_log_mask = tcg_enabled(uc) ? (1 << DIRTY_MEMORY_CODE) : 0;
if (err) {
mr->size = int128_zero();
object_unparent(uc, OBJECT(mr));
error_propagate(errp, err);
}
}
void memory_region_init_ram_device_ptr(struct uc_struct *uc,

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_mips
#define object_set_link_property object_set_link_property_mips
#define object_type_get_instance_size object_type_get_instance_size_mips
#define object_unparent object_unparent_mips
#define omap_cachemaint_write omap_cachemaint_write_mips
#define omap_cp_reginfo omap_cp_reginfo_mips
#define omap_threadid_write omap_threadid_write_mips

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_mips64
#define object_set_link_property object_set_link_property_mips64
#define object_type_get_instance_size object_type_get_instance_size_mips64
#define object_unparent object_unparent_mips64
#define omap_cachemaint_write omap_cachemaint_write_mips64
#define omap_cp_reginfo omap_cp_reginfo_mips64
#define omap_threadid_write omap_threadid_write_mips64

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_mips64el
#define object_set_link_property object_set_link_property_mips64el
#define object_type_get_instance_size object_type_get_instance_size_mips64el
#define object_unparent object_unparent_mips64el
#define omap_cachemaint_write omap_cachemaint_write_mips64el
#define omap_cp_reginfo omap_cp_reginfo_mips64el
#define omap_threadid_write omap_threadid_write_mips64el

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_mipsel
#define object_set_link_property object_set_link_property_mipsel
#define object_type_get_instance_size object_type_get_instance_size_mipsel
#define object_unparent object_unparent_mipsel
#define omap_cachemaint_write omap_cachemaint_write_mipsel
#define omap_cp_reginfo omap_cp_reginfo_mipsel
#define omap_threadid_write omap_threadid_write_mipsel

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_powerpc
#define object_set_link_property object_set_link_property_powerpc
#define object_type_get_instance_size object_type_get_instance_size_powerpc
#define object_unparent object_unparent_powerpc
#define omap_cachemaint_write omap_cachemaint_write_powerpc
#define omap_cp_reginfo omap_cp_reginfo_powerpc
#define omap_threadid_write omap_threadid_write_powerpc

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_sparc
#define object_set_link_property object_set_link_property_sparc
#define object_type_get_instance_size object_type_get_instance_size_sparc
#define object_unparent object_unparent_sparc
#define omap_cachemaint_write omap_cachemaint_write_sparc
#define omap_cp_reginfo omap_cp_reginfo_sparc
#define omap_threadid_write omap_threadid_write_sparc

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_sparc64
#define object_set_link_property object_set_link_property_sparc64
#define object_type_get_instance_size object_type_get_instance_size_sparc64
#define object_unparent object_unparent_sparc64
#define omap_cachemaint_write omap_cachemaint_write_sparc64
#define omap_cp_reginfo omap_cp_reginfo_sparc64
#define omap_threadid_write omap_threadid_write_sparc64

View file

@ -2109,7 +2109,6 @@
#define object_resolve_path_type object_resolve_path_type_x86_64
#define object_set_link_property object_set_link_property_x86_64
#define object_type_get_instance_size object_type_get_instance_size_x86_64
#define object_unparent object_unparent_x86_64
#define omap_cachemaint_write omap_cachemaint_write_x86_64
#define omap_cp_reginfo omap_cp_reginfo_x86_64
#define omap_threadid_write omap_threadid_write_x86_64