From patchwork Thu Sep 20 10:32:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hildenbrand X-Patchwork-Id: 10607377 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D49BC1390 for ; Thu, 20 Sep 2018 10:37:22 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C35092CCD9 for ; Thu, 20 Sep 2018 10:37:22 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B6F262CCFB; Thu, 20 Sep 2018 10:37:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4F0D02CCF5 for ; Thu, 20 Sep 2018 10:37:22 +0000 (UTC) Received: from localhost ([::1]:49357 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g2wKn-00069H-21 for patchwork-qemu-devel@patchwork.kernel.org; Thu, 20 Sep 2018 06:37:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32778) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g2wGd-0002TY-V2 for qemu-devel@nongnu.org; Thu, 20 Sep 2018 06:33:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g2wGc-0005za-Ce for qemu-devel@nongnu.org; Thu, 20 Sep 2018 06:33:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41526) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1g2wGc-0005zB-4I; Thu, 20 Sep 2018 06:33:02 -0400 Received: from smtp.corp.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 58FA25D5EA; Thu, 20 Sep 2018 10:33:01 +0000 (UTC) Received: from t460s.redhat.com (ovpn-117-43.ams2.redhat.com [10.36.117.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id D29F43091327; Thu, 20 Sep 2018 10:32:57 +0000 (UTC) From: David Hildenbrand To: qemu-devel@nongnu.org Date: Thu, 20 Sep 2018 12:32:23 +0200 Message-Id: <20180920103243.28474-3-david@redhat.com> In-Reply-To: <20180920103243.28474-1-david@redhat.com> References: <20180920103243.28474-1-david@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.26 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 20 Sep 2018 10:33:01 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 02/22] memory-device: handle integer overflows properly 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: Pankaj Gupta , Eduardo Habkost , "Michael S . Tsirkin" , Xiao Guangrong , David Hildenbrand , "Dr . David Alan Gilbert" , Markus Armbruster , Alexander Graf , qemu-ppc@nongnu.org, Paolo Bonzini , Igor Mammedov , Luiz Capitulino , David Gibson , Richard Henderson Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Although unlikely in practice, we could have integer overflows on some calculations based on addresses and sizes, leading to error checks not triggering. Let's properly handle this whenever we do an addition. Make address_space_end point at the real end, instead of end + 1, so we don't have to handle special cases like it being 0. This will allow us to place a memory device at the very end of the guest physical 64bit address space (if ever possible). Also, QEMU_ALIGN_UP(md_addr + md_size, align) could (theoretically) wrap to address 0, so add a final check for 0. Reported-by: Dr. David Alan Gilbert Signed-off-by: David Hildenbrand Reviewed-by: David Gibson --- hw/mem/memory-device.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c index efacbc2a7d..020aad102a 100644 --- a/hw/mem/memory-device.c +++ b/hw/mem/memory-device.c @@ -85,7 +85,8 @@ static void memory_device_check_addable(MachineState *ms, uint64_t size, /* will we exceed the total amount of memory specified */ memory_device_used_region_size(OBJECT(ms), &used_region_size); - if (used_region_size + size > ms->maxram_size - ms->ram_size) { + if (used_region_size + size < used_region_size || + used_region_size + size > ms->maxram_size - ms->ram_size) { error_setg(errp, "not enough space, currently 0x%" PRIx64 " in use of total hot pluggable 0x" RAM_ADDR_FMT, used_region_size, ms->maxram_size - ms->ram_size); @@ -115,7 +116,7 @@ uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint, } address_space_start = ms->device_memory->base; address_space_end = address_space_start + - memory_region_size(&ms->device_memory->mr); + memory_region_size(&ms->device_memory->mr) - 1; g_assert(address_space_end >= address_space_start); /* address_space_start indicates the maximum alignment we expect */ @@ -149,7 +150,8 @@ uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint, "] before 0x%" PRIx64, new_addr, size, address_space_start); return 0; - } else if ((new_addr + size) > address_space_end) { + } else if (new_addr + size - 1 < new_addr || + new_addr + size - 1 > address_space_end) { error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64 "] beyond 0x%" PRIx64, new_addr, size, address_space_end); @@ -182,7 +184,8 @@ uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint, } } - if (new_addr + size > address_space_end) { + if (new_addr + size - 1 < new_addr || !new_addr || + new_addr + size - 1 > address_space_end) { error_setg(errp, "could not find position in guest address space for " "memory device - memory fragmented due to alignments"); goto out;