ascend inclusion category: Feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8LNGH
---------------------------------------------
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 | 27 +++++++++++++++++++++++++++ mm/mmap.c | 9 +++++++++ mm/mremap.c | 4 ++++ 3 files changed, 40 insertions(+)
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h index 87ce9eb9fa3e..bd2e0ca8f975 100644 --- a/include/linux/share_pool.h +++ b/include/linux/share_pool.h @@ -157,6 +157,23 @@ static inline void sp_init_mm(struct mm_struct *mm) mm->sp_group_master = NULL; }
+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) @@ -245,6 +262,16 @@ static inline bool sp_check_vm_share_pool(unsigned long vm_flags) { return false; } + +static inline bool sp_check_addr(unsigned long addr) +{ + return false; +} + +static inline bool sp_check_mmap_addr(unsigned long addr, unsigned long flags) +{ + return false; +} #endif /* !CONFIG_SHARE_POOL */
#endif /* LINUX_SHARE_POOL_H */ diff --git a/mm/mmap.c b/mm/mmap.c index ff9d9a8d25ce..21d1fc39bf21 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1720,6 +1720,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;
@@ -1769,6 +1772,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;
@@ -2949,6 +2955,9 @@ static int __vm_munmap(unsigned long start, size_t len, bool unlock) 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 382e81c33fc4..b6979f9d687c 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> @@ -948,6 +949,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);