prctl: prctl_set_mm -- Make prctl_set_mm_map to accept map as an argument
RFC 2/3 prctl: prctl_set_mm -- Make prctl_set_mm_map to accept map as an argument
Once we make it to accept struct prctl_mm_map as an argument it will be possible to reuse this functionallity for the rest of PR_SET_MM_x operations. Here we simply allocate struct prctl_mm_map in a caller and provide it downstairs.
CC Jonathan de Boyne Pollard <[email protected]>
CC Andrey Vagin <[email protected]>
CC Andrew Morton <[email protected]>
CC Michael Kerrisk <[email protected]>
CC Yang Shi <[email protected]>
CC Michal Hocko <[email protected]>
Signed-off-by Cyrill Gorcunov <[email protected]>
--- kernel/sys.c | 59 +++++++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 28 deletions(-)
kernel/sys.c +31 -28
@@ -1969,9 +1969,8 @@ exit_err: goto exit; } -static int prctl_set_mm_map (int opt,const void __user *addr,unsigned long data_size) +static int prctl_set_mm_map (struct prctl_mm_map *prctl_map) { -struct prctl_mm_map prctl_map = { .exe_fd = (u32)-1 , };unsigned long user_auxv[AT_VECTOR_SIZE ];struct mm_struct *mm = current->mm;int error;
@@ -1979,21 +1978,15 @@ static int prctl_set_mm_map(int opt, conBUILD_BUG_ON (sizeof (user_auxv) !=sizeof (mm->saved_auxv));BUILD_BUG_ON (sizeof (struct prctl_mm_map ) >256 ); -if (data_size !=sizeof (prctl_map)) -return -EINVAL ; - -if (copy_from_user (&prctl_map, addr,sizeof (prctl_map))) -return -EFAULT ; - - error =validate_prctl_map (&prctl_map); + error =validate_prctl_map (prctl_map);if (error)return error; -if (prctl_map.auxv_size) { +if (prctl_map->auxv_size) {memset (user_auxv,0 ,sizeof (user_auxv));if (copy_from_user (user_auxv, - (const void __user *)prctl_map.auxv, - prctl_map.auxv_size)) + (const void __user *)prctl_map->auxv, + prctl_map->auxv_size))return -EFAULT ;/* Last entry must be AT_NULL as specification requires */
@@ -2001,8 +1994,8 @@ static int prctl_set_mm_map(int opt, con user_auxv[AT_VECTOR_SIZE -1 ] =AT_NULL ; } -if (prctl_map.exe_fd != (u32)-1 ) { - error =prctl_set_mm_exe_file (mm, prctl_map.exe_fd); +if (prctl_map->exe_fd != (u32)-1 ) { + error =prctl_set_mm_exe_file (mm, prctl_map->exe_fd);if (error)return error; }
@@ -2026,17 +2019,17 @@ static int prctl_set_mm_map(int opt, con*/ spin_lock (&mm->arg_lock); - mm->start_code = prctl_map.start_code; - mm->end_code = prctl_map.end_code; - mm->start_data = prctl_map.start_data; - mm->end_data = prctl_map.end_data; - mm->start_brk = prctl_map.start_brk; - mm->brk = prctl_map.brk; - mm->start_stack = prctl_map.start_stack; - mm->arg_start = prctl_map.arg_start; - mm->arg_end = prctl_map.arg_end; - mm->env_start = prctl_map.env_start; - mm->env_end = prctl_map.env_end; + mm->start_code = prctl_map->start_code; + mm->end_code = prctl_map->end_code; + mm->start_data = prctl_map->start_data; + mm->end_data = prctl_map->end_data; + mm->start_brk = prctl_map->start_brk; + mm->brk = prctl_map->brk; + mm->start_stack = prctl_map->start_stack; + mm->arg_start = prctl_map->arg_start; + mm->arg_end = prctl_map->arg_end; + mm->env_start = prctl_map->env_start; + mm->env_end = prctl_map->env_end;spin_unlock (&mm->arg_lock);/*
@@ -2047,7 +2040,7 @@ static int prctl_set_mm_map(int opt, con* not introduce additional locks here making the kernel * more complex. */ -if (prctl_map.auxv_size) +if (prctl_map->auxv_size)memcpy (mm->saved_auxv, user_auxv,sizeof (user_auxv));up_read (&mm->mmap_sem);
@@ -2063,8 +2056,18 @@ static int prctl_set_mm(int opt, unsignereturn put_user ((unsigned int )sizeof (struct prctl_mm_map ), (unsigned int __user *)addr); -if (opt ==PR_SET_MM_MAP ) -return prctl_set_mm_map (opt, (const void __user *)addr, arg4); +if (opt ==PR_SET_MM_MAP ) { +struct prctl_mm_map prctl_map = { .exe_fd = (u32)-1 , }; + +if (arg4 !=sizeof (prctl_map)) +return -EINVAL ; + +if (copy_from_user (&prctl_map, (const void __user *)addr, +sizeof (prctl_map))) +return -EFAULT ; + +return prctl_set_mm_map (&prctl_map); + }#endif pr_warn_once ("PR_SET_MM_* has been removed. Use PR_SET_MM_MAP instead\n" );