ascend inclusion category: Feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7YF5R
---------------------------------------------
Add protections for the va reserved for sharepool. Forbid mremap/munmap to access that range.
Signed-off-by: Wang Wensheng wangwensheng4@huawei.com --- include/linux/share_pool.h | 31 ++++++++++++++++++++----------- mm/mmap.c | 9 +++++++++ mm/mremap.c | 4 ++++ 3 files changed, 33 insertions(+), 11 deletions(-)
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h index b0711eea4b73..693ceea5999b 100644 --- a/include/linux/share_pool.h +++ b/include/linux/share_pool.h @@ -158,6 +158,23 @@ static inline bool sp_check_vm_share_pool(unsigned long vm_flags) return false; }
+static inline bool sp_check_addr(unsigned long addr) +{ + if (sp_is_enabled() && mg_is_sharepool_addr(addr)) + return true; + else + return false; +} + +static inline bool sp_check_mmap_addr(unsigned long addr, unsigned long flags) +{ + if (sp_is_enabled() && mg_is_sharepool_addr(addr) && + !(flags & MAP_SHARE_POOL)) + return true; + else + return false; +} + #else /* CONFIG_SHARE_POOL */
static inline int mg_sp_group_add_task(int tgid, unsigned long prot, int spg_id) @@ -233,14 +250,6 @@ static inline bool mg_is_sharepool_addr(unsigned long addr) return false; }
-static inline void spa_overview_show(struct seq_file *seq) -{ -} - -static inline void spg_overview_show(struct seq_file *seq) -{ -} - static inline bool sp_is_enabled(void) { return false; @@ -255,14 +264,14 @@ static inline bool sp_check_vm_share_pool(unsigned long vm_flags) return false; }
-static inline bool is_vm_huge_special(struct vm_area_struct *vma) +static inline bool sp_check_addr(unsigned long addr) { return false; }
-static inline int sp_node_id(struct vm_area_struct *vma) +static inline bool sp_check_mmap_addr(unsigned long addr, unsigned long flags) { - return numa_node_id(); + return false; }
#endif /* !CONFIG_SHARE_POOL */ diff --git a/mm/mmap.c b/mm/mmap.c index 1e5a20d81aa9..eb24efdba25d 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1765,6 +1765,9 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr, if (len > mmap_end - mmap_min_addr) return -ENOMEM;
+ if (sp_check_mmap_addr(addr, flags)) + return -EINVAL; + if (flags & MAP_FIXED) return addr;
@@ -1814,6 +1817,9 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr, if (len > mmap_end - mmap_min_addr) return -ENOMEM;
+ if (sp_check_mmap_addr(addr, flags)) + return -EINVAL; + if (flags & MAP_FIXED) return addr;
@@ -3083,6 +3089,9 @@ static int __vm_munmap(unsigned long start, size_t len, bool downgrade) LIST_HEAD(uf); VMA_ITERATOR(vmi, mm, start);
+ if (sp_check_addr(start)) + return -EINVAL; + if (mmap_write_lock_killable(mm)) return -EINTR;
diff --git a/mm/mremap.c b/mm/mremap.c index b11ce6c92099..add907c0a9af 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -25,6 +25,7 @@ #include <linux/uaccess.h> #include <linux/userfaultfd_k.h> #include <linux/mempolicy.h> +#include <linux/share_pool.h>
#include <asm/cacheflush.h> #include <asm/tlb.h> @@ -936,6 +937,9 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, if (offset_in_page(addr)) return ret;
+ if (sp_check_addr(addr) || sp_check_addr(new_addr)) + return ret; + old_len = PAGE_ALIGN(old_len); new_len = PAGE_ALIGN(new_len);