Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965591AbaLLG3o (ORCPT ); Fri, 12 Dec 2014 01:29:44 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:52014 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759356AbaLLGQ6 (ORCPT ); Fri, 12 Dec 2014 01:16:58 -0500 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Jamie Iles" , "Sasha Levin" , stable@vger.kernel.org, "Quentin Casasnovas" , "Vegard Nossum" , "Paolo Bonzini" Date: Fri, 12 Dec 2014 06:14:25 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.2 081/164] kvm: fix excessive pages un-pinning in kvm_iommu_map error path. In-Reply-To: X-SA-Exim-Connect-IP: 2001:470:1f08:1539:c97:8151:cc89:c28d X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.2.65-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Quentin Casasnovas commit 3d32e4dbe71374a6780eaf51d719d76f9a9bf22f upstream. The third parameter of kvm_unpin_pages() when called from kvm_iommu_map_pages() is wrong, it should be the number of pages to un-pin and not the page size. This error was facilitated with an inconsistent API: kvm_pin_pages() takes a size, but kvn_unpin_pages() takes a number of pages, so fix the problem by matching the two. This was introduced by commit 350b8bd ("kvm: iommu: fix the third parameter of kvm_iommu_put_pages (CVE-2014-3601)"), which fixes the lack of un-pinning for pages intended to be un-pinned (i.e. memory leak) but unfortunately potentially aggravated the number of pages we un-pin that should have stayed pinned. As far as I understand though, the same practical mitigations apply. This issue was found during review of Red Hat 6.6 patches to prepare Ksplice rebootless updates. Thanks to Vegard for his time on a late Friday evening to help me in understanding this code. Fixes: 350b8bd ("kvm: iommu: fix the third parameter of... (CVE-2014-3601)") Cc: stable@vger.kernel.org Signed-off-by: Quentin Casasnovas Signed-off-by: Vegard Nossum Signed-off-by: Jamie Iles Reviewed-by: Sasha Levin Signed-off-by: Paolo Bonzini [bwh: Backported to 3.2: kvm_pin_pages() also takes a struct kvm *kvm param] Signed-off-by: Ben Hutchings --- virt/kvm/iommu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) --- a/virt/kvm/iommu.c +++ b/virt/kvm/iommu.c @@ -43,13 +43,13 @@ static void kvm_iommu_put_pages(struct k gfn_t base_gfn, unsigned long npages); static pfn_t kvm_pin_pages(struct kvm *kvm, struct kvm_memory_slot *slot, - gfn_t gfn, unsigned long size) + gfn_t gfn, unsigned long npages) { gfn_t end_gfn; pfn_t pfn; pfn = gfn_to_pfn_memslot(kvm, slot, gfn); - end_gfn = gfn + (size >> PAGE_SHIFT); + end_gfn = gfn + npages; gfn += 1; if (is_error_pfn(pfn)) @@ -117,7 +117,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, * Pin all pages we are about to map in memory. This is * important because we unmap and unpin in 4kb steps later. */ - pfn = kvm_pin_pages(kvm, slot, gfn, page_size); + pfn = kvm_pin_pages(kvm, slot, gfn, page_size >> PAGE_SHIFT); if (is_error_pfn(pfn)) { gfn += 1; continue; @@ -129,7 +129,7 @@ int kvm_iommu_map_pages(struct kvm *kvm, if (r) { printk(KERN_ERR "kvm_iommu_map_address:" "iommu failed to map pfn=%llx\n", pfn); - kvm_unpin_pages(kvm, pfn, page_size); + kvm_unpin_pages(kvm, pfn, page_size >> PAGE_SHIFT); goto unmap_pages; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/