From patchwork Tue Apr 17 09:46:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Stefan Bader X-Patchwork-Id: 899167 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 40QL4m5rW3z9s02; Tue, 17 Apr 2018 19:47:04 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1f8NCQ-0005il-KX; Tue, 17 Apr 2018 09:46:54 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1f8NCP-0005ie-4z for kernel-team@lists.ubuntu.com; Tue, 17 Apr 2018 09:46:53 +0000 Received: from 1.general.smb.uk.vpn ([10.172.193.28] helo=canonical.com) by youngberry.canonical.com with esmtpsa (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1f8NCO-0001YO-SP for kernel-team@lists.ubuntu.com; Tue, 17 Apr 2018 09:46:52 +0000 From: Stefan Bader To: kernel-team@lists.ubuntu.com Subject: [Trusty SRU: CVE-2017-12134] xen: fix bio vec merging Date: Tue, 17 Apr 2018 11:46:52 +0200 Message-Id: <1523958412-25466-1-git-send-email-stefan.bader@canonical.com> X-Mailer: git-send-email 2.7.4 MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Roger Pau Monne The current test for bio vec merging is not fully accurate and can be tricked into merging bios when certain grant combinations are used. The result of these malicious bio merges is a bio that extends past the memory page used by any of the originating bios. Take into account the following scenario, where a guest creates two grant references that point to the same mfn, ie: grant 1 -> mfn A, grant 2 -> mfn A. These references are then used in a PV block request, and mapped by the backend domain, thus obtaining two different pfns that point to the same mfn, pfn B -> mfn A, pfn C -> mfn A. If those grants happen to be used in two consecutive sectors of a disk IO operation becoming two different bios in the backend domain, the checks in xen_biovec_phys_mergeable will succeed, because bfn1 == bfn2 (they both point to the same mfn). However due to the bio merging, the backend domain will end up with a bio that expands past mfn A into mfn A + 1. Fix this by making sure the check in xen_biovec_phys_mergeable takes into account the offset and the length of the bio, this basically replicates whats done in __BIOVEC_PHYS_MERGEABLE using mfns (bus addresses). While there also remove the usage of __BIOVEC_PHYS_MERGEABLE, since that's already checked by the callers of xen_biovec_phys_mergeable. CC: stable@vger.kernel.org Reported-by: "Jan H. Schönherr" Signed-off-by: Roger Pau Monné Reviewed-by: Juergen Gross Signed-off-by: Konrad Rzeszutek Wilk CVE-2017-12134 (backported from commit 462cdace790ac2ed6aad1b19c9c0af0143b6aab0) [smb: pfn_to_gfn in newer code returns the same as pfn_to_mfn] Signed-off-by: Stefan Bader Acked-by: Kleber Sacilotto de Souza Acked-by: Colin Ian King --- Already applied in Xenial, Trusty still needs it but needed a bit of tweaking. Basically the newer code uses pfn_to_gfn which either returns a pfn or a mfn. Which is the same behavior as pfn_to_mfn. -Stefan drivers/xen/biomerge.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c index 0edb91c..4a77fe8 100644 --- a/drivers/xen/biomerge.c +++ b/drivers/xen/biomerge.c @@ -9,7 +9,6 @@ bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, unsigned long mfn1 = pfn_to_mfn(page_to_pfn(vec1->bv_page)); unsigned long mfn2 = pfn_to_mfn(page_to_pfn(vec2->bv_page)); - return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) && - ((mfn1 == mfn2) || ((mfn1+1) == mfn2)); + return mfn1 + PFN_DOWN(vec1->bv_offset + vec1->bv_len) == mfn2; } EXPORT_SYMBOL(xen_biovec_phys_mergeable);