wok-current rev 19458
linux: CVE-2016-5195
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Fri Oct 21 17:33:56 2016 +0200 (2016-10-21) |
parents | 8c71bd3c7080 |
children | 1c458fa173fb |
files | linux/receipt linux/stuff/linux-CVE-2016-5195.u |
line diff
1.1 --- a/linux/receipt Fri Oct 21 15:36:54 2016 +0200 1.2 +++ b/linux/receipt Fri Oct 21 17:33:56 2016 +0200 1.3 @@ -230,6 +230,7 @@ 1.4 aufs3-mmap.patch 1.5 channel-negative-one-maxim.patch 1.6 mac80211.compat08082009.wl_frag+ack_v1.patch 1.7 +$PACKAGE-CVE-2016-5195.u 1.8 EOT 1.9 1.10 # Mrproper and lguest
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/linux/stuff/linux-CVE-2016-5195.u Fri Oct 21 17:33:56 2016 +0200 2.3 @@ -0,0 +1,87 @@ 2.4 +https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-5195 2.5 +--- a/include/linux/mm.h 2.6 ++++ b/include/linux/mm.h 2.7 +@@ -1611,6 +1611,7 @@ struct page *follow_page(struct vm_area_struct *, unsigned long address, 2.8 + #define FOLL_MLOCK 0x40 /* mark page as mlocked */ 2.9 + #define FOLL_SPLIT 0x80 /* don't return transhuge pages, split them */ 2.10 + #define FOLL_HWPOISON 0x100 /* check page is hwpoisoned */ 2.11 ++#define FOLL_COW 0x4000 /* internal GUP flag */ 2.12 + 2.13 + typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, 2.14 + void *data); 2.15 +diff --git a/mm/memory.c b/mm/memory.c 2.16 +index 675b211296fd..2917e9b2e4d4 100644 2.17 +--- a/mm/memory.c 2.18 ++++ b/mm/memory.c 2.19 +@@ -1427,6 +1427,24 @@ int zap_vma_ptes(struct vm_area_struct *vma, unsigned long address, 2.20 + } 2.21 + EXPORT_SYMBOL_GPL(zap_vma_ptes); 2.22 + 2.23 ++static inline bool can_follow_write_pte(pte_t pte, struct page *page, 2.24 ++ unsigned int flags) 2.25 ++{ 2.26 ++ if (pte_write(pte)) 2.27 ++ return true; 2.28 ++ 2.29 ++ /* 2.30 ++ * Make sure that we are really following CoWed page. We do not really 2.31 ++ * have to care about exclusiveness of the page because we only want 2.32 ++ * to ensure that once COWed page hasn't disappeared in the meantime 2.33 ++ * or it hasn't been merged to a KSM page. 2.34 ++ */ 2.35 ++ if ((flags & FOLL_FORCE) && (flags & FOLL_COW)) 2.36 ++ return page && PageAnon(page) && !PageKsm(page); 2.37 ++ 2.38 ++ return false; 2.39 ++} 2.40 ++ 2.41 + /** 2.42 + * follow_page - look up a page descriptor from a user-virtual address 2.43 + * @vma: vm_area_struct mapping @address 2.44 +@@ -1509,10 +1527,13 @@ split_fallthrough: 2.45 + pte = *ptep; 2.46 + if (!pte_present(pte)) 2.47 + goto no_page; 2.48 +- if ((flags & FOLL_WRITE) && !pte_write(pte)) 2.49 +- goto unlock; 2.50 + 2.51 + page = vm_normal_page(vma, address, pte); 2.52 ++ if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, page, flags)) { 2.53 ++ pte_unmap_unlock(ptep, ptl); 2.54 ++ return NULL; 2.55 ++ } 2.56 ++ 2.57 + if (unlikely(!page)) { 2.58 + if ((flags & FOLL_DUMP) || 2.59 + !is_zero_pfn(pte_pfn(pte))) 2.60 +@@ -1555,7 +1576,7 @@ split_fallthrough: 2.61 + unlock_page(page); 2.62 + } 2.63 + } 2.64 +-unlock: 2.65 ++ 2.66 + pte_unmap_unlock(ptep, ptl); 2.67 + out: 2.68 + return page; 2.69 +@@ -1789,17 +1810,13 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, 2.70 + * The VM_FAULT_WRITE bit tells us that 2.71 + * do_wp_page has broken COW when necessary, 2.72 + * even if maybe_mkwrite decided not to set 2.73 +- * pte_write. We can thus safely do subsequent 2.74 +- * page lookups as if they were reads. But only 2.75 +- * do so when looping for pte_write is futile: 2.76 +- * in some cases userspace may also be wanting 2.77 +- * to write to the gotten user page, which a 2.78 +- * read fault here might prevent (a readonly 2.79 +- * page might get reCOWed by userspace write). 2.80 ++ * pte_write. We cannot simply drop FOLL_WRITE 2.81 ++ * here because the COWed page might be gone by 2.82 ++ * the time we do the subsequent page lookups. 2.83 + */ 2.84 + if ((ret & VM_FAULT_WRITE) && 2.85 + !(vma->vm_flags & VM_WRITE)) 2.86 +- foll_flags &= ~FOLL_WRITE; 2.87 ++ foll_flags |= FOLL_COW; 2.88 + 2.89 + cond_resched(); 2.90 + }