提交 03714218 编写于 作者: Z ZhangPeng 提交者: Ma Wupeng

userswap: add checks for input addresses

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6CAIM

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

Add checks for new_addr in uswap_mremap() and src_addr in
uswap_check_copy_mode(), including user mode checks, overlapping
checks, etc.
Signed-off-by: NZhangPeng <zhangpeng362@huawei.com>
上级 74c0e7cd
...@@ -36,10 +36,22 @@ bool uswap_adjust_uffd_range(struct uffdio_register *uffdio_register, ...@@ -36,10 +36,22 @@ bool uswap_adjust_uffd_range(struct uffdio_register *uffdio_register,
bool do_uswap_page(swp_entry_t entry, struct vm_fault *vmf, bool do_uswap_page(swp_entry_t entry, struct vm_fault *vmf,
struct vm_area_struct *vma, vm_fault_t *ret); struct vm_area_struct *vma, vm_fault_t *ret);
static inline bool uswap_check_copy_mode(struct vm_area_struct *vma, __u64 mode) static inline bool uswap_check_copy(struct vm_area_struct *vma,
unsigned long src_addr,
unsigned long len, __u64 mode)
{ {
if (!(vma->vm_flags & VM_USWAP) && (mode & UFFDIO_COPY_MODE_DIRECT_MAP)) if (vma->vm_flags & VM_USWAP) {
return false; if (!(mode & UFFDIO_COPY_MODE_DIRECT_MAP))
return false;
if (offset_in_page(src_addr))
return false;
if (src_addr > TASK_SIZE || src_addr > TASK_SIZE - len)
return false;
} else {
if (mode & UFFDIO_COPY_MODE_DIRECT_MAP)
return false;
}
return true; return true;
} }
......
...@@ -512,7 +512,7 @@ static __always_inline ssize_t __mcopy_atomic(struct mm_struct *dst_mm, ...@@ -512,7 +512,7 @@ static __always_inline ssize_t __mcopy_atomic(struct mm_struct *dst_mm,
err = -EINVAL; err = -EINVAL;
#ifdef CONFIG_USERSWAP #ifdef CONFIG_USERSWAP
if (!uswap_check_copy_mode(dst_vma, mode)) if (!uswap_check_copy(dst_vma, src_addr, len, mode))
goto out_unlock; goto out_unlock;
#endif #endif
/* /*
......
...@@ -364,7 +364,14 @@ unsigned long uswap_mremap(unsigned long old_addr, unsigned long old_len, ...@@ -364,7 +364,14 @@ unsigned long uswap_mremap(unsigned long old_addr, unsigned long old_len,
unsigned long i; unsigned long i;
if (!len || old_len != new_len || offset_in_page(old_addr) || if (!len || old_len != new_len || offset_in_page(old_addr) ||
(len % PAGE_SIZE)) offset_in_page(new_addr) || (len % PAGE_SIZE))
return ret;
if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
return ret;
/* Ensure the old/new locations do not overlap */
if (old_addr + old_len > new_addr && new_addr + new_len > old_addr)
return ret; return ret;
down_read(&mm->mmap_lock); down_read(&mm->mmap_lock);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册