@@ -1289,13 +1289,11 @@ static __always_inline void wake_userfault(struct userfaultfd_ctx *ctx,
12891289 __wake_userfault (ctx , range );
12901290}
12911291
1292- static __always_inline int validate_range ( struct mm_struct * mm ,
1293- __u64 start , __u64 len )
1292+ static __always_inline int validate_unaligned_range (
1293+ struct mm_struct * mm , __u64 start , __u64 len )
12941294{
12951295 __u64 task_size = mm -> task_size ;
12961296
1297- if (start & ~PAGE_MASK )
1298- return - EINVAL ;
12991297 if (len & ~PAGE_MASK )
13001298 return - EINVAL ;
13011299 if (!len )
@@ -1306,9 +1304,20 @@ static __always_inline int validate_range(struct mm_struct *mm,
13061304 return - EINVAL ;
13071305 if (len > task_size - start )
13081306 return - EINVAL ;
1307+ if (start + len <= start )
1308+ return - EINVAL ;
13091309 return 0 ;
13101310}
13111311
1312+ static __always_inline int validate_range (struct mm_struct * mm ,
1313+ __u64 start , __u64 len )
1314+ {
1315+ if (start & ~PAGE_MASK )
1316+ return - EINVAL ;
1317+
1318+ return validate_unaligned_range (mm , start , len );
1319+ }
1320+
13121321static int userfaultfd_register (struct userfaultfd_ctx * ctx ,
13131322 unsigned long arg )
13141323{
@@ -1757,17 +1766,15 @@ static int userfaultfd_copy(struct userfaultfd_ctx *ctx,
17571766 sizeof (uffdio_copy )- sizeof (__s64 )))
17581767 goto out ;
17591768
1769+ ret = validate_unaligned_range (ctx -> mm , uffdio_copy .src ,
1770+ uffdio_copy .len );
1771+ if (ret )
1772+ goto out ;
17601773 ret = validate_range (ctx -> mm , uffdio_copy .dst , uffdio_copy .len );
17611774 if (ret )
17621775 goto out ;
1763- /*
1764- * double check for wraparound just in case. copy_from_user()
1765- * will later check uffdio_copy.src + uffdio_copy.len to fit
1766- * in the userland range.
1767- */
1776+
17681777 ret = - EINVAL ;
1769- if (uffdio_copy .src + uffdio_copy .len <= uffdio_copy .src )
1770- goto out ;
17711778 if (uffdio_copy .mode & ~(UFFDIO_COPY_MODE_DONTWAKE |UFFDIO_COPY_MODE_WP ))
17721779 goto out ;
17731780 if (uffdio_copy .mode & UFFDIO_COPY_MODE_WP )
@@ -1927,11 +1934,6 @@ static int userfaultfd_continue(struct userfaultfd_ctx *ctx, unsigned long arg)
19271934 goto out ;
19281935
19291936 ret = - EINVAL ;
1930- /* double check for wraparound just in case. */
1931- if (uffdio_continue .range .start + uffdio_continue .range .len <=
1932- uffdio_continue .range .start ) {
1933- goto out ;
1934- }
19351937 if (uffdio_continue .mode & ~(UFFDIO_CONTINUE_MODE_DONTWAKE |
19361938 UFFDIO_CONTINUE_MODE_WP ))
19371939 goto out ;
0 commit comments