From a19c78ef72f4eb69430020e96293449762ba1afa Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 26 Nov 2019 09:20:48 +0100 Subject: [PATCH] 4.9-stable patches added patches: bluetooth-fix-invalid-free-in-bcsp_close.patch kvm-mmu-do-not-treat-zone_device-pages-as-being-reserved.patch --- ...tooth-fix-invalid-free-in-bcsp_close.patch | 50 +++++++ ...-zone_device-pages-as-being-reserved.patch | 134 ++++++++++++++++++ queue-4.9/series | 2 + 3 files changed, 186 insertions(+) create mode 100644 queue-4.9/bluetooth-fix-invalid-free-in-bcsp_close.patch create mode 100644 queue-4.9/kvm-mmu-do-not-treat-zone_device-pages-as-being-reserved.patch diff --git a/queue-4.9/bluetooth-fix-invalid-free-in-bcsp_close.patch b/queue-4.9/bluetooth-fix-invalid-free-in-bcsp_close.patch new file mode 100644 index 00000000000..9859548014f --- /dev/null +++ b/queue-4.9/bluetooth-fix-invalid-free-in-bcsp_close.patch @@ -0,0 +1,50 @@ +From cf94da6f502d8caecabd56b194541c873c8a7a3c Mon Sep 17 00:00:00 2001 +From: Tomas Bortoli +Date: Fri, 1 Nov 2019 21:42:44 +0100 +Subject: Bluetooth: Fix invalid-free in bcsp_close() + +From: Tomas Bortoli + +commit cf94da6f502d8caecabd56b194541c873c8a7a3c upstream. + +Syzbot reported an invalid-free that I introduced fixing a memleak. + +bcsp_recv() also frees bcsp->rx_skb but never nullifies its value. +Nullify bcsp->rx_skb every time it is freed. + +Signed-off-by: Tomas Bortoli +Reported-by: syzbot+a0d209a4676664613e76@syzkaller.appspotmail.com +Signed-off-by: Marcel Holtmann +Cc: Alexander Potapenko +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/bluetooth/hci_bcsp.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/bluetooth/hci_bcsp.c ++++ b/drivers/bluetooth/hci_bcsp.c +@@ -605,6 +605,7 @@ static int bcsp_recv(struct hci_uart *hu + if (*ptr == 0xc0) { + BT_ERR("Short BCSP packet"); + kfree_skb(bcsp->rx_skb); ++ bcsp->rx_skb = NULL; + bcsp->rx_state = BCSP_W4_PKT_START; + bcsp->rx_count = 0; + } else +@@ -620,6 +621,7 @@ static int bcsp_recv(struct hci_uart *hu + bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) { + BT_ERR("Error in BCSP hdr checksum"); + kfree_skb(bcsp->rx_skb); ++ bcsp->rx_skb = NULL; + bcsp->rx_state = BCSP_W4_PKT_DELIMITER; + bcsp->rx_count = 0; + continue; +@@ -644,6 +646,7 @@ static int bcsp_recv(struct hci_uart *hu + bscp_get_crc(bcsp)); + + kfree_skb(bcsp->rx_skb); ++ bcsp->rx_skb = NULL; + bcsp->rx_state = BCSP_W4_PKT_DELIMITER; + bcsp->rx_count = 0; + continue; diff --git a/queue-4.9/kvm-mmu-do-not-treat-zone_device-pages-as-being-reserved.patch b/queue-4.9/kvm-mmu-do-not-treat-zone_device-pages-as-being-reserved.patch new file mode 100644 index 00000000000..ff69384f147 --- /dev/null +++ b/queue-4.9/kvm-mmu-do-not-treat-zone_device-pages-as-being-reserved.patch @@ -0,0 +1,134 @@ +From a78986aae9b2988f8493f9f65a587ee433e83bc3 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Mon, 11 Nov 2019 14:12:27 -0800 +Subject: KVM: MMU: Do not treat ZONE_DEVICE pages as being reserved + +From: Sean Christopherson + +commit a78986aae9b2988f8493f9f65a587ee433e83bc3 upstream. + +Explicitly exempt ZONE_DEVICE pages from kvm_is_reserved_pfn() and +instead manually handle ZONE_DEVICE on a case-by-case basis. For things +like page refcounts, KVM needs to treat ZONE_DEVICE pages like normal +pages, e.g. put pages grabbed via gup(). But for flows such as setting +A/D bits or shifting refcounts for transparent huge pages, KVM needs to +to avoid processing ZONE_DEVICE pages as the flows in question lack the +underlying machinery for proper handling of ZONE_DEVICE pages. + +This fixes a hang reported by Adam Borowski[*] in dev_pagemap_cleanup() +when running a KVM guest backed with /dev/dax memory, as KVM straight up +doesn't put any references to ZONE_DEVICE pages acquired by gup(). + +Note, Dan Williams proposed an alternative solution of doing put_page() +on ZONE_DEVICE pages immediately after gup() in order to simplify the +auditing needed to ensure is_zone_device_page() is called if and only if +the backing device is pinned (via gup()). But that approach would break +kvm_vcpu_{un}map() as KVM requires the page to be pinned from map() 'til +unmap() when accessing guest memory, unlike KVM's secondary MMU, which +coordinates with mmu_notifier invalidations to avoid creating stale +page references, i.e. doesn't rely on pages being pinned. + +[*] http://lkml.kernel.org/r/20190919115547.GA17963@angband.pl + +Reported-by: Adam Borowski +Analyzed-by: David Hildenbrand +Acked-by: Dan Williams +Cc: stable@vger.kernel.org +Fixes: 3565fce3a659 ("mm, x86: get_user_pages() for dax mappings") +Signed-off-by: Sean Christopherson +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +[sean: backport to 4.x; resolve conflict in mmu.c] +Signed-off-by: Sean Christopherson +--- + arch/x86/kvm/mmu.c | 8 ++++---- + include/linux/kvm_host.h | 1 + + virt/kvm/kvm_main.c | 26 +++++++++++++++++++++++--- + 3 files changed, 28 insertions(+), 7 deletions(-) + +--- a/arch/x86/kvm/mmu.c ++++ b/arch/x86/kvm/mmu.c +@@ -2934,7 +2934,7 @@ static void transparent_hugepage_adjust( + * here. + */ + if (!is_error_noslot_pfn(pfn) && !kvm_is_reserved_pfn(pfn) && +- level == PT_PAGE_TABLE_LEVEL && ++ !kvm_is_zone_device_pfn(pfn) && level == PT_PAGE_TABLE_LEVEL && + PageTransCompoundMap(pfn_to_page(pfn)) && + !mmu_gfn_lpage_is_disallowed(vcpu, gfn, PT_DIRECTORY_LEVEL)) { + unsigned long mask; +@@ -4890,9 +4890,9 @@ restart: + * the guest, and the guest page table is using 4K page size + * mapping if the indirect sp has level = 1. + */ +- if (sp->role.direct && +- !kvm_is_reserved_pfn(pfn) && +- PageTransCompoundMap(pfn_to_page(pfn))) { ++ if (sp->role.direct && !kvm_is_reserved_pfn(pfn) && ++ !kvm_is_zone_device_pfn(pfn) && ++ PageTransCompoundMap(pfn_to_page(pfn))) { + drop_spte(kvm, sptep); + need_tlb_flush = 1; + goto restart; +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -843,6 +843,7 @@ int kvm_cpu_has_pending_timer(struct kvm + void kvm_vcpu_kick(struct kvm_vcpu *vcpu); + + bool kvm_is_reserved_pfn(kvm_pfn_t pfn); ++bool kvm_is_zone_device_pfn(kvm_pfn_t pfn); + + struct kvm_irq_ack_notifier { + struct hlist_node link; +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -131,10 +131,30 @@ __weak void kvm_arch_mmu_notifier_invali + { + } + ++bool kvm_is_zone_device_pfn(kvm_pfn_t pfn) ++{ ++ /* ++ * The metadata used by is_zone_device_page() to determine whether or ++ * not a page is ZONE_DEVICE is guaranteed to be valid if and only if ++ * the device has been pinned, e.g. by get_user_pages(). WARN if the ++ * page_count() is zero to help detect bad usage of this helper. ++ */ ++ if (!pfn_valid(pfn) || WARN_ON_ONCE(!page_count(pfn_to_page(pfn)))) ++ return false; ++ ++ return is_zone_device_page(pfn_to_page(pfn)); ++} ++ + bool kvm_is_reserved_pfn(kvm_pfn_t pfn) + { ++ /* ++ * ZONE_DEVICE pages currently set PG_reserved, but from a refcounting ++ * perspective they are "normal" pages, albeit with slightly different ++ * usage rules. ++ */ + if (pfn_valid(pfn)) +- return PageReserved(pfn_to_page(pfn)); ++ return PageReserved(pfn_to_page(pfn)) && ++ !kvm_is_zone_device_pfn(pfn); + + return true; + } +@@ -1758,7 +1778,7 @@ static void kvm_release_pfn_dirty(kvm_pf + + void kvm_set_pfn_dirty(kvm_pfn_t pfn) + { +- if (!kvm_is_reserved_pfn(pfn)) { ++ if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn)) { + struct page *page = pfn_to_page(pfn); + + if (!PageReserved(page)) +@@ -1769,7 +1789,7 @@ EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty); + + void kvm_set_pfn_accessed(kvm_pfn_t pfn) + { +- if (!kvm_is_reserved_pfn(pfn)) ++ if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn)) + mark_page_accessed(pfn_to_page(pfn)); + } + EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed); diff --git a/queue-4.9/series b/queue-4.9/series index d531c449ae7..94a57629377 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -107,3 +107,5 @@ pinctrl-zynq-use-define-directive-for-pin_config_io_.patch pci-keystone-use-quirk-to-limit-mrrs-for-k2g.patch spi-omap2-mcspi-fix-dma-and-fifo-event-trigger-size-.patch mm-memory_hotplug-do-not-unlock-when-fails-to-take-t.patch +bluetooth-fix-invalid-free-in-bcsp_close.patch +kvm-mmu-do-not-treat-zone_device-pages-as-being-reserved.patch -- 2.47.3