prctl: Deprecate non PR_SET_MM_MAP operations
PATCH 1/1 prctl: Deprecate non PR_SET_MM_MAP operations
An ability to manipulate mm_struct fields was introduced in sake of CRIU in first place. Later we provide more suitable and safe operation PR_SET_MM_MAP where all fields to be modifed are passed in one structure which allows us to make more detailed verification.
Still old interface remains present for compatibility reason though CRIU itself already switched to PR_SET_MM_MAP on its own long ago.
Googling didn't reveal some other users of this operation so I think it should be safe to remove this interface.
--- kernel/sys.c | 146 ----------------------------------------------------------- 1 file changed, 2 insertions(+), 144 deletions(-)
kernel/sys.c +2 -144
@@ -2001,44 +2001,9 @@ static int prctl_set_mm_map(int opt, con }#endif /* CONFIG_CHECKPOINT_RESTORE */ -static int prctl_set_auxv (struct mm_struct *mm,unsigned long addr, -unsigned long len) -{ -/* -* This doesn't move the auxiliary vector itself since it's pinned to -* mm_struct, but it permits filling the vector with new values. It's -* up to the caller to provide sane values here, otherwise userspace -* tools which use this vector might be unhappy. -*/ -unsigned long user_auxv[AT_VECTOR_SIZE ]; - -if (len >sizeof (user_auxv)) -return -EINVAL ; - -if (copy_from_user (user_auxv, (const void __user *)addr, len)) -return -EFAULT ; - -/* Make sure the last entry is always AT_NULL */ - user_auxv[AT_VECTOR_SIZE -2 ] =0 ; - user_auxv[AT_VECTOR_SIZE -1 ] =0 ; - -BUILD_BUG_ON (sizeof (user_auxv) !=sizeof (mm->saved_auxv)); - -task_lock (current); -memcpy (mm->saved_auxv, user_auxv, len); -task_unlock (current); - -return 0 ; -} -static int prctl_set_mm (int opt,unsigned long addr,unsigned long arg4,unsigned long arg5) { -struct mm_struct *mm = current->mm; -struct prctl_mm_map prctl_map; -struct vm_area_struct *vma; -int error; -if (arg5 || (arg4 && (opt !=PR_SET_MM_AUXV && opt !=PR_SET_MM_MAP && opt !=PR_SET_MM_MAP_SIZE )))
@@ -2049,115 +2014,8 @@ static int prctl_set_mm(int opt, unsignereturn prctl_set_mm_map (opt, (const void __user *)addr, arg4);#endif -if (!capable (CAP_SYS_RESOURCE )) -return -EPERM ; - -if (opt ==PR_SET_MM_EXE_FILE ) -return prctl_set_mm_exe_file (mm, (unsigned int )addr); - -if (opt ==PR_SET_MM_AUXV ) -return prctl_set_auxv (mm, addr, arg4); - -if (addr >=TASK_SIZE || addr < mmap_min_addr) -return -EINVAL ; - - error = -EINVAL ; - -down_write (&mm->mmap_sem); - vma =find_vma (mm, addr); - - prctl_map.start_code = mm->start_code; - prctl_map.end_code = mm->end_code; - prctl_map.start_data = mm->start_data; - prctl_map.end_data = mm->end_data; - prctl_map.start_brk = mm->start_brk; - prctl_map.brk = mm->brk; - prctl_map.start_stack = mm->start_stack; - prctl_map.arg_start = mm->arg_start; - prctl_map.arg_end = mm->arg_end; - prctl_map.env_start = mm->env_start; - prctl_map.env_end = mm->env_end; - prctl_map.auxv =NULL ; - prctl_map.auxv_size =0 ; - prctl_map.exe_fd =-1 ; - -switch (opt) { -case PR_SET_MM_START_CODE : - prctl_map.start_code = addr; -break ; -case PR_SET_MM_END_CODE : - prctl_map.end_code = addr; -break ; -case PR_SET_MM_START_DATA : - prctl_map.start_data = addr; -break ; -case PR_SET_MM_END_DATA : - prctl_map.end_data = addr; -break ; -case PR_SET_MM_START_STACK : - prctl_map.start_stack = addr; -break ; -case PR_SET_MM_START_BRK : - prctl_map.start_brk = addr; -break ; -case PR_SET_MM_BRK : - prctl_map.brk = addr; -break ; -case PR_SET_MM_ARG_START : - prctl_map.arg_start = addr; -break ; -case PR_SET_MM_ARG_END : - prctl_map.arg_end = addr; -break ; -case PR_SET_MM_ENV_START : - prctl_map.env_start = addr; -break ; -case PR_SET_MM_ENV_END : - prctl_map.env_end = addr; -break ; -default : - goto out; - } - - error =validate_prctl_map (&prctl_map); -if (error) - goto out; - -switch (opt) { -/* -* If command line arguments and environment -* are placed somewhere else on stack, we can -* set them up here, ARG_START/END to setup -* command line argumets and ENV_START/END -* for environment. -*/ -case PR_SET_MM_START_STACK : -case PR_SET_MM_ARG_START : -case PR_SET_MM_ARG_END : -case PR_SET_MM_ENV_START : -case PR_SET_MM_ENV_END : -if (!vma) { - error = -EFAULT ; - goto out; - } - } - - 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; - - error =0 ; -out: -up_write (&mm->mmap_sem); -return error; +pr_warn_once ("Non PR_SET_MM_MAP operations are deprecated\n" ); +return -EINVAL ; }#ifdef CONFIG_CHECKPOINT_RESTORE
Hi,
kernel/sys.c static int prctl_set_mm(int opt, unsigne · line 2019
Quoted 12 lines · Cyrill Gorcunov
--- kernel/sys.c | 146 ----------------------------------------------------------- 1 file changed, 2 insertions(+), 144 deletions(-)Index:
linux-ml.git/kernel/sys.c
===================================================================kernel/sys.c +2
-0+pr_warn_once ("Non PR_SET_MM_MAP operations are deprecated\n" ); +return -EINVAL ; }
I'm not against removing such functionality, but I think that it's more than "deprecated." It's gone.
Signature · 1 line
~Randy
Quoted 7 lines · Randy Dunlap
kernel/sys.c static int prctl_set_mm(int opt, unsigne · line 2019
Quoted 4 lines
kernel/sys.c +2
-0+pr_warn_once ("Non PR_SET_MM_MAP operations are deprecated\n" ); +return -EINVAL ; }I'm not against removing such functionality, but I think that it's more than "deprecated." It's gone.
At first this was plain warning without code removal but I've been advised that dropping it completely may be a better idea which I agree https://lkml.org/lkml/2018/4/4/31 Or you mean the warning message itsef? We aready have similars, for example in kernel/auditfilter.c
printk(KERN_ERR "AUDIT_POSSIBLE is deprecated\n");
Quoted 9 lines · Cyrill Gorcunov
Quoted 7 lines · Randy Dunlap
kernel/sys.c static int prctl_set_mm(int opt, unsigne · line 2019
Quoted 4 lines
kernel/sys.c +2
-0+pr_warn_once ("Non PR_SET_MM_MAP operations are deprecated\n" ); +return -EINVAL ; }I'm not against removing such functionality, but I think that it's more than "deprecated." It's gone.
Quoted 5 lines
At first this was plain warning without code removal but I've been advised that dropping it completely may be a better idea which I agree https://lkml.org/lkml/2018/4/4/31 Or you mean the warning message itsef? We aready have similars, for example in
kernel/auditfilter.c
The traditional way (eons ago) to deprecate something was to add a printk() and then delete the feature a few years later. Still, I have no objection to dropping that prctl.
Sorry if I wasn't clear. I was objecting to the "language", i.e., to the word "deprecated." Deprecated means frowned on, advised against, etc. It does not mean "deleted."
Quoted 1 line
printk(KERN_ERR "AUDIT_POSSIBLE is deprecated\n");
Yeah, that one's wrong also. :)
Signature · 1 line
~Randy
Quoted 7 lines · Randy Dunlap
Quoted 6 lines
At first this was plain warning without code removal but I've been advised that dropping it completely may be a better idea which I agree https://lkml.org/lkml/2018/4/4/31 Or you mean the warning message itsef? We aready have similars, for example in
kernel/auditfilter.c
Quoted 7 lines
The traditional way (eons ago) to deprecate something was to add a
printk()and then delete the feature a few years later. Still, I have no objection to dropping that prctl.Sorry if I wasn't clear. I was objecting to the "language", i.e., to the word "deprecated." Deprecated means frowned on, advised against, etc. It does not mean "deleted."
True. I remember this rule of deprecation. But when I dropped the code I though which message to put here (or should I put it at all) and since "deprecated" was the first word came into mind I decided to grep sources, the result you see by its own :)
Quoted 4 lines
Quoted 2 lines
printk(KERN_ERR "AUDIT_POSSIBLE is deprecated\n");Yeah, that one's wrong also. :)
So, maybe just get rid of any warning message at all?
Quoted 22 lines · Cyrill Gorcunov
Quoted 7 lines · Randy Dunlap
Quoted 6 lines
At first this was plain warning without code removal but I've been advised that dropping it completely may be a better idea which I agree https://lkml.org/lkml/2018/4/4/31 Or you mean the warning message itsef? We aready have similars, for example in
kernel/auditfilter.cQuoted 7 lines
The traditional way (eons ago) to deprecate something was to add a
printk()and then delete the feature a few years later. Still, I have no objection to dropping that prctl.Sorry if I wasn't clear. I was objecting to the "language", i.e., to the word "deprecated." Deprecated means frowned on, advised against, etc. It does not mean "deleted."
True. I remember this rule of deprecation. But when I dropped the code I though which message to put here (or should I put it at all) and since "deprecated" was the first word came into mind I decided to grep sources, the result you see by its own :)
Quoted 1 line
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
printk(KERN_ERR "AUDIT_POSSIBLE is deprecated\n");Yeah, that one's wrong also. :)
So, maybe just get rid of any warning message at all?
That would be OK since -EINVAL or something similar is being returned.
Signature · 1 line
~Randy
Quoted 4 lines · Randy Dunlap
Quoted 2 lines
So, maybe just get rid of any warning message at all?
That would be OK since
-EINVALor something similar is being returned.
Thanks for feedback! Will do tomorrow and send it out.
Quoted 1 line · Cyrill Gorcunov
On Wed, Apr 04, 2018 at 01:53:08PM -0700, Randy Dunlap wrote:
[...]
Quoted 3 lines
Quoted 1 line
Yeah, that one's wrong also. :)
So, maybe just get rid of any warning message at all?
or simply do
pr_warn("PR_SET_MM_MAP has been removed. Use <ALTERNATIVE> instead\n");Signature · 2 lines
Michal Hocko SUSE Labs
Quoted 61 lines · Cyrill Gorcunov
An ability to manipulate
mm_structfields was introduced in sake of CRIU in first place. Later we provide more suitable and safe operationPR_SET_MM_MAPwhere all fields to be modifed are passed in one structure which allows us to make more detailed verification.Still old interface remains present for compatibility reason though CRIU itself already switched to
PR_SET_MM_MAPon its own long ago.Googling didn't reveal some other users of this operation so I think it should be safe to remove this interface.
CC Andrey Vagin <[email protected]>CC Andrew Morton <[email protected]>CC Pavel Emelyanov <[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 | 146 ----------------------------------------------------------- 1 file changed, 2 insertions(+), 144 deletions(-)Index:
linux-ml.git/kernel/sys.c
===================================================================kernel/sys.c +0
-29@@ -2001,44 +2001,9 @@ static int prctl_set_mm_map(int opt, con }#endif /* CONFIG_CHECKPOINT_RESTORE */ -static int prctl_set_auxv (struct mm_struct *mm,unsigned long addr, -unsigned long len) -{ -/* -* This doesn't move the auxiliary vector itself since it's pinned to -* mm_struct, but it permits filling the vector with new values. It's -* up to the caller to provide sane values here, otherwise userspace -* tools which use this vector might be unhappy. -*/ -unsigned long user_auxv[AT_VECTOR_SIZE ]; - -if (len >sizeof (user_auxv)) -return -EINVAL ; - -if (copy_from_user (user_auxv, (const void __user *)addr, len)) -return -EFAULT ; - -/* Make sure the last entry is always AT_NULL */ - user_auxv[AT_VECTOR_SIZE -2 ] =0 ; - user_auxv[AT_VECTOR_SIZE -1 ] =0 ; - -BUILD_BUG_ON (sizeof (user_auxv) !=sizeof (mm->saved_auxv)); - -task_lock (current); -memcpy (mm->saved_auxv, user_auxv, len); -task_unlock (current); - -return 0 ; -}
kernel/sys.c static int prctl_set_mm_map(int opt, con · line 2007
Quoted 10 lines
kernel/sys.c +0
-6-static int prctl_set_mm (int opt,unsigned long addr,unsigned long arg4,unsigned long arg5) { -struct mm_struct *mm = current->mm; -struct prctl_mm_map prctl_map; -struct vm_area_struct *vma; -int error; - if (arg5 || (arg4 && (opt != PR_SET_MM_AUXV &&
This PR_SET_MM_AUXV should be removed too? There is not callsite to prctl_set_auxv() anymore.
Thanks,
Yang
Quoted 120 lines
kernel/sys.c +2
-109opt !=PR_SET_MM_MAP && opt != PR_SET_MM_MAP_SIZE)))@@ -2049,115 +2014,8 @@ static int prctl_set_mm(int opt, unsignereturn prctl_set_mm_map (opt, (const void __user *)addr, arg4);#endif -if (!capable (CAP_SYS_RESOURCE )) -return -EPERM ; - -if (opt ==PR_SET_MM_EXE_FILE ) -return prctl_set_mm_exe_file (mm, (unsigned int )addr); - -if (opt ==PR_SET_MM_AUXV ) -return prctl_set_auxv (mm, addr, arg4); - -if (addr >=TASK_SIZE || addr < mmap_min_addr) -return -EINVAL ; - - error = -EINVAL ; - -down_write (&mm->mmap_sem); - vma =find_vma (mm, addr); - - prctl_map.start_code = mm->start_code; - prctl_map.end_code = mm->end_code; - prctl_map.start_data = mm->start_data; - prctl_map.end_data = mm->end_data; - prctl_map.start_brk = mm->start_brk; - prctl_map.brk = mm->brk; - prctl_map.start_stack = mm->start_stack; - prctl_map.arg_start = mm->arg_start; - prctl_map.arg_end = mm->arg_end; - prctl_map.env_start = mm->env_start; - prctl_map.env_end = mm->env_end; - prctl_map.auxv =NULL ; - prctl_map.auxv_size =0 ; - prctl_map.exe_fd =-1 ; - -switch (opt) { -case PR_SET_MM_START_CODE : - prctl_map.start_code = addr; -break ; -case PR_SET_MM_END_CODE : - prctl_map.end_code = addr; -break ; -case PR_SET_MM_START_DATA : - prctl_map.start_data = addr; -break ; -case PR_SET_MM_END_DATA : - prctl_map.end_data = addr; -break ; -case PR_SET_MM_START_STACK : - prctl_map.start_stack = addr; -break ; -case PR_SET_MM_START_BRK : - prctl_map.start_brk = addr; -break ; -case PR_SET_MM_BRK : - prctl_map.brk = addr; -break ; -case PR_SET_MM_ARG_START : - prctl_map.arg_start = addr; -break ; -case PR_SET_MM_ARG_END : - prctl_map.arg_end = addr; -break ; -case PR_SET_MM_ENV_START : - prctl_map.env_start = addr; -break ; -case PR_SET_MM_ENV_END : - prctl_map.env_end = addr; -break ; -default : - goto out; - } - - error =validate_prctl_map (&prctl_map); -if (error) - goto out; - -switch (opt) { -/* -* If command line arguments and environment -* are placed somewhere else on stack, we can -* set them up here, ARG_START/END to setup -* command line argumets and ENV_START/END -* for environment. -*/ -case PR_SET_MM_START_STACK : -case PR_SET_MM_ARG_START : -case PR_SET_MM_ARG_END : -case PR_SET_MM_ENV_START : -case PR_SET_MM_ENV_END : -if (!vma) { - error = -EFAULT ; - goto out; - } - } - - 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; - - error =0 ; -out: -up_write (&mm->mmap_sem); -return error; +pr_warn_once ("Non PR_SET_MM_MAP operations are deprecated\n" ); +return -EINVAL ; }#ifdef CONFIG_CHECKPOINT_RESTORE
Quoted 7 lines · Yang Shi
Quoted 6 lines · Cyrill Gorcunov
An ability to manipulate
mm_structfields was introduced in sake of CRIU in first place. Later we provide more suitable and safe operationPR_SET_MM_MAPwhere all fields to be modifed are passed in one structure which allows us to make more detailed verification.
Quoted 5 lines
Quoted 2 lines
-
if (arg5 || (arg4 && (opt !=PR_SET_MM_AUXV&&This
PR_SET_MM_AUXVshould be removed too? There is not callsite toprctl_set_auxv()anymore.
Yeah, good point. Will update.