@@ -1900,6 +1900,23 @@ static void do_pages_stat_array(struct mm_struct *mm, unsigned long nr_pages,
19001900 mmap_read_unlock (mm );
19011901}
19021902
1903+ static int get_compat_pages_array (const void __user * chunk_pages [],
1904+ const void __user * __user * pages ,
1905+ unsigned long chunk_nr )
1906+ {
1907+ compat_uptr_t __user * pages32 = (compat_uptr_t __user * )pages ;
1908+ compat_uptr_t p ;
1909+ int i ;
1910+
1911+ for (i = 0 ; i < chunk_nr ; i ++ ) {
1912+ if (get_user (p , pages32 + i ))
1913+ return - EFAULT ;
1914+ chunk_pages [i ] = compat_ptr (p );
1915+ }
1916+
1917+ return 0 ;
1918+ }
1919+
19031920/*
19041921 * Determine the nodes of a user array of pages and store it in
19051922 * a user array of status.
@@ -1919,8 +1936,15 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages,
19191936 if (chunk_nr > DO_PAGES_STAT_CHUNK_NR )
19201937 chunk_nr = DO_PAGES_STAT_CHUNK_NR ;
19211938
1922- if (copy_from_user (chunk_pages , pages , chunk_nr * sizeof (* chunk_pages )))
1923- break ;
1939+ if (in_compat_syscall ()) {
1940+ if (get_compat_pages_array (chunk_pages , pages ,
1941+ chunk_nr ))
1942+ break ;
1943+ } else {
1944+ if (copy_from_user (chunk_pages , pages ,
1945+ chunk_nr * sizeof (* chunk_pages )))
1946+ break ;
1947+ }
19241948
19251949 do_pages_stat_array (mm , chunk_nr , chunk_pages , chunk_status );
19261950
@@ -2025,23 +2049,14 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
20252049
20262050#ifdef CONFIG_COMPAT
20272051COMPAT_SYSCALL_DEFINE6 (move_pages , pid_t , pid , compat_ulong_t , nr_pages ,
2028- compat_uptr_t __user * , pages32 ,
2052+ compat_uptr_t __user * , pages ,
20292053 const int __user * , nodes ,
20302054 int __user * , status ,
20312055 int , flags )
20322056{
2033- const void __user * __user * pages ;
2034- int i ;
2035-
2036- pages = compat_alloc_user_space (nr_pages * sizeof (void * ));
2037- for (i = 0 ; i < nr_pages ; i ++ ) {
2038- compat_uptr_t p ;
2039-
2040- if (get_user (p , pages32 + i ) ||
2041- put_user (compat_ptr (p ), pages + i ))
2042- return - EFAULT ;
2043- }
2044- return kernel_move_pages (pid , nr_pages , pages , nodes , status , flags );
2057+ return kernel_move_pages (pid , nr_pages ,
2058+ (const void __user * __user * )pages ,
2059+ nodes , status , flags );
20452060}
20462061#endif /* CONFIG_COMPAT */
20472062
0 commit comments