diff options
Diffstat (limited to 'fs/userfaultfd.c')
| -rw-r--r-- | fs/userfaultfd.c | 23 | 
1 files changed, 14 insertions, 9 deletions
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index f9fd18670e22..37df7c9eedb1 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -1460,7 +1460,8 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,  			start = vma->vm_start;  		vma_end = min(end, vma->vm_end); -		new_flags = (vma->vm_flags & ~vm_flags) | vm_flags; +		new_flags = (vma->vm_flags & +			     ~(VM_UFFD_MISSING|VM_UFFD_WP)) | vm_flags;  		prev = vma_merge(mm, prev, start, vma_end, new_flags,  				 vma->anon_vma, vma->vm_file, vma->vm_pgoff,  				 vma_policy(vma), @@ -1834,13 +1835,12 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx,  	if (copy_from_user(&uffdio_api, buf, sizeof(uffdio_api)))  		goto out;  	features = uffdio_api.features; -	if (uffdio_api.api != UFFD_API || (features & ~UFFD_API_FEATURES)) { -		memset(&uffdio_api, 0, sizeof(uffdio_api)); -		if (copy_to_user(buf, &uffdio_api, sizeof(uffdio_api))) -			goto out; -		ret = -EINVAL; -		goto out; -	} +	ret = -EINVAL; +	if (uffdio_api.api != UFFD_API || (features & ~UFFD_API_FEATURES)) +		goto err_out; +	ret = -EPERM; +	if ((features & UFFD_FEATURE_EVENT_FORK) && !capable(CAP_SYS_PTRACE)) +		goto err_out;  	/* report all available features and ioctls to userland */  	uffdio_api.features = UFFD_API_FEATURES;  	uffdio_api.ioctls = UFFD_API_IOCTLS; @@ -1853,6 +1853,11 @@ static int userfaultfd_api(struct userfaultfd_ctx *ctx,  	ret = 0;  out:  	return ret; +err_out: +	memset(&uffdio_api, 0, sizeof(uffdio_api)); +	if (copy_to_user(buf, &uffdio_api, sizeof(uffdio_api))) +		ret = -EFAULT; +	goto out;  }  static long userfaultfd_ioctl(struct file *file, unsigned cmd, @@ -1923,7 +1928,7 @@ static const struct file_operations userfaultfd_fops = {  	.poll		= userfaultfd_poll,  	.read		= userfaultfd_read,  	.unlocked_ioctl = userfaultfd_ioctl, -	.compat_ioctl	= userfaultfd_ioctl, +	.compat_ioctl	= compat_ptr_ioctl,  	.llseek		= noop_llseek,  };  |