提交 dfe53b35 编写于 作者: X Xiongfeng Wang 提交者: Yang Yingliang

userswap: add a kernel parameter to enable userswap

hulk inclusion
category: bugfix
bugzilla: 175146
CVE: NA

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

Disable userswap by default and add a kernel parameter to enable it.
Signed-off-by: NXiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: NKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 c2ec8d8c
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
#include <linux/hugetlb.h> #include <linux/hugetlb.h>
static struct kmem_cache *userfaultfd_ctx_cachep __read_mostly; static struct kmem_cache *userfaultfd_ctx_cachep __read_mostly;
#ifdef CONFIG_USERSWAP
int enable_userswap;
#endif
enum userfaultfd_state { enum userfaultfd_state {
UFFD_STATE_WAIT_API, UFFD_STATE_WAIT_API,
...@@ -906,7 +909,8 @@ static int userfaultfd_release(struct inode *inode, struct file *file) ...@@ -906,7 +909,8 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
for (vma = mm->mmap; vma; vma = vma->vm_next) { for (vma = mm->mmap; vma; vma = vma->vm_next) {
userfault_flags = VM_UFFD_MISSING | VM_UFFD_WP; userfault_flags = VM_UFFD_MISSING | VM_UFFD_WP;
#ifdef CONFIG_USERSWAP #ifdef CONFIG_USERSWAP
userfault_flags |= VM_USWAP; if (enable_userswap)
userfault_flags |= VM_USWAP;
#endif #endif
cond_resched(); cond_resched();
BUG_ON(!!vma->vm_userfaultfd_ctx.ctx ^ BUG_ON(!!vma->vm_userfaultfd_ctx.ctx ^
...@@ -1335,7 +1339,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, ...@@ -1335,7 +1339,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
* register the whole vma overlapping with the address range to avoid * register the whole vma overlapping with the address range to avoid
* splitting the vma. * splitting the vma.
*/ */
if (uffdio_register.mode & UFFDIO_REGISTER_MODE_USWAP) { if (enable_userswap && (uffdio_register.mode & UFFDIO_REGISTER_MODE_USWAP)) {
uffdio_register.mode &= ~UFFDIO_REGISTER_MODE_USWAP; uffdio_register.mode &= ~UFFDIO_REGISTER_MODE_USWAP;
if (!uffdio_register.mode) if (!uffdio_register.mode)
goto out; goto out;
...@@ -2008,6 +2012,15 @@ SYSCALL_DEFINE1(userfaultfd, int, flags) ...@@ -2008,6 +2012,15 @@ SYSCALL_DEFINE1(userfaultfd, int, flags)
return fd; return fd;
} }
#ifdef CONFIG_USERSWAP
static int __init enable_userswap_setup(char *str)
{
enable_userswap = true;
return 1;
}
__setup("enable_userswap", enable_userswap_setup);
#endif
static int __init userfaultfd_init(void) static int __init userfaultfd_init(void)
{ {
userfaultfd_ctx_cachep = kmem_cache_create("userfaultfd_ctx_cache", userfaultfd_ctx_cachep = kmem_cache_create("userfaultfd_ctx_cache",
......
...@@ -28,6 +28,10 @@ ...@@ -28,6 +28,10 @@
#define UFFD_SHARED_FCNTL_FLAGS (O_CLOEXEC | O_NONBLOCK) #define UFFD_SHARED_FCNTL_FLAGS (O_CLOEXEC | O_NONBLOCK)
#define UFFD_FLAGS_SET (EFD_SHARED_FCNTL_FLAGS) #define UFFD_FLAGS_SET (EFD_SHARED_FCNTL_FLAGS)
#ifdef CONFIG_USERSWAP
extern int enable_userswap;
#endif
extern vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason); extern vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason);
extern ssize_t mcopy_atomic(struct mm_struct *dst_mm, unsigned long dst_start, extern ssize_t mcopy_atomic(struct mm_struct *dst_mm, unsigned long dst_start,
......
...@@ -1580,7 +1580,7 @@ unsigned long __do_mmap(struct mm_struct *mm, struct file *file, ...@@ -1580,7 +1580,7 @@ unsigned long __do_mmap(struct mm_struct *mm, struct file *file,
prot |= PROT_EXEC; prot |= PROT_EXEC;
#ifdef CONFIG_USERSWAP #ifdef CONFIG_USERSWAP
if (flags & MAP_REPLACE) { if (enable_userswap && (flags & MAP_REPLACE)) {
if (offset_in_page(addr) || (len % PAGE_SIZE)) if (offset_in_page(addr) || (len % PAGE_SIZE))
return -EINVAL; return -EINVAL;
page_num = len / PAGE_SIZE; page_num = len / PAGE_SIZE;
...@@ -1768,7 +1768,7 @@ unsigned long __do_mmap(struct mm_struct *mm, struct file *file, ...@@ -1768,7 +1768,7 @@ unsigned long __do_mmap(struct mm_struct *mm, struct file *file,
#ifdef CONFIG_USERSWAP #ifdef CONFIG_USERSWAP
/* mark the vma as special to avoid merging with other vmas */ /* mark the vma as special to avoid merging with other vmas */
if (flags & MAP_REPLACE) if (enable_userswap && (flags & MAP_REPLACE))
vm_flags |= VM_SPECIAL; vm_flags |= VM_SPECIAL;
#endif #endif
...@@ -1780,7 +1780,7 @@ unsigned long __do_mmap(struct mm_struct *mm, struct file *file, ...@@ -1780,7 +1780,7 @@ unsigned long __do_mmap(struct mm_struct *mm, struct file *file,
#ifndef CONFIG_USERSWAP #ifndef CONFIG_USERSWAP
return addr; return addr;
#else #else
if (!(flags & MAP_REPLACE)) if (!enable_userswap || !(flags & MAP_REPLACE))
return addr; return addr;
if (IS_ERR_VALUE(addr)) { if (IS_ERR_VALUE(addr)) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册