@@ -2399,14 +2399,15 @@ static void do_pages_stat_array(struct mm_struct *mm, unsigned long nr_pages,
23992399
24002400static int get_compat_pages_array (const void __user * chunk_pages [],
24012401 const void __user * __user * pages ,
2402+ unsigned long chunk_offset ,
24022403 unsigned long chunk_nr )
24032404{
24042405 compat_uptr_t __user * pages32 = (compat_uptr_t __user * )pages ;
24052406 compat_uptr_t p ;
24062407 int i ;
24072408
24082409 for (i = 0 ; i < chunk_nr ; i ++ ) {
2409- if (get_user (p , pages32 + i ))
2410+ if (get_user (p , pages32 + chunk_offset + i ))
24102411 return - EFAULT ;
24112412 chunk_pages [i ] = compat_ptr (p );
24122413 }
@@ -2425,27 +2426,28 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages,
24252426#define DO_PAGES_STAT_CHUNK_NR 16UL
24262427 const void __user * chunk_pages [DO_PAGES_STAT_CHUNK_NR ];
24272428 int chunk_status [DO_PAGES_STAT_CHUNK_NR ];
2429+ unsigned long chunk_offset = 0 ;
24282430
24292431 while (nr_pages ) {
24302432 unsigned long chunk_nr = min (nr_pages , DO_PAGES_STAT_CHUNK_NR );
24312433
24322434 if (in_compat_syscall ()) {
24332435 if (get_compat_pages_array (chunk_pages , pages ,
2434- chunk_nr ))
2436+ chunk_offset , chunk_nr ))
24352437 break ;
24362438 } else {
2437- if (copy_from_user (chunk_pages , pages ,
2439+ if (copy_from_user (chunk_pages , pages + chunk_offset ,
24382440 chunk_nr * sizeof (* chunk_pages )))
24392441 break ;
24402442 }
24412443
24422444 do_pages_stat_array (mm , chunk_nr , chunk_pages , chunk_status );
24432445
2444- if (copy_to_user (status , chunk_status , chunk_nr * sizeof (* status )))
2446+ if (copy_to_user (status + chunk_offset , chunk_status ,
2447+ chunk_nr * sizeof (* status )))
24452448 break ;
24462449
2447- pages += chunk_nr ;
2448- status += chunk_nr ;
2450+ chunk_offset += chunk_nr ;
24492451 nr_pages -= chunk_nr ;
24502452 }
24512453 return nr_pages ? - EFAULT : 0 ;
0 commit comments