diff options
Diffstat (limited to 'libre/linux-libre-hardened/0001-Revert-mm-sparsemem-fix-race-in-accessing-memory_sec.patch')
-rw-r--r-- | libre/linux-libre-hardened/0001-Revert-mm-sparsemem-fix-race-in-accessing-memory_sec.patch | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/libre/linux-libre-hardened/0001-Revert-mm-sparsemem-fix-race-in-accessing-memory_sec.patch b/libre/linux-libre-hardened/0001-Revert-mm-sparsemem-fix-race-in-accessing-memory_sec.patch new file mode 100644 index 000000000..43e1b5d41 --- /dev/null +++ b/libre/linux-libre-hardened/0001-Revert-mm-sparsemem-fix-race-in-accessing-memory_sec.patch @@ -0,0 +1,103 @@ +From 95fa13c9fe928ae6e21c1554360b5cada74cc857 Mon Sep 17 00:00:00 2001 +From: Levente Polyak <levente@leventepolyak.net> +Date: Fri, 2 Feb 2024 02:03:34 +0100 +Subject: [PATCH] Revert "mm/sparsemem: fix race in accessing + memory_section->usage" + +This reverts commit 3a01daace71b521563c38bbbf874e14c3e58adb7. +--- + include/linux/mmzone.h | 14 +++----------- + mm/sparse.c | 17 ++++++++--------- + 2 files changed, 11 insertions(+), 20 deletions(-) + +diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h +index a7c32324c263..9db36e197712 100644 +--- a/include/linux/mmzone.h ++++ b/include/linux/mmzone.h +@@ -1793,7 +1793,6 @@ static inline unsigned long section_nr_to_pfn(unsigned long sec) + #define SUBSECTION_ALIGN_DOWN(pfn) ((pfn) & PAGE_SUBSECTION_MASK) + + struct mem_section_usage { +- struct rcu_head rcu; + #ifdef CONFIG_SPARSEMEM_VMEMMAP + DECLARE_BITMAP(subsection_map, SUBSECTIONS_PER_SECTION); + #endif +@@ -1987,7 +1986,7 @@ static inline int pfn_section_valid(struct mem_section *ms, unsigned long pfn) + { + int idx = subsection_map_index(pfn); + +- return test_bit(idx, READ_ONCE(ms->usage)->subsection_map); ++ return test_bit(idx, ms->usage->subsection_map); + } + #else + static inline int pfn_section_valid(struct mem_section *ms, unsigned long pfn) +@@ -2011,7 +2010,6 @@ static inline int pfn_section_valid(struct mem_section *ms, unsigned long pfn) + static inline int pfn_valid(unsigned long pfn) + { + struct mem_section *ms; +- int ret; + + /* + * Ensure the upper PAGE_SHIFT bits are clear in the +@@ -2025,19 +2023,13 @@ static inline int pfn_valid(unsigned long pfn) + if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS) + return 0; + ms = __pfn_to_section(pfn); +- rcu_read_lock(); +- if (!valid_section(ms)) { +- rcu_read_unlock(); ++ if (!valid_section(ms)) + return 0; +- } + /* + * Traditionally early sections always returned pfn_valid() for + * the entire section-sized span. + */ +- ret = early_section(ms) || pfn_section_valid(ms, pfn); +- rcu_read_unlock(); +- +- return ret; ++ return early_section(ms) || pfn_section_valid(ms, pfn); + } + #endif + +diff --git a/mm/sparse.c b/mm/sparse.c +index 338cf946dee8..77d91e565045 100644 +--- a/mm/sparse.c ++++ b/mm/sparse.c +@@ -791,13 +791,6 @@ static void section_deactivate(unsigned long pfn, unsigned long nr_pages, + if (empty) { + unsigned long section_nr = pfn_to_section_nr(pfn); + +- /* +- * Mark the section invalid so that valid_section() +- * return false. This prevents code from dereferencing +- * ms->usage array. +- */ +- ms->section_mem_map &= ~SECTION_HAS_MEM_MAP; +- + /* + * When removing an early section, the usage map is kept (as the + * usage maps of other sections fall into the same page). It +@@ -806,10 +799,16 @@ static void section_deactivate(unsigned long pfn, unsigned long nr_pages, + * was allocated during boot. + */ + if (!PageReserved(virt_to_page(ms->usage))) { +- kfree_rcu(ms->usage, rcu); +- WRITE_ONCE(ms->usage, NULL); ++ kfree(ms->usage); ++ ms->usage = NULL; + } + memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr); ++ /* ++ * Mark the section invalid so that valid_section() ++ * return false. This prevents code from dereferencing ++ * ms->usage array. ++ */ ++ ms->section_mem_map &= ~SECTION_HAS_MEM_MAP; + } + + /* +-- +2.43.0 + |