From patchwork Wed Jun 24 10:50:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 279584 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 41EF2C433DF for ; Wed, 24 Jun 2020 10:54:32 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 11B3820CC7 for ; Wed, 24 Jun 2020 10:54:32 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="P4kEQ2GV" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 11B3820CC7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:34758 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jo331-0007qb-80 for qemu-devel@archiver.kernel.org; Wed, 24 Jun 2020 06:54:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56458) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jo2zf-0000ul-PL for qemu-devel@nongnu.org; Wed, 24 Jun 2020 06:51:03 -0400 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:39306 helo=us-smtp-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1jo2zd-0001Eq-Ow for qemu-devel@nongnu.org; Wed, 24 Jun 2020 06:51:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1592995861; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Q9Je4/GAg4SH4ewN1aBvGsdOoDw32X/9E7go6c+n/Uk=; b=P4kEQ2GVdxnpqEc7t4t7oFQEvCTa624bS6vQu0NJHsHMG/xjg/6Sz739SRd+RT+fvzrXFh j6/+wBGIkh9y6Hro4RrSaqvmrQDwfYsdxeHfPLd94TrjolNNt8CNTdcsJZumhES7Jm8Ygg +hShBOZgW31fkqyjmEiveEmZsAC3Y44= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-223-lDTrkSTPPcC5AwSzj00fzA-1; Wed, 24 Jun 2020 06:50:58 -0400 X-MC-Unique: lDTrkSTPPcC5AwSzj00fzA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id D325A87950F; Wed, 24 Jun 2020 10:50:57 +0000 (UTC) Received: from virtlab511.virt.lab.eng.bos.redhat.com (virtlab511.virt.lab.eng.bos.redhat.com [10.19.152.198]) by smtp.corp.redhat.com (Postfix) with ESMTP id 883681DC; Wed, 24 Jun 2020 10:50:54 +0000 (UTC) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 05/31] memory: Revert "memory: accept mismatching sizes in memory_region_access_valid" Date: Wed, 24 Jun 2020 06:50:22 -0400 Message-Id: <20200624105048.375353-5-pbonzini@redhat.com> In-Reply-To: <20200624104917.375143-1-pbonzini@redhat.com> References: <20200624104917.375143-1-pbonzini@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=207.211.31.120; envelope-from=pbonzini@redhat.com; helo=us-smtp-1.mimecast.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/24 02:33:25 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-1, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Henderson , qemu-stable@nongnu.org, "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: "Michael S. Tsirkin" Memory API documentation documents valid .min_access_size and .max_access_size fields and explains that any access outside these boundaries is blocked. This is what devices seem to assume. However this is not what the implementation does: it simply ignores the boundaries unless there's an "accepts" callback. Naturally, this breaks a bunch of devices. Revert to the documented behaviour. Devices that want to allow any access can just drop the valid field, or add the impl field to have accesses converted to appropriate length. Cc: qemu-stable@nongnu.org Reviewed-by: Richard Henderson Fixes: CVE-2020-13754 Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1842363 Fixes: a014ed07bd5a ("memory: accept mismatching sizes in memory_region_access_valid") Signed-off-by: Michael S. Tsirkin Message-Id: <20200610134731.1514409-1-mst@redhat.com> Signed-off-by: Paolo Bonzini --- memory.c | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/memory.c b/memory.c index 2f15a4b250..9200b20130 100644 --- a/memory.c +++ b/memory.c @@ -1352,35 +1352,24 @@ bool memory_region_access_valid(MemoryRegion *mr, bool is_write, MemTxAttrs attrs) { - int access_size_min, access_size_max; - int access_size, i; - - if (!mr->ops->valid.unaligned && (addr & (size - 1))) { + if (mr->ops->valid.accepts + && !mr->ops->valid.accepts(mr->opaque, addr, size, is_write, attrs)) { return false; } - if (!mr->ops->valid.accepts) { - return true; - } - - access_size_min = mr->ops->valid.min_access_size; - if (!mr->ops->valid.min_access_size) { - access_size_min = 1; + if (!mr->ops->valid.unaligned && (addr & (size - 1))) { + return false; } - access_size_max = mr->ops->valid.max_access_size; + /* Treat zero as compatibility all valid */ if (!mr->ops->valid.max_access_size) { - access_size_max = 4; + return true; } - access_size = MAX(MIN(size, access_size_max), access_size_min); - for (i = 0; i < size; i += access_size) { - if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size, - is_write, attrs)) { - return false; - } + if (size > mr->ops->valid.max_access_size + || size < mr->ops->valid.min_access_size) { + return false; } - return true; }