diff --git a/CVE-2017-7979-0001-net_sched-nla_memdup_cookie-can-be-static.patch b/CVE-2017-7979-0001-net_sched-nla_memdup_cookie-can-be-static.patch deleted file mode 100644 index 6400aae..0000000 --- a/CVE-2017-7979-0001-net_sched-nla_memdup_cookie-can-be-static.patch +++ /dev/null @@ -1,42 +0,0 @@ -From e18cf144f49054fa79d43689accdd2766618953d Mon Sep 17 00:00:00 2001 -From: Wei Yongjun -Date: Mon, 24 Apr 2017 16:26:00 +0200 -Subject: [PATCH 1/2] net_sched: nla_memdup_cookie() can be static -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1682368 - -Fixes the following sparse warning: - -net/sched/act_api.c:532:5: warning: - symbol 'nla_memdup_cookie' was not declared. Should it be static? - -Signed-off-by: Wei Yongjun -Signed-off-by: David S. Miller -(cherry picked from commit 6f2e3f7d9785dacb358b48b44950182b5c13e4bc) -Signed-off-by: Fabian Grünbichler -Acked-by: Kamal Mostafa -Acked-by: Seth Forshee -Signed-off-by: Stefan Bader ---- - net/sched/act_api.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/sched/act_api.c b/net/sched/act_api.c -index 501c42d..e336f30 100644 ---- a/net/sched/act_api.c -+++ b/net/sched/act_api.c -@@ -532,7 +532,7 @@ int tcf_action_dump(struct sk_buff *skb, struct list_head *actions, - return err; - } - --int nla_memdup_cookie(struct tc_action *a, struct nlattr **tb) -+static int nla_memdup_cookie(struct tc_action *a, struct nlattr **tb) - { - a->act_cookie = kzalloc(sizeof(*a->act_cookie), GFP_KERNEL); - if (!a->act_cookie) --- -2.1.4 - diff --git a/CVE-2017-7979-0002-net-sched-actions-allocate-act-cookie-early.patch b/CVE-2017-7979-0002-net-sched-actions-allocate-act-cookie-early.patch deleted file mode 100644 index 7ba37e1..0000000 --- a/CVE-2017-7979-0002-net-sched-actions-allocate-act-cookie-early.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 3fe083491bf6c688d34c6e300f14d775a5b8a443 Mon Sep 17 00:00:00 2001 -From: Wolfgang Bumiller -Date: Mon, 24 Apr 2017 16:26:00 +0200 -Subject: [PATCH 2/2] net sched actions: allocate act cookie early -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1682368 - -Policing filters do not use the TCA_ACT_* enum and the tb[] -nlattr array in tcf_action_init_1() doesn't get filled for -them so we should not try to look for a TCA_ACT_COOKIE -attribute in the then uninitialized array. -The error handling in cookie allocation then calls -tcf_hash_release() leading to invalid memory access later -on. -Additionally, if cookie allocation fails after an already -existing non-policing filter has successfully been changed, -tcf_action_release() should not be called, also we would -have to roll back the changes in the error handling, so -instead we now allocate the cookie early and assign it on -success at the end. - -CVE-2017-7979 -Fixes: 1045ba77a596 ("net sched actions: Add support for user cookies") -Signed-off-by: Wolfgang Bumiller -Acked-by: Jamal Hadi Salim -Signed-off-by: David S. Miller -(cherry picked from commit e0535ce58b92d7baf0b33284a6c4f8f0338f943e) -Signed-off-by: Fabian Grünbichler -Acked-by: Kamal Mostafa -Acked-by: Seth Forshee -Signed-off-by: Stefan Bader - -Signed-off-by: Fabian Grünbichler ---- - net/sched/act_api.c | 55 +++++++++++++++++++++++++++++++---------------------- - 1 file changed, 32 insertions(+), 23 deletions(-) - -diff --git a/net/sched/act_api.c b/net/sched/act_api.c -index e336f30..bdbc7a9 100644 ---- a/net/sched/act_api.c -+++ b/net/sched/act_api.c -@@ -532,20 +532,20 @@ int tcf_action_dump(struct sk_buff *skb, struct list_head *actions, - return err; - } - --static int nla_memdup_cookie(struct tc_action *a, struct nlattr **tb) -+static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb) - { -- a->act_cookie = kzalloc(sizeof(*a->act_cookie), GFP_KERNEL); -- if (!a->act_cookie) -- return -ENOMEM; -+ struct tc_cookie *c = kzalloc(sizeof(*c), GFP_KERNEL); -+ if (!c) -+ return NULL; - -- a->act_cookie->data = nla_memdup(tb[TCA_ACT_COOKIE], GFP_KERNEL); -- if (!a->act_cookie->data) { -- kfree(a->act_cookie); -- return -ENOMEM; -+ c->data = nla_memdup(tb[TCA_ACT_COOKIE], GFP_KERNEL); -+ if (!c->data) { -+ kfree(c); -+ return NULL; - } -- a->act_cookie->len = nla_len(tb[TCA_ACT_COOKIE]); -+ c->len = nla_len(tb[TCA_ACT_COOKIE]); - -- return 0; -+ return c; - } - - struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, -@@ -554,6 +554,7 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, - { - struct tc_action *a; - struct tc_action_ops *a_o; -+ struct tc_cookie *cookie = NULL; - char act_name[IFNAMSIZ]; - struct nlattr *tb[TCA_ACT_MAX + 1]; - struct nlattr *kind; -@@ -569,6 +570,18 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, - goto err_out; - if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) - goto err_out; -+ if (tb[TCA_ACT_COOKIE]) { -+ int cklen = nla_len(tb[TCA_ACT_COOKIE]); -+ -+ if (cklen > TC_COOKIE_MAX_SIZE) -+ goto err_out; -+ -+ cookie = nla_memdup_cookie(tb); -+ if (!cookie) { -+ err = -ENOMEM; -+ goto err_out; -+ } -+ } - } else { - err = -EINVAL; - if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) -@@ -607,20 +620,12 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, - if (err < 0) - goto err_mod; - -- if (tb[TCA_ACT_COOKIE]) { -- int cklen = nla_len(tb[TCA_ACT_COOKIE]); -- -- if (cklen > TC_COOKIE_MAX_SIZE) { -- err = -EINVAL; -- tcf_hash_release(a, bind); -- goto err_mod; -- } -- -- if (nla_memdup_cookie(a, tb) < 0) { -- err = -ENOMEM; -- tcf_hash_release(a, bind); -- goto err_mod; -+ if (name == NULL && tb[TCA_ACT_COOKIE]) { -+ if (a->act_cookie) { -+ kfree(a->act_cookie->data); -+ kfree(a->act_cookie); - } -+ a->act_cookie = cookie; - } - - /* module count goes up only when brand new policy is created -@@ -635,6 +640,10 @@ struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla, - err_mod: - module_put(a_o->owner); - err_out: -+ if (cookie) { -+ kfree(cookie->data); -+ kfree(cookie); -+ } - return ERR_PTR(err); - } - --- -2.1.4 - diff --git a/Makefile b/Makefile index 5c886f9..0e37389 100644 --- a/Makefile +++ b/Makefile @@ -234,12 +234,6 @@ ${KERNEL_SRC}/README ${KERNEL_CFG_ORG}: ${KERNEL_SRC_SUBMODULE} | submodules cd ${KERNEL_SRC}; patch -p1 < ../kvm-dynamic-halt-polling-disable-default.patch cd ${KERNEL_SRC}; patch -p1 < ../cgroup-cpuset-add-cpuset.remap_cpus.patch cd ${KERNEL_SRC}; patch -p1 < ../openvswitch-Set-internal-device-max-mtu-to-ETH_MAX_M.patch - cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-7979-0001-net_sched-nla_memdup_cookie-can-be-static.patch - cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-7979-0002-net-sched-actions-allocate-act-cookie-early.patch - cd ${KERNEL_SRC}; patch -p1 < ../swapops-0001-Revert-mm-ksm-handle-protnone-saved-writes-when-maki.patch - cd ${KERNEL_SRC}; patch -p1 < ../swapops-0002-Revert-mm-ksm-convert-write_protect_page-to-use-page.patch - cd ${KERNEL_SRC}; patch -p1 < ../swapops-0003-Revert-mm-introduce-page_vma_mapped_walk.patch - cd ${KERNEL_SRC}; patch -p1 < ../swapops-0004-mm-ksm-handle-protnone-saved-writes-when-making-page.patch cd ${KERNEL_SRC}; patch -p1 < ../0001-netfilter-nft_set_rbtree-handle-re-addition-element-.patch # DoS from within (unpriv) containers sed -i ${KERNEL_SRC}/Makefile -e 's/^EXTRAVERSION.*$$/EXTRAVERSION=${EXTRAVERSION}/' touch $@ diff --git a/swapops-0001-Revert-mm-ksm-handle-protnone-saved-writes-when-maki.patch b/swapops-0001-Revert-mm-ksm-handle-protnone-saved-writes-when-maki.patch deleted file mode 100644 index 6b12f39..0000000 --- a/swapops-0001-Revert-mm-ksm-handle-protnone-saved-writes-when-maki.patch +++ /dev/null @@ -1,70 +0,0 @@ -From b4cf3c107f8f1d2da2b606e9d08e241be7000d65 Mon Sep 17 00:00:00 2001 -From: Seth Forshee -Date: Wed, 3 May 2017 08:34:47 -0500 -Subject: [PATCH 1/4] Revert "mm/ksm: handle protnone saved writes when making - page write protect" - -This reverts commit c228a1037cd6bd0064472ea282e3730a342d6fca. - -Signed-off-by: Seth Forshee ---- - include/asm-generic/pgtable.h | 8 -------- - mm/ksm.c | 9 ++------- - 2 files changed, 2 insertions(+), 15 deletions(-) - -diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h -index 8c8ba48bef0b..b6f3a8a4b738 100644 ---- a/include/asm-generic/pgtable.h -+++ b/include/asm-generic/pgtable.h -@@ -200,10 +200,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres - #define pte_mk_savedwrite pte_mkwrite - #endif - --#ifndef pte_clear_savedwrite --#define pte_clear_savedwrite pte_wrprotect --#endif -- - #ifndef pmd_savedwrite - #define pmd_savedwrite pmd_write - #endif -@@ -212,10 +208,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres - #define pmd_mk_savedwrite pmd_mkwrite - #endif - --#ifndef pmd_clear_savedwrite --#define pmd_clear_savedwrite pmd_wrprotect --#endif -- - #ifndef __HAVE_ARCH_PMDP_SET_WRPROTECT - #ifdef CONFIG_TRANSPARENT_HUGEPAGE - static inline void pmdp_set_wrprotect(struct mm_struct *mm, -diff --git a/mm/ksm.c b/mm/ksm.c -index abc05187168a..9dd2e58fb6dc 100644 ---- a/mm/ksm.c -+++ b/mm/ksm.c -@@ -880,8 +880,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, - if (WARN_ONCE(!pvmw.pte, "Unexpected PMD mapping?")) - goto out_unlock; - -- if (pte_write(*pvmw.pte) || pte_dirty(*pvmw.pte) || -- (pte_protnone(*pvmw.pte) && pte_savedwrite(*pvmw.pte))) { -+ if (pte_write(*pvmw.pte) || pte_dirty(*pvmw.pte)) { - pte_t entry; - - swapped = PageSwapCache(page); -@@ -906,11 +905,7 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, - } - if (pte_dirty(entry)) - set_page_dirty(page); -- -- if (pte_protnone(entry)) -- entry = pte_mkclean(pte_clear_savedwrite(entry)); -- else -- entry = pte_mkclean(pte_wrprotect(entry)); -+ entry = pte_mkclean(pte_wrprotect(entry)); - set_pte_at_notify(mm, pvmw.address, pvmw.pte, entry); - } - *orig_pte = *pvmw.pte; --- -2.7.4 - diff --git a/swapops-0002-Revert-mm-ksm-convert-write_protect_page-to-use-page.patch b/swapops-0002-Revert-mm-ksm-convert-write_protect_page-to-use-page.patch deleted file mode 100644 index f517c0b..0000000 --- a/swapops-0002-Revert-mm-ksm-convert-write_protect_page-to-use-page.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 40e1fa51bc8aa3df1d3a23711b5de62d8251bff5 Mon Sep 17 00:00:00 2001 -From: Seth Forshee -Date: Wed, 3 May 2017 08:34:52 -0500 -Subject: [PATCH 2/4] Revert "mm, ksm: convert write_protect_page() to use - page_vma_mapped_walk()" - -This reverts commit 3000e033152a70fa139765b4dbb5baec46b1cc1b. - -Signed-off-by: Seth Forshee ---- - mm/ksm.c | 34 ++++++++++++++++------------------ - 1 file changed, 16 insertions(+), 18 deletions(-) - -diff --git a/mm/ksm.c b/mm/ksm.c -index 9dd2e58fb6dc..fed4afd8293b 100644 ---- a/mm/ksm.c -+++ b/mm/ksm.c -@@ -856,35 +856,33 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, - pte_t *orig_pte) - { - struct mm_struct *mm = vma->vm_mm; -- struct page_vma_mapped_walk pvmw = { -- .page = page, -- .vma = vma, -- }; -+ unsigned long addr; -+ pte_t *ptep; -+ spinlock_t *ptl; - int swapped; - int err = -EFAULT; - unsigned long mmun_start; /* For mmu_notifiers */ - unsigned long mmun_end; /* For mmu_notifiers */ - -- pvmw.address = page_address_in_vma(page, vma); -- if (pvmw.address == -EFAULT) -+ addr = page_address_in_vma(page, vma); -+ if (addr == -EFAULT) - goto out; - - BUG_ON(PageTransCompound(page)); - -- mmun_start = pvmw.address; -- mmun_end = pvmw.address + PAGE_SIZE; -+ mmun_start = addr; -+ mmun_end = addr + PAGE_SIZE; - mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end); - -- if (!page_vma_mapped_walk(&pvmw)) -+ ptep = page_check_address(page, mm, addr, &ptl, 0); -+ if (!ptep) - goto out_mn; -- if (WARN_ONCE(!pvmw.pte, "Unexpected PMD mapping?")) -- goto out_unlock; - -- if (pte_write(*pvmw.pte) || pte_dirty(*pvmw.pte)) { -+ if (pte_write(*ptep) || pte_dirty(*ptep)) { - pte_t entry; - - swapped = PageSwapCache(page); -- flush_cache_page(vma, pvmw.address, page_to_pfn(page)); -+ flush_cache_page(vma, addr, page_to_pfn(page)); - /* - * Ok this is tricky, when get_user_pages_fast() run it doesn't - * take any lock, therefore the check that we are going to make -@@ -894,25 +892,25 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, - * this assure us that no O_DIRECT can happen after the check - * or in the middle of the check. - */ -- entry = ptep_clear_flush_notify(vma, pvmw.address, pvmw.pte); -+ entry = ptep_clear_flush_notify(vma, addr, ptep); - /* - * Check that no O_DIRECT or similar I/O is in progress on the - * page - */ - if (page_mapcount(page) + 1 + swapped != page_count(page)) { -- set_pte_at(mm, pvmw.address, pvmw.pte, entry); -+ set_pte_at(mm, addr, ptep, entry); - goto out_unlock; - } - if (pte_dirty(entry)) - set_page_dirty(page); - entry = pte_mkclean(pte_wrprotect(entry)); -- set_pte_at_notify(mm, pvmw.address, pvmw.pte, entry); -+ set_pte_at_notify(mm, addr, ptep, entry); - } -- *orig_pte = *pvmw.pte; -+ *orig_pte = *ptep; - err = 0; - - out_unlock: -- page_vma_mapped_walk_done(&pvmw); -+ pte_unmap_unlock(ptep, ptl); - out_mn: - mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end); - out: --- -2.7.4 - diff --git a/swapops-0003-Revert-mm-introduce-page_vma_mapped_walk.patch b/swapops-0003-Revert-mm-introduce-page_vma_mapped_walk.patch deleted file mode 100644 index edafc7c..0000000 --- a/swapops-0003-Revert-mm-introduce-page_vma_mapped_walk.patch +++ /dev/null @@ -1,294 +0,0 @@ -From 47a3e75a6d3db759a5fce3e922f144af0d6f1d38 Mon Sep 17 00:00:00 2001 -From: Seth Forshee -Date: Wed, 3 May 2017 08:34:56 -0500 -Subject: [PATCH 3/4] Revert "mm: introduce page_vma_mapped_walk()" - -This reverts commit 6e2a092a48d38cfc0f06bdb523014acbfeba7b2e. - -Signed-off-by: Seth Forshee ---- - include/linux/rmap.h | 26 ------- - mm/Makefile | 6 +- - mm/huge_memory.c | 9 +-- - mm/page_vma_mapped.c | 188 --------------------------------------------------- - 4 files changed, 5 insertions(+), 224 deletions(-) - delete mode 100644 mm/page_vma_mapped.c - -diff --git a/include/linux/rmap.h b/include/linux/rmap.h -index b76343610653..15321fb1df6b 100644 ---- a/include/linux/rmap.h -+++ b/include/linux/rmap.h -@@ -9,7 +9,6 @@ - #include - #include - #include --#include - - /* - * The anon_vma heads a list of private "related" vmas, to scan if -@@ -233,31 +232,6 @@ static inline bool page_check_address_transhuge(struct page *page, - } - #endif - --/* Avoid racy checks */ --#define PVMW_SYNC (1 << 0) --/* Look for migarion entries rather than present PTEs */ --#define PVMW_MIGRATION (1 << 1) -- --struct page_vma_mapped_walk { -- struct page *page; -- struct vm_area_struct *vma; -- unsigned long address; -- pmd_t *pmd; -- pte_t *pte; -- spinlock_t *ptl; -- unsigned int flags; --}; -- --static inline void page_vma_mapped_walk_done(struct page_vma_mapped_walk *pvmw) --{ -- if (pvmw->pte) -- pte_unmap(pvmw->pte); -- if (pvmw->ptl) -- spin_unlock(pvmw->ptl); --} -- --bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw); -- - /* - * Used by swapoff to help locate where page is expected in vma. - */ -diff --git a/mm/Makefile b/mm/Makefile -index 474fa3431059..14fa1c83b504 100644 ---- a/mm/Makefile -+++ b/mm/Makefile -@@ -23,10 +23,8 @@ KCOV_INSTRUMENT_vmstat.o := n - - mmu-y := nommu.o - mmu-$(CONFIG_MMU) := gup.o highmem.o memory.o mincore.o \ -- mlock.o mmap.o mprotect.o mremap.o msync.o \ -- page_vma_mapped.o pagewalk.o pgtable-generic.o \ -- rmap.o vmalloc.o -- -+ mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \ -+ vmalloc.o pagewalk.o pgtable-generic.o - - ifdef CONFIG_CROSS_MEMORY_ATTACH - mmu-$(CONFIG_MMU) += process_vm_access.o -diff --git a/mm/huge_memory.c b/mm/huge_memory.c -index 87303c6bacf4..e6de801fa477 100644 ---- a/mm/huge_memory.c -+++ b/mm/huge_memory.c -@@ -1878,12 +1878,9 @@ static void freeze_page(struct page *page) - static void unfreeze_page(struct page *page) - { - int i; -- if (PageTransHuge(page)) { -- remove_migration_ptes(page, page, true); -- } else { -- for (i = 0; i < HPAGE_PMD_NR; i++) -- remove_migration_ptes(page + i, page + i, true); -- } -+ -+ for (i = 0; i < HPAGE_PMD_NR; i++) -+ remove_migration_ptes(page + i, page + i, true); - } - - static void __split_huge_page_tail(struct page *head, int tail, -diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c -deleted file mode 100644 -index dc1a54826cf2..000000000000 ---- a/mm/page_vma_mapped.c -+++ /dev/null -@@ -1,188 +0,0 @@ --#include --#include --#include --#include --#include -- --#include "internal.h" -- --static inline bool check_pmd(struct page_vma_mapped_walk *pvmw) --{ -- pmd_t pmde; -- /* -- * Make sure we don't re-load pmd between present and !trans_huge check. -- * We need a consistent view. -- */ -- pmde = READ_ONCE(*pvmw->pmd); -- return pmd_present(pmde) && !pmd_trans_huge(pmde); --} -- --static inline bool not_found(struct page_vma_mapped_walk *pvmw) --{ -- page_vma_mapped_walk_done(pvmw); -- return false; --} -- --static bool map_pte(struct page_vma_mapped_walk *pvmw) --{ -- pvmw->pte = pte_offset_map(pvmw->pmd, pvmw->address); -- if (!(pvmw->flags & PVMW_SYNC)) { -- if (pvmw->flags & PVMW_MIGRATION) { -- if (!is_swap_pte(*pvmw->pte)) -- return false; -- } else { -- if (!pte_present(*pvmw->pte)) -- return false; -- } -- } -- pvmw->ptl = pte_lockptr(pvmw->vma->vm_mm, pvmw->pmd); -- spin_lock(pvmw->ptl); -- return true; --} -- --static bool check_pte(struct page_vma_mapped_walk *pvmw) --{ -- if (pvmw->flags & PVMW_MIGRATION) { --#ifdef CONFIG_MIGRATION -- swp_entry_t entry; -- if (!is_swap_pte(*pvmw->pte)) -- return false; -- entry = pte_to_swp_entry(*pvmw->pte); -- if (!is_migration_entry(entry)) -- return false; -- if (migration_entry_to_page(entry) - pvmw->page >= -- hpage_nr_pages(pvmw->page)) { -- return false; -- } -- if (migration_entry_to_page(entry) < pvmw->page) -- return false; --#else -- WARN_ON_ONCE(1); --#endif -- } else { -- if (!pte_present(*pvmw->pte)) -- return false; -- -- /* THP can be referenced by any subpage */ -- if (pte_page(*pvmw->pte) - pvmw->page >= -- hpage_nr_pages(pvmw->page)) { -- return false; -- } -- if (pte_page(*pvmw->pte) < pvmw->page) -- return false; -- } -- -- return true; --} -- --/** -- * page_vma_mapped_walk - check if @pvmw->page is mapped in @pvmw->vma at -- * @pvmw->address -- * @pvmw: pointer to struct page_vma_mapped_walk. page, vma, address and flags -- * must be set. pmd, pte and ptl must be NULL. -- * -- * Returns true if the page is mapped in the vma. @pvmw->pmd and @pvmw->pte point -- * to relevant page table entries. @pvmw->ptl is locked. @pvmw->address is -- * adjusted if needed (for PTE-mapped THPs). -- * -- * If @pvmw->pmd is set but @pvmw->pte is not, you have found PMD-mapped page -- * (usually THP). For PTE-mapped THP, you should run page_vma_mapped_walk() in -- * a loop to find all PTEs that map the THP. -- * -- * For HugeTLB pages, @pvmw->pte is set to the relevant page table entry -- * regardless of which page table level the page is mapped at. @pvmw->pmd is -- * NULL. -- * -- * Retruns false if there are no more page table entries for the page in -- * the vma. @pvmw->ptl is unlocked and @pvmw->pte is unmapped. -- * -- * If you need to stop the walk before page_vma_mapped_walk() returned false, -- * use page_vma_mapped_walk_done(). It will do the housekeeping. -- */ --bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw) --{ -- struct mm_struct *mm = pvmw->vma->vm_mm; -- struct page *page = pvmw->page; -- pgd_t *pgd; -- pud_t *pud; -- -- /* The only possible pmd mapping has been handled on last iteration */ -- if (pvmw->pmd && !pvmw->pte) -- return not_found(pvmw); -- -- /* Only for THP, seek to next pte entry makes sense */ -- if (pvmw->pte) { -- if (!PageTransHuge(pvmw->page) || PageHuge(pvmw->page)) -- return not_found(pvmw); -- goto next_pte; -- } -- -- if (unlikely(PageHuge(pvmw->page))) { -- /* when pud is not present, pte will be NULL */ -- pvmw->pte = huge_pte_offset(mm, pvmw->address); -- if (!pvmw->pte) -- return false; -- -- pvmw->ptl = huge_pte_lockptr(page_hstate(page), mm, pvmw->pte); -- spin_lock(pvmw->ptl); -- if (!check_pte(pvmw)) -- return not_found(pvmw); -- return true; -- } --restart: -- pgd = pgd_offset(mm, pvmw->address); -- if (!pgd_present(*pgd)) -- return false; -- pud = pud_offset(pgd, pvmw->address); -- if (!pud_present(*pud)) -- return false; -- pvmw->pmd = pmd_offset(pud, pvmw->address); -- if (pmd_trans_huge(*pvmw->pmd)) { -- pvmw->ptl = pmd_lock(mm, pvmw->pmd); -- if (!pmd_present(*pvmw->pmd)) -- return not_found(pvmw); -- if (likely(pmd_trans_huge(*pvmw->pmd))) { -- if (pvmw->flags & PVMW_MIGRATION) -- return not_found(pvmw); -- if (pmd_page(*pvmw->pmd) != page) -- return not_found(pvmw); -- return true; -- } else { -- /* THP pmd was split under us: handle on pte level */ -- spin_unlock(pvmw->ptl); -- pvmw->ptl = NULL; -- } -- } else { -- if (!check_pmd(pvmw)) -- return false; -- } -- if (!map_pte(pvmw)) -- goto next_pte; -- while (1) { -- if (check_pte(pvmw)) -- return true; --next_pte: do { -- pvmw->address += PAGE_SIZE; -- if (pvmw->address >= -- __vma_address(pvmw->page, pvmw->vma) + -- hpage_nr_pages(pvmw->page) * PAGE_SIZE) -- return not_found(pvmw); -- /* Did we cross page table boundary? */ -- if (pvmw->address % PMD_SIZE == 0) { -- pte_unmap(pvmw->pte); -- if (pvmw->ptl) { -- spin_unlock(pvmw->ptl); -- pvmw->ptl = NULL; -- } -- goto restart; -- } else { -- pvmw->pte++; -- } -- } while (pte_none(*pvmw->pte)); -- -- if (!pvmw->ptl) { -- pvmw->ptl = pte_lockptr(mm, pvmw->pmd); -- spin_lock(pvmw->ptl); -- } -- } --} --- -2.7.4 - diff --git a/swapops-0004-mm-ksm-handle-protnone-saved-writes-when-making-page.patch b/swapops-0004-mm-ksm-handle-protnone-saved-writes-when-making-page.patch deleted file mode 100644 index 3b48e10..0000000 --- a/swapops-0004-mm-ksm-handle-protnone-saved-writes-when-making-page.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 361de9fb44163c4e693022786af380a2b2298c6d Mon Sep 17 00:00:00 2001 -From: "Aneesh Kumar K.V" -Date: Fri, 24 Feb 2017 14:59:19 -0800 -Subject: [PATCH 4/4] mm/ksm: handle protnone saved writes when making page - write protect - -Without this KSM will consider the page write protected, but a numa -fault can later mark the page writable. This can result in memory -corruption. - -Link: http://lkml.kernel.org/r/1487498625-10891-3-git-send-email-aneesh.kumar@linux.vnet.ibm.com -Signed-off-by: Aneesh Kumar K.V -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds -(backported from commit 595cd8f256d24face93b2722927ec9c980419c26) -Signed-off-by: Seth Forshee ---- - include/asm-generic/pgtable.h | 8 ++++++++ - mm/ksm.c | 9 +++++++-- - 2 files changed, 15 insertions(+), 2 deletions(-) - -diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h -index b6f3a8a4b738..8c8ba48bef0b 100644 ---- a/include/asm-generic/pgtable.h -+++ b/include/asm-generic/pgtable.h -@@ -200,6 +200,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres - #define pte_mk_savedwrite pte_mkwrite - #endif - -+#ifndef pte_clear_savedwrite -+#define pte_clear_savedwrite pte_wrprotect -+#endif -+ - #ifndef pmd_savedwrite - #define pmd_savedwrite pmd_write - #endif -@@ -208,6 +212,10 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres - #define pmd_mk_savedwrite pmd_mkwrite - #endif - -+#ifndef pmd_clear_savedwrite -+#define pmd_clear_savedwrite pmd_wrprotect -+#endif -+ - #ifndef __HAVE_ARCH_PMDP_SET_WRPROTECT - #ifdef CONFIG_TRANSPARENT_HUGEPAGE - static inline void pmdp_set_wrprotect(struct mm_struct *mm, -diff --git a/mm/ksm.c b/mm/ksm.c -index fed4afd8293b..099dfa45d596 100644 ---- a/mm/ksm.c -+++ b/mm/ksm.c -@@ -878,7 +878,8 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, - if (!ptep) - goto out_mn; - -- if (pte_write(*ptep) || pte_dirty(*ptep)) { -+ if (pte_write(*ptep) || pte_dirty(*ptep) || -+ (pte_protnone(*ptep) && pte_savedwrite(*ptep))) { - pte_t entry; - - swapped = PageSwapCache(page); -@@ -903,7 +904,11 @@ static int write_protect_page(struct vm_area_struct *vma, struct page *page, - } - if (pte_dirty(entry)) - set_page_dirty(page); -- entry = pte_mkclean(pte_wrprotect(entry)); -+ -+ if (pte_protnone(entry)) -+ entry = pte_mkclean(pte_clear_savedwrite(entry)); -+ else -+ entry = pte_mkclean(pte_wrprotect(entry)); - set_pte_at_notify(mm, addr, ptep, entry); - } - *orig_pte = *ptep; --- -2.7.4 -