From patchwork Sun Sep 30 08:12:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 976850 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="i+vTWY6D"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42NKC13RKJz9s1x for ; Sun, 30 Sep 2018 19:01:01 +1000 (AEST) Received: from localhost ([::1]:54480 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g6Xb1-0005j7-4k for incoming@patchwork.ozlabs.org; Sun, 30 Sep 2018 05:00:59 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41689) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g6Ws8-0002xu-9j for qemu-devel@nongnu.org; Sun, 30 Sep 2018 04:14:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g6Ws6-0001CL-9m for qemu-devel@nongnu.org; Sun, 30 Sep 2018 04:14:36 -0400 Received: from mail-wr1-x434.google.com ([2a00:1450:4864:20::434]:36651) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g6Ws2-0000y2-MS for qemu-devel@nongnu.org; Sun, 30 Sep 2018 04:14:31 -0400 Received: by mail-wr1-x434.google.com with SMTP id y16so2236988wrw.3 for ; Sun, 30 Sep 2018 01:14:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=He3vaZTf1Q0Lfqm60FMzWJRldFGWAIuGtHyXwIDUN00=; b=i+vTWY6DDpH3jgQAE+28OxBte5WxYVudoeL8DluQkJ6WeV3oEeQ3WH5lZmaP/R+DWH OUf/5dTPJum/zFWoX78sUNjfPkryJOVEf3XsL0Zy36353gHKtjPD/JUzc+8NUubGlG8v D3lubRyjoIdZvYFJl9vcq4w2jmyPc9rHWmO8NQ36wPgp0gMciskHm4ldHzceGi7QKy1Q mgLspZ+W6lubAtTCxGVb+k+3BrnZJYyKtEfxWS9HVtYSEX6+YsJvRalT6WKvigq+mtXb bOp67hECnIU0GiGzD+zw9W63QC878BKc4sxrD2AD+LcYx7HwNAoXiczYuu8DGs6igHfG QvEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=He3vaZTf1Q0Lfqm60FMzWJRldFGWAIuGtHyXwIDUN00=; b=tFvcLciwvOIuZ/IJos4VU/XrcKY92C/eKKy5CTT1fojQpFUkmpt4xzqNK36CLGtXGa Jb2XWAmGzN+svffizVpXh83rbhNK54f69i21LVi2SQNp8plcUFQKPwvqjHA2MNVete2J TaD9pQAySPPpdW2WDlNEIpRftCXQtatCOeY4FyywII+dDtGI366op9xfnOy8FAvem6MJ NzWd51I5HPHlr5DKYlmhGbgLgOfpO8dRX9txWEcfgxnUKmQEJ9zmP2Lmh6Yv0ivV/Ipg UMfvKj/0DWaEaQ9lkkioDPr/A4uxXPCeBxPGDnthO04T4BcweyXz9ZJn+OuQ11CBrOKL JA6w== X-Gm-Message-State: ABuFfogHb10q9ujhjE/gP91QEJ0+yugAJjsL8wlyQosPUwGB861tm5HS V+loin57dSk74Kn6/OYrojFIhp3U X-Google-Smtp-Source: ACcGV611dPAb056kz30rDLblOQ9yoGD+URj5sySjf7mLeqHyqf5H8+hSoSK4mdETcgTXzuHaV74ZLA== X-Received: by 2002:adf:9f0f:: with SMTP id l15-v6mr3823786wrf.206.1538295251389; Sun, 30 Sep 2018 01:14:11 -0700 (PDT) Received: from 640k.lan (94-36-187-248.adsl-ull.clienti.tiscali.it. [94.36.187.248]) by smtp.gmail.com with ESMTPSA id u76-v6sm11369194wmd.10.2018.09.30.01.14.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 30 Sep 2018 01:14:10 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Sun, 30 Sep 2018 10:12:47 +0200 Message-Id: <1538295197-23704-50-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1538295197-23704-1-git-send-email-pbonzini@redhat.com> References: <1538295197-23704-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::434 Subject: [Qemu-devel] [PULL 49/79] memory: cleanup side effects of memory_region_init_foo() on failure X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Igor Mammedov Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Igor Mammedov 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) Signed-off-by: Igor Mammedov Message-Id: <1536064777-42312-1-git-send-email-imammedo@redhat.com> Signed-off-by: Paolo Bonzini --- memory.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/memory.c b/memory.c index 9b73892..aceadb2 100644 --- a/memory.c +++ b/memory.c @@ -1518,12 +1518,18 @@ void memory_region_init_ram_shared_nomigrate(MemoryRegion *mr, bool share, Error **errp) { + Error *err = NULL; memory_region_init(mr, owner, name, size); mr->ram = true; mr->terminates = true; mr->destructor = memory_region_destructor_ram; - mr->ram_block = qemu_ram_alloc(size, share, mr, errp); + mr->ram_block = qemu_ram_alloc(size, share, mr, &err); mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0; + if (err) { + mr->size = int128_zero(); + object_unparent(OBJECT(mr)); + error_propagate(errp, err); + } } void memory_region_init_resizeable_ram(MemoryRegion *mr, @@ -1536,13 +1542,19 @@ void memory_region_init_resizeable_ram(MemoryRegion *mr, void *host), Error **errp) { + Error *err = NULL; memory_region_init(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() ? (1 << DIRTY_MEMORY_CODE) : 0; + if (err) { + mr->size = int128_zero(); + object_unparent(OBJECT(mr)); + error_propagate(errp, err); + } } #ifdef __linux__ @@ -1555,13 +1567,19 @@ void memory_region_init_ram_from_file(MemoryRegion *mr, const char *path, Error **errp) { + Error *err = NULL; memory_region_init(mr, owner, name, size); mr->ram = true; mr->terminates = true; mr->destructor = memory_region_destructor_ram; mr->align = align; - mr->ram_block = qemu_ram_alloc_from_file(size, mr, ram_flags, path, errp); + mr->ram_block = qemu_ram_alloc_from_file(size, mr, ram_flags, path, &err); mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0; + if (err) { + mr->size = int128_zero(); + object_unparent(OBJECT(mr)); + error_propagate(errp, err); + } } void memory_region_init_ram_from_fd(MemoryRegion *mr, @@ -1572,14 +1590,20 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr, int fd, Error **errp) { + Error *err = NULL; memory_region_init(mr, owner, name, size); mr->ram = true; mr->terminates = true; mr->destructor = memory_region_destructor_ram; mr->ram_block = qemu_ram_alloc_from_fd(size, mr, share ? RAM_SHARED : 0, - fd, errp); + fd, &err); mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0; + if (err) { + mr->size = int128_zero(); + object_unparent(OBJECT(mr)); + error_propagate(errp, err); + } } #endif @@ -1630,13 +1654,19 @@ void memory_region_init_rom_nomigrate(MemoryRegion *mr, uint64_t size, Error **errp) { + Error *err = NULL; memory_region_init(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, false, mr, errp); + mr->ram_block = qemu_ram_alloc(size, false, mr, &err); mr->dirty_log_mask = tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0; + if (err) { + mr->size = int128_zero(); + object_unparent(OBJECT(mr)); + error_propagate(errp, err); + } } void memory_region_init_rom_device_nomigrate(MemoryRegion *mr, @@ -1647,6 +1677,7 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr, uint64_t size, Error **errp) { + Error *err = NULL; assert(ops); memory_region_init(mr, owner, name, size); mr->ops = ops; @@ -1654,7 +1685,12 @@ void memory_region_init_rom_device_nomigrate(MemoryRegion *mr, mr->terminates = true; mr->rom_device = true; mr->destructor = memory_region_destructor_ram; - mr->ram_block = qemu_ram_alloc(size, false, mr, errp); + mr->ram_block = qemu_ram_alloc(size, false, mr, &err); + if (err) { + mr->size = int128_zero(); + object_unparent(OBJECT(mr)); + error_propagate(errp, err); + } } void memory_region_init_iommu(void *_iommu_mr,