Commit 80efa5c8 authored by Xiongfeng Wang's avatar Xiongfeng Wang Committed by Zheng Zengkai
Browse files

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: default avatarXiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: default avatarKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>

 Conflicts:
	include/linux/userfaultfd_k.h
Signed-off-by: default avatarXiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: default avatarKefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 84ff5e27
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@
int sysctl_unprivileged_userfaultfd __read_mostly = 1;

static struct kmem_cache *userfaultfd_ctx_cachep __read_mostly;
#ifdef CONFIG_USERSWAP
int enable_userswap;
#endif

enum userfaultfd_state {
	UFFD_STATE_WAIT_API,
@@ -863,6 +866,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
	for (vma = mm->mmap; vma; vma = vma->vm_next) {
		userfault_flags = VM_UFFD_MISSING | VM_UFFD_WP;
#ifdef CONFIG_USERSWAP
		if (enable_userswap)
			userfault_flags |= VM_USWAP;
#endif
		cond_resched();
@@ -1295,7 +1299,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
	 * register the whole vma overlapping with the address range to avoid
	 * 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;
		if (!uffdio_register.mode)
			goto out;
@@ -2024,6 +2028,15 @@ SYSCALL_DEFINE1(userfaultfd, int, flags)
	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)
{
	userfaultfd_ctx_cachep = kmem_cache_create("userfaultfd_ctx_cache",
+3 −0
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@
#define UFFD_FLAGS_SET (EFD_SHARED_FCNTL_FLAGS)

extern int sysctl_unprivileged_userfaultfd;
#ifdef CONFIG_USERSWAP
extern int enable_userswap;
#endif

extern vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason);

+3 −3
Original line number Diff line number Diff line
@@ -1598,7 +1598,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
			prot |= PROT_EXEC;

#ifdef CONFIG_USERSWAP
	if (flags & MAP_REPLACE) {
	if (enable_userswap && (flags & MAP_REPLACE)) {
		if (offset_in_page(addr) || (len % PAGE_SIZE))
			return -EINVAL;
		page_num = len / PAGE_SIZE;
@@ -1765,7 +1765,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr,

#ifdef CONFIG_USERSWAP
	/* 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;
#endif

@@ -1777,7 +1777,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
#ifndef CONFIG_USERSWAP
	return addr;
#else
	if (!(flags & MAP_REPLACE))
	if (!enable_userswap || !(flags & MAP_REPLACE))
		return addr;

	if (IS_ERR_VALUE(addr)) {