Skip to content

Commit 7d03257

Browse files
xairytorvalds
authored andcommitted
userfaultfd: untag user pointers
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]>
1 parent ed8a66b commit 7d03257

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

fs/userfaultfd.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,21 +1272,23 @@ static __always_inline void wake_userfault(struct userfaultfd_ctx *ctx,
12721272
}
12731273

12741274
static __always_inline int validate_range(struct mm_struct *mm,
1275-
__u64 start, __u64 len)
1275+
__u64 *start, __u64 len)
12761276
{
12771277
__u64 task_size = mm->task_size;
12781278

1279-
if (start & ~PAGE_MASK)
1279+
*start = untagged_addr(*start);
1280+
1281+
if (*start & ~PAGE_MASK)
12801282
return -EINVAL;
12811283
if (len & ~PAGE_MASK)
12821284
return -EINVAL;
12831285
if (!len)
12841286
return -EINVAL;
1285-
if (start < mmap_min_addr)
1287+
if (*start < mmap_min_addr)
12861288
return -EINVAL;
1287-
if (start >= task_size)
1289+
if (*start >= task_size)
12881290
return -EINVAL;
1289-
if (len > task_size - start)
1291+
if (len > task_size - *start)
12901292
return -EINVAL;
12911293
return 0;
12921294
}
@@ -1336,7 +1338,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
13361338
goto out;
13371339
}
13381340

1339-
ret = validate_range(mm, uffdio_register.range.start,
1341+
ret = validate_range(mm, &uffdio_register.range.start,
13401342
uffdio_register.range.len);
13411343
if (ret)
13421344
goto out;
@@ -1525,7 +1527,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
15251527
if (copy_from_user(&uffdio_unregister, buf, sizeof(uffdio_unregister)))
15261528
goto out;
15271529

1528-
ret = validate_range(mm, uffdio_unregister.start,
1530+
ret = validate_range(mm, &uffdio_unregister.start,
15291531
uffdio_unregister.len);
15301532
if (ret)
15311533
goto out;
@@ -1676,7 +1678,7 @@ static int userfaultfd_wake(struct userfaultfd_ctx *ctx,
16761678
if (copy_from_user(&uffdio_wake, buf, sizeof(uffdio_wake)))
16771679
goto out;
16781680

1679-
ret = validate_range(ctx->mm, uffdio_wake.start, uffdio_wake.len);
1681+
ret = validate_range(ctx->mm, &uffdio_wake.start, uffdio_wake.len);
16801682
if (ret)
16811683
goto out;
16821684

@@ -1716,7 +1718,7 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx,
17161718
sizeof(uffdio_copy)-sizeof(__s64)))
17171719
goto out;
17181720

1719-
ret = validate_range(ctx->mm, uffdio_copy.dst, uffdio_copy.len);
1721+
ret = validate_range(ctx->mm, &uffdio_copy.dst, uffdio_copy.len);
17201722
if (ret)
17211723
goto out;
17221724
/*
@@ -1772,7 +1774,7 @@ static int userfaultfd_zeropage(struct userfaultfd_ctx *ctx,
17721774
sizeof(uffdio_zeropage)-sizeof(__s64)))
17731775
goto out;
17741776

1775-
ret = validate_range(ctx->mm, uffdio_zeropage.range.start,
1777+
ret = validate_range(ctx->mm, &uffdio_zeropage.range.start,
17761778
uffdio_zeropage.range.len);
17771779
if (ret)
17781780
goto out;

0 commit comments

Comments
 (0)