From: Fang Lijun fanglijun3@huawei.com
ascend inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4D63I CVE: NA
-------------------------------------------------
An interface do_vm_mmap is added to support the allocation in the address spaces of other processes.
Signed-off-by: Fang Lijun fanglijun3@huawei.com Signed-off-by: Zhou Guanghui zhouguanghui1@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- include/linux/mm.h | 3 +++ mm/mmap.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+)
diff --git a/include/linux/mm.h b/include/linux/mm.h index 75d94ea5d1c20..58fe28dd959b9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2436,6 +2436,9 @@ static inline void mm_populate(unsigned long addr, unsigned long len) {} extern int __must_check vm_brk(unsigned long, unsigned long); extern int __must_check vm_brk_flags(unsigned long, unsigned long, unsigned long); extern int vm_munmap(unsigned long, size_t); +extern unsigned long do_vm_mmap(struct mm_struct *mm, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long pgoff); extern unsigned long __must_check vm_mmap(struct file *, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); diff --git a/mm/mmap.c b/mm/mmap.c index 80779bbb1c048..f7f1fd3b5fa39 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -3094,6 +3094,40 @@ int vm_munmap(unsigned long start, size_t len) } EXPORT_SYMBOL(vm_munmap);
+/* + * Must acquire an additional reference to the mm struct to prevent the + * mm struct of other process from being released. + * + * This interface is applicable only to kernel thread scenarios. + */ +unsigned long do_vm_mmap(struct mm_struct *mm, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long pgoff) +{ + unsigned long ret; + unsigned long populate; + LIST_HEAD(uf); + + if (mm == NULL || current->mm) + return -EINVAL; + + if (down_write_killable(&mm->mmap_sem)) + return -EINTR; + + current->mm = mm; + ret = do_mmap_pgoff(0, addr, len, prot, flag, pgoff, + &populate, &uf); + + current->mm = NULL; + up_write(&mm->mmap_sem); + userfaultfd_unmap_complete(mm, &uf); + if (populate) + mm_populate(ret, populate); + + return ret; +} +EXPORT_SYMBOL(do_vm_mmap); + SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { profile_munmap(addr);