提交 a051590c 编写于 作者: T Tang Yizhou 提交者: Yang Yingliang

share_pool: share_pool: Don't allow non-sp mmap in sp address range

ascend inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I4EUVI
CVE: NA

-------------------------------------------------

The situation below is not allowed:

int *result = mmap(ADDR, sizeof(int), PROT_READ | PROT_WRITE,
	MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);

As share pool uses an independent UVA allocation algorithm, it may
produce an address that is conflicted with user-specified address.
Signed-off-by: NTang Yizhou <tangyizhou@huawei.com>
Reviewed-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 a80d250a
...@@ -292,6 +292,9 @@ static inline void sp_free_pages(struct page *page, struct vm_struct *area) ...@@ -292,6 +292,9 @@ static inline void sp_free_pages(struct page *page, struct vm_struct *area)
__free_pages(page, is_vmalloc_huge(area->flags) ? PMD_SHIFT - PAGE_SHIFT : 0); __free_pages(page, is_vmalloc_huge(area->flags) ? PMD_SHIFT - PAGE_SHIFT : 0);
} }
extern bool sp_check_addr(unsigned long addr);
extern bool sp_check_mmap_addr(unsigned long addr, unsigned long flags);
#else #else
static inline int sp_group_add_task(int pid, int spg_id) static inline int sp_group_add_task(int pid, int spg_id)
...@@ -495,6 +498,17 @@ static inline int sp_node_id(struct vm_area_struct *vma) ...@@ -495,6 +498,17 @@ static inline int sp_node_id(struct vm_area_struct *vma)
{ {
return numa_node_id(); return numa_node_id();
} }
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 #endif
#endif /* LINUX_SHARE_POOL_H */ #endif /* LINUX_SHARE_POOL_H */
...@@ -2354,6 +2354,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, ...@@ -2354,6 +2354,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
if (flags & MAP_FIXED) if (flags & MAP_FIXED)
return addr; return addr;
if (sp_check_mmap_addr(addr, flags))
return -EINVAL;
if (addr) { if (addr) {
addr = PAGE_ALIGN(addr); addr = PAGE_ALIGN(addr);
...@@ -2405,6 +2408,9 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, ...@@ -2405,6 +2408,9 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
if (flags & MAP_FIXED) if (flags & MAP_FIXED)
return addr; return addr;
if (sp_check_mmap_addr(addr, flags))
return -EINVAL;
/* requesting a specific address */ /* requesting a specific address */
if (addr) { if (addr) {
addr = PAGE_ALIGN(addr); addr = PAGE_ALIGN(addr);
...@@ -3111,6 +3117,9 @@ int vm_munmap(unsigned long start, size_t len) ...@@ -3111,6 +3117,9 @@ int vm_munmap(unsigned long start, size_t len)
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
LIST_HEAD(uf); LIST_HEAD(uf);
if (sp_check_addr(start))
return -EINVAL;
if (down_write_killable(&mm->mmap_sem)) if (down_write_killable(&mm->mmap_sem))
return -EINTR; return -EINTR;
...@@ -3129,6 +3138,9 @@ int do_vm_munmap(struct mm_struct *mm, unsigned long start, size_t len) ...@@ -3129,6 +3138,9 @@ int do_vm_munmap(struct mm_struct *mm, unsigned long start, size_t len)
if (mm == NULL) if (mm == NULL)
return -EINVAL; return -EINVAL;
if (sp_check_addr(start))
return -EINVAL;
if (down_write_killable(&mm->mmap_sem)) if (down_write_killable(&mm->mmap_sem))
return -EINTR; return -EINTR;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/mm-arch-hooks.h> #include <linux/mm-arch-hooks.h>
#include <linux/userfaultfd_k.h> #include <linux/userfaultfd_k.h>
#include <linux/share_pool.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
...@@ -534,6 +535,9 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len, ...@@ -534,6 +535,9 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
if (offset_in_page(addr)) if (offset_in_page(addr))
return ret; return ret;
if (sp_check_addr(addr) || sp_check_addr(new_addr))
return ret;
old_len = PAGE_ALIGN(old_len); old_len = PAGE_ALIGN(old_len);
new_len = PAGE_ALIGN(new_len); new_len = PAGE_ALIGN(new_len);
......
...@@ -58,6 +58,8 @@ ...@@ -58,6 +58,8 @@
#define byte2mb(size) ((size) >> 20) #define byte2mb(size) ((size) >> 20)
#define page2kb(page_num) ((page_num) << (PAGE_SHIFT - 10)) #define page2kb(page_num) ((page_num) << (PAGE_SHIFT - 10))
#define PF_DOMAIN_CORE 0x10000000 /* AOS CORE processes in sched.h */
/* mdc scene hack */ /* mdc scene hack */
static int __read_mostly enable_mdc_default_group; static int __read_mostly enable_mdc_default_group;
static const int mdc_default_group_id = 1; static const int mdc_default_group_id = 1;
...@@ -334,6 +336,14 @@ static inline void check_interrupt_context(void) ...@@ -334,6 +336,14 @@ static inline void check_interrupt_context(void)
panic("share_pool: can't be used in interrupt context\n"); panic("share_pool: can't be used in interrupt context\n");
} }
static inline bool check_aoscore_process(struct task_struct *tsk)
{
if (tsk->flags & PF_DOMAIN_CORE)
return true;
else
return false;
}
static unsigned long sp_mmap(struct mm_struct *mm, struct file *file, static unsigned long sp_mmap(struct mm_struct *mm, struct file *file,
struct sp_area *spa, unsigned long *populate); struct sp_area *spa, unsigned long *populate);
static void sp_munmap(struct mm_struct *mm, unsigned long addr, unsigned long size); static void sp_munmap(struct mm_struct *mm, unsigned long addr, unsigned long size);
...@@ -675,6 +685,14 @@ int sp_group_add_task(int pid, int spg_id) ...@@ -675,6 +685,14 @@ int sp_group_add_task(int pid, int spg_id)
goto out; goto out;
} }
if (check_aoscore_process(tsk)) {
up_write(&sp_group_sem);
ret = -EACCES;
free_new_spg_id(id_newly_generated, spg_id);
sp_dump_stack();
goto out_put_task;
}
/* /*
* group_leader: current thread may be exiting in a multithread process * group_leader: current thread may be exiting in a multithread process
* *
...@@ -3030,6 +3048,26 @@ void __init proc_sharepool_init(void) ...@@ -3030,6 +3048,26 @@ void __init proc_sharepool_init(void)
/*** End of tatistical and maintenance functions ***/ /*** End of tatistical and maintenance functions ***/
bool sp_check_addr(unsigned long addr)
{
if (enable_ascend_share_pool && is_sharepool_addr(addr) &&
!check_aoscore_process(current)) {
sp_dump_stack();
return true;
} else
return false;
}
bool sp_check_mmap_addr(unsigned long addr, unsigned long flags)
{
if (enable_ascend_share_pool && is_sharepool_addr(addr) &&
!check_aoscore_process(current) && !(flags & MAP_SHARE_POOL)) {
sp_dump_stack();
return true;
} else
return false;
}
vm_fault_t sharepool_no_page(struct mm_struct *mm, vm_fault_t sharepool_no_page(struct mm_struct *mm,
struct vm_area_struct *vma, struct vm_area_struct *vma,
struct address_space *mapping, pgoff_t idx, struct address_space *mapping, pgoff_t idx,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册