Skip to content

Commit

Permalink
userfaultfd: untag user pointers
Browse files Browse the repository at this point in the history
This patch is a part of a series that extends kernel ABI to allow to pass
tagged user pointers (with the top byte set to something else other than
0x00) as syscall arguments.

userfaultfd code use provided user pointers for vma lookups, which can
only by done with untagged pointers.

Untag user pointers in validate_range().

Link: http://lkml.kernel.org/r/cdc59ddd7011012ca2e689bc88c3b65b1ea7e413.1563904656.git.andreyknvl@google.com
Signed-off-by: Andrey Konovalov <[email protected]>
Reviewed-by: Mike Rapoport <[email protected]>
Reviewed-by: Vincenzo Frascino <[email protected]>
Reviewed-by: Catalin Marinas <[email protected]>
Reviewed-by: Kees Cook <[email protected]>
Cc: Al Viro <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Eric Auger <[email protected]>
Cc: Felix Kuehling <[email protected]>
Cc: Jens Wiklander <[email protected]>
Cc: Khalid Aziz <[email protected]>
Cc: Mauro Carvalho Chehab <[email protected]>
Cc: Will Deacon <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
xairy authored and torvalds committed Sep 26, 2019
1 parent ed8a66b commit 7d03257
Showing 1 changed file with 12 additions and 10 deletions.
22 changes: 12 additions & 10 deletions fs/userfaultfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1272,21 +1272,23 @@ static __always_inline void wake_userfault(struct userfaultfd_ctx *ctx,
}

static __always_inline int validate_range(struct mm_struct *mm,
__u64 start, __u64 len)
__u64 *start, __u64 len)
{
__u64 task_size = mm->task_size;

if (start & ~PAGE_MASK)
*start = untagged_addr(*start);

if (*start & ~PAGE_MASK)
return -EINVAL;
if (len & ~PAGE_MASK)
return -EINVAL;
if (!len)
return -EINVAL;
if (start < mmap_min_addr)
if (*start < mmap_min_addr)
return -EINVAL;
if (start >= task_size)
if (*start >= task_size)
return -EINVAL;
if (len > task_size - start)
if (len > task_size - *start)
return -EINVAL;
return 0;
}
Expand Down Expand Up @@ -1336,7 +1338,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
goto out;
}

ret = validate_range(mm, uffdio_register.range.start,
ret = validate_range(mm, &uffdio_register.range.start,
uffdio_register.range.len);
if (ret)
goto out;
Expand Down Expand Up @@ -1525,7 +1527,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
if (copy_from_user(&uffdio_unregister, buf, sizeof(uffdio_unregister)))
goto out;

ret = validate_range(mm, uffdio_unregister.start,
ret = validate_range(mm, &uffdio_unregister.start,
uffdio_unregister.len);
if (ret)
goto out;
Expand Down Expand Up @@ -1676,7 +1678,7 @@ static int userfaultfd_wake(struct userfaultfd_ctx *ctx,
if (copy_from_user(&uffdio_wake, buf, sizeof(uffdio_wake)))
goto out;

ret = validate_range(ctx->mm, uffdio_wake.start, uffdio_wake.len);
ret = validate_range(ctx->mm, &uffdio_wake.start, uffdio_wake.len);
if (ret)
goto out;

Expand Down Expand Up @@ -1716,7 +1718,7 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx,
sizeof(uffdio_copy)-sizeof(__s64)))
goto out;

ret = validate_range(ctx->mm, uffdio_copy.dst, uffdio_copy.len);
ret = validate_range(ctx->mm, &uffdio_copy.dst, uffdio_copy.len);
if (ret)
goto out;
/*
Expand Down Expand Up @@ -1772,7 +1774,7 @@ static int userfaultfd_zeropage(struct userfaultfd_ctx *ctx,
sizeof(uffdio_zeropage)-sizeof(__s64)))
goto out;

ret = validate_range(ctx->mm, uffdio_zeropage.range.start,
ret = validate_range(ctx->mm, &uffdio_zeropage.range.start,
uffdio_zeropage.range.len);
if (ret)
goto out;
Expand Down

0 comments on commit 7d03257

Please sign in to comment.