From: Wang Wensheng wangwensheng4@huawei.com
ascend inclusion category: Feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4NDAW CVE: NA
-------------------
Change the mmap_base in mm_struct and check the limit in get_unmapped_area.
Signed-off-by: Wang Wensheng wangwensheng4@huawei.com Signed-off-by: Peng Wu wupeng58@huawei.com Reviewed-by: Kefeng Wangwangkefeng.wang@huawei.com Reviewed-by: Weilong Chen chenweilong@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- include/linux/share_pool.h | 12 +++++++++++- mm/mmap.c | 7 +++++++ mm/util.c | 4 ++++ 3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h index 37a26487a7d8..3a56238c8a4d 100644 --- a/include/linux/share_pool.h +++ b/include/linux/share_pool.h @@ -262,6 +262,16 @@ static inline bool sp_is_enabled(void) return static_branch_likely(&share_pool_enabled_key); }
+static inline void sp_area_work_around(struct vm_unmapped_area_info *info, + unsigned long flags) +{ + /* the MAP_DVPP couldn't work with MAP_SHARE_POOL. In addition, the + * address ranges corresponding to the two flags must not overlap. + */ + if (sp_is_enabled() && !(flags & MAP_DVPP)) + info->high_limit = min(info->high_limit, MMAP_SHARE_POOL_START); +} + #else /* CONFIG_ASCEND_SHARE_POOL */
static inline int mg_sp_group_add_task(int pid, unsigned long prot, int spg_id) @@ -442,7 +452,7 @@ static inline bool sp_is_enabled(void) return false; }
-static inline void sp_area_work_around(struct vm_unmapped_area_info *info) +static inline void sp_area_work_around(struct vm_unmapped_area_info *info, unsigned long flags) { }
diff --git a/mm/mmap.c b/mm/mmap.c index 0af1300734a2..d5a97a56dca7 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -48,6 +48,7 @@ #include <linux/oom.h> #include <linux/sched/mm.h> #include <linux/swapops.h> +#include <linux/share_pool.h>
#include <linux/uaccess.h> #include <asm/cacheflush.h> @@ -2450,6 +2451,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, if (enable_mmap_dvpp) dvpp_mmap_get_area(&info, flags);
+ sp_area_work_around(&info, flags); + return vm_unmapped_area(&info); } #endif @@ -2500,6 +2503,8 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, if (enable_mmap_dvpp) dvpp_mmap_get_area(&info, flags);
+ sp_area_work_around(&info, flags); + addr = vm_unmapped_area(&info);
/* @@ -2517,6 +2522,8 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, if (enable_mmap_dvpp) dvpp_mmap_get_area(&info, flags);
+ sp_area_work_around(&info, flags); + addr = vm_unmapped_area(&info); }
diff --git a/mm/util.c b/mm/util.c index 2350c064abc6..d31820abadb4 100644 --- a/mm/util.c +++ b/mm/util.c @@ -23,6 +23,7 @@ #include <linux/processor.h> #include <linux/sizes.h> #include <linux/compat.h> +#include <linux/share_pool.h>
#include <linux/uaccess.h> #include <linux/oom.h> @@ -392,6 +393,9 @@ static unsigned long mmap_base(unsigned long rnd, struct rlimit *rlim_stack) else if (gap > MAX_GAP) gap = MAX_GAP;
+ if (sp_is_enabled()) + return ALIGN_DOWN(MMAP_SHARE_POOL_START - rnd, PAGE_SIZE); + return PAGE_ALIGN(STACK_TOP - gap - rnd); }