From 5a69e530964fff24f6e89ed387f1115b0a9feaec Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 17 Oct 2022 11:49:49 +0200 Subject: [PATCH] 5.19-stable patches added patches: mm-hugetlb-fix-uaf-in-hugetlb_handle_userfault.patch --- ...udio-properly-refcounting-clock-rate.patch | 15 +- ...-fix-uaf-in-hugetlb_handle_userfault.patch | 155 ++++++++++++++++++ queue-5.19/series | 1 + 3 files changed, 161 insertions(+), 10 deletions(-) create mode 100644 queue-5.19/mm-hugetlb-fix-uaf-in-hugetlb_handle_userfault.patch diff --git a/queue-5.19/alsa-usb-audio-properly-refcounting-clock-rate.patch b/queue-5.19/alsa-usb-audio-properly-refcounting-clock-rate.patch index de2fe8a7262..02e2cb8ee23 100644 --- a/queue-5.19/alsa-usb-audio-properly-refcounting-clock-rate.patch +++ b/queue-5.19/alsa-usb-audio-properly-refcounting-clock-rate.patch @@ -22,11 +22,9 @@ Link: https://lore.kernel.org/r/20220920181126.4912-1-tiwai@suse.de Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- - sound/usb/endpoint.c | 11 +++++++---- + sound/usb/endpoint.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) -diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c -index 971c33937dca..26fcbf61c890 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -39,6 +39,7 @@ struct snd_usb_iface_ref { @@ -35,9 +33,9 @@ index 971c33937dca..26fcbf61c890 100644 atomic_t locked; + int opened; int rate; - bool need_setup; struct list_head list; -@@ -804,6 +805,7 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip, + }; +@@ -802,6 +803,7 @@ snd_usb_endpoint_open(struct snd_usb_aud ep = NULL; goto unlock; } @@ -45,7 +43,7 @@ index 971c33937dca..26fcbf61c890 100644 } ep->cur_audiofmt = fp; -@@ -927,8 +929,10 @@ void snd_usb_endpoint_close(struct snd_usb_audio *chip, +@@ -925,8 +927,10 @@ void snd_usb_endpoint_close(struct snd_u endpoint_set_interface(chip, ep, false); if (!--ep->opened) { @@ -58,7 +56,7 @@ index 971c33937dca..26fcbf61c890 100644 ep->iface = 0; ep->altsetting = 0; ep->cur_audiofmt = NULL; -@@ -1649,8 +1653,7 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, bool keep_pending) +@@ -1633,8 +1637,7 @@ void snd_usb_endpoint_stop(struct snd_us WRITE_ONCE(ep->sync_source->sync_sink, NULL); stop_urbs(ep, false, keep_pending); if (ep->clock_ref) @@ -68,6 +66,3 @@ index 971c33937dca..26fcbf61c890 100644 } } --- -2.35.1 - diff --git a/queue-5.19/mm-hugetlb-fix-uaf-in-hugetlb_handle_userfault.patch b/queue-5.19/mm-hugetlb-fix-uaf-in-hugetlb_handle_userfault.patch new file mode 100644 index 00000000000..207e4dc4394 --- /dev/null +++ b/queue-5.19/mm-hugetlb-fix-uaf-in-hugetlb_handle_userfault.patch @@ -0,0 +1,155 @@ +From 958f32ce832ba781ac20e11bb2d12a9352ea28fc Mon Sep 17 00:00:00 2001 +From: Liu Shixin +Date: Fri, 23 Sep 2022 12:21:13 +0800 +Subject: mm: hugetlb: fix UAF in hugetlb_handle_userfault + +From: Liu Shixin + +commit 958f32ce832ba781ac20e11bb2d12a9352ea28fc upstream. + +The vma_lock and hugetlb_fault_mutex are dropped before handling userfault +and reacquire them again after handle_userfault(), but reacquire the +vma_lock could lead to UAF[1,2] due to the following race, + +hugetlb_fault + hugetlb_no_page + /*unlock vma_lock */ + hugetlb_handle_userfault + handle_userfault + /* unlock mm->mmap_lock*/ + vm_mmap_pgoff + do_mmap + mmap_region + munmap_vma_range + /* clean old vma */ + /* lock vma_lock again <--- UAF */ + /* unlock vma_lock */ + +Since the vma_lock will unlock immediately after +hugetlb_handle_userfault(), let's drop the unneeded lock and unlock in +hugetlb_handle_userfault() to fix the issue. + +[1] https://lore.kernel.org/linux-mm/000000000000d5e00a05e834962e@google.com/ +[2] https://lore.kernel.org/linux-mm/20220921014457.1668-1-liuzixian4@huawei.com/ +Link: https://lkml.kernel.org/r/20220923042113.137273-1-liushixin2@huawei.com +Fixes: 1a1aad8a9b7b ("userfaultfd: hugetlbfs: add userfaultfd hugetlb hook") +Signed-off-by: Liu Shixin +Signed-off-by: Kefeng Wang +Reported-by: syzbot+193f9cee8638750b23cf@syzkaller.appspotmail.com +Reported-by: Liu Zixian +Reviewed-by: Mike Kravetz +Cc: David Hildenbrand +Cc: John Hubbard +Cc: Muchun Song +Cc: Sidhartha Kumar +Cc: [4.14+] +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/hugetlb.c | 37 +++++++++++++++++-------------------- + 1 file changed, 17 insertions(+), 20 deletions(-) + +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -5467,7 +5467,6 @@ static inline vm_fault_t hugetlb_handle_ + unsigned long addr, + unsigned long reason) + { +- vm_fault_t ret; + u32 hash; + struct vm_fault vmf = { + .vma = vma, +@@ -5485,18 +5484,14 @@ static inline vm_fault_t hugetlb_handle_ + }; + + /* +- * hugetlb_fault_mutex and i_mmap_rwsem must be +- * dropped before handling userfault. Reacquire +- * after handling fault to make calling code simpler. ++ * vma_lock and hugetlb_fault_mutex must be dropped before handling ++ * userfault. Also mmap_lock will be dropped during handling ++ * userfault, any vma operation should be careful from here. + */ + hash = hugetlb_fault_mutex_hash(mapping, idx); + mutex_unlock(&hugetlb_fault_mutex_table[hash]); + i_mmap_unlock_read(mapping); +- ret = handle_userfault(&vmf, reason); +- i_mmap_lock_read(mapping); +- mutex_lock(&hugetlb_fault_mutex_table[hash]); +- +- return ret; ++ return handle_userfault(&vmf, reason); + } + + static vm_fault_t hugetlb_no_page(struct mm_struct *mm, +@@ -5514,6 +5509,7 @@ static vm_fault_t hugetlb_no_page(struct + spinlock_t *ptl; + unsigned long haddr = address & huge_page_mask(h); + bool new_page, new_pagecache_page = false; ++ u32 hash = hugetlb_fault_mutex_hash(mapping, idx); + + /* + * Currently, we are forced to kill the process in the event the +@@ -5524,7 +5520,7 @@ static vm_fault_t hugetlb_no_page(struct + if (is_vma_resv_set(vma, HPAGE_RESV_UNMAPPED)) { + pr_warn_ratelimited("PID %d killed due to inadequate hugepage pool\n", + current->pid); +- return ret; ++ goto out; + } + + /* +@@ -5541,12 +5537,10 @@ retry: + page = find_lock_page(mapping, idx); + if (!page) { + /* Check for page in userfault range */ +- if (userfaultfd_missing(vma)) { +- ret = hugetlb_handle_userfault(vma, mapping, idx, ++ if (userfaultfd_missing(vma)) ++ return hugetlb_handle_userfault(vma, mapping, idx, + flags, haddr, address, + VM_UFFD_MISSING); +- goto out; +- } + + page = alloc_huge_page(vma, haddr, 0); + if (IS_ERR(page)) { +@@ -5606,10 +5600,9 @@ retry: + if (userfaultfd_minor(vma)) { + unlock_page(page); + put_page(page); +- ret = hugetlb_handle_userfault(vma, mapping, idx, ++ return hugetlb_handle_userfault(vma, mapping, idx, + flags, haddr, address, + VM_UFFD_MINOR); +- goto out; + } + } + +@@ -5667,6 +5660,8 @@ retry: + + unlock_page(page); + out: ++ mutex_unlock(&hugetlb_fault_mutex_table[hash]); ++ i_mmap_unlock_read(mapping); + return ret; + + backout: +@@ -5765,11 +5760,13 @@ vm_fault_t hugetlb_fault(struct mm_struc + + entry = huge_ptep_get(ptep); + /* PTE markers should be handled the same way as none pte */ +- if (huge_pte_none_mostly(entry)) { +- ret = hugetlb_no_page(mm, vma, mapping, idx, address, ptep, ++ if (huge_pte_none_mostly(entry)) ++ /* ++ * hugetlb_no_page will drop vma lock and hugetlb fault ++ * mutex internally, which make us return immediately. ++ */ ++ return hugetlb_no_page(mm, vma, mapping, idx, address, ptep, + entry, flags); +- goto out_mutex; +- } + + ret = 0; + diff --git a/queue-5.19/series b/queue-5.19/series index 5bfb98e9657..9537adf6f1a 100644 --- a/queue-5.19/series +++ b/queue-5.19/series @@ -825,3 +825,4 @@ clk-bcm2835-round-uart-input-clock-up.patch perf-skip-and-warn-on-unknown-format-confign-attrs.patch perf-intel-pt-fix-segfault-in-intel_pt_print_info-with-uclibc.patch perf-intel-pt-fix-system_wide-dummy-event-for-hybrid.patch +mm-hugetlb-fix-uaf-in-hugetlb_handle_userfault.patch -- 2.47.2