mips: sched: Fix CPUMASK_OFFSTACK memory corruption
PATCH v3 1/1 mips: sched: Fix CPUMASK_OFFSTACK memory corruption
This patch addresses a critical memory management flaw. When CONFIG_CPUMASK_OFFSTACK is enabled, cpumask_var_t is a pointer. Consequently, sizeof(new_mask) evaluates to the pointer size, causing copy_from_user() to clobber the mask pointer. Furthermore, the old logic performed copy_from_user() before allocating the mask.
Fix this by allocating new_mask first. To handle variable-sized user masks correctly, use cpumask_size() to truncate overly large user masks or pad undersized masks with zeros before copying the data directly into the allocated buffer.
---
Changes since v2 [1]:
- Dropped patch 1. This is to be addressed by the cgroup cpuset maintainer (Waiman Long)
- Dropped patch 3. Will be submitted as a separate patch (Paul Moore)
Changes since v1 [2]:
- Reordered the allocation and user-copy of new_mask in the MIPS architecture's mipsmt_sys_sched_setaffinity() to occur before the LSM hook is invoked. This ensures the security modules evaluate a fully populated mask rather than uninitialised memory, while cleanly handling error unwinding
- Updated cpuset_can_fork() to pass the destination cpuset's effective CPU mask instead of NULL
[1]: https://lore.kernel.org/lkml/[email protected]/
[2]: https://lore.kernel.org/lkml/[email protected]/
--- arch/mips/kernel/mips-mt-fpaff.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
arch/mips/kernel/mips-mt-fpaff.c +15 -13
@@ -71,11 +71,16 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,struct task_struct *p;int retval; -if (len <sizeof (new_mask)) -return -EINVAL ; - -if (copy_from_user (&new_mask, user_mask_ptr,sizeof (new_mask))) -return -EFAULT ; +if (!alloc_cpumask_var (&new_mask,GFP_KERNEL )) +return -ENOMEM ; +if (len <cpumask_size ()) +cpumask_clear (new_mask); +else if (len >cpumask_size ()) + len =cpumask_size (); +if (copy_from_user (new_mask, user_mask_ptr, len)) { + retval = -EFAULT ; + goto out_free_new_mask; + }cpus_read_lock ();rcu_read_lock ();
@@ -84,7 +89,8 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len,if (!p) {rcu_read_unlock ();cpus_read_unlock (); -return -ESRCH ; + retval = -ESRCH ; + goto out_free_new_mask; }/* Prevent p going away */
@@ -95,13 +101,9 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, retval = -ENOMEM ; goto out_put_task; } -if (!alloc_cpumask_var (&new_mask,GFP_KERNEL )) { - retval = -ENOMEM ; - goto out_free_cpus_allowed; - }if (!alloc_cpumask_var (&effective_mask,GFP_KERNEL )) { retval = -ENOMEM ; - goto out_free_new_mask; + goto out_free_cpus_allowed; }if (!check_same_owner (p) && !capable (CAP_SYS_NICE )) { retval = -EPERM ;
@@ -142,13 +144,13 @@ asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, } out_unlock:free_cpumask_var (effective_mask); -out_free_new_mask: -free_cpumask_var (new_mask); out_free_cpus_allowed:free_cpumask_var (cpus_allowed); out_put_task:put_task_struct (p);cpus_read_unlock (); +out_free_new_mask: +free_cpumask_var (new_mask);return retval; }
base-commit: 5200f5f493f79f14bbdc349e402a40dfb32f23c8
Signature · 1 line
2.51.0
Quoted 28 lines · Aaron Tomlin
This patch addresses a critical memory management flaw. When
CONFIG_CPUMASK_OFFSTACKis enabled,cpumask_var_tis a pointer. Consequently,sizeof(new_mask)evaluates to the pointer size, causingcopy_from_user()to clobber the mask pointer. Furthermore, the old logic performedcopy_from_user()before allocating the mask.Fix this by allocating
new_maskfirst. To handle variable-sized user masks correctly, usecpumask_size()to truncate overly large user masks or pad undersized masks with zeros before copying the data directly into the allocated buffer.Fixes 295cbf6d63165 ("[MIPS] Move FPU affinity code into separate file.")Signed-off-by Aaron Tomlin <[email protected]>---
Changes since v2 [1]:
- Dropped patch 1. This is to be addressed by the cgroup cpuset maintainer (Waiman Long)- Dropped patch 3. Will be submitted as a separate patch (Paul Moore)
Changes since v1 [2]:
- Reordered the allocation and user-copy ofnew_maskin the MIPS architecture'smipsmt_sys_sched_setaffinity()to occur before the LSM hook is invoked. This ensures the security modules evaluate a fully populated mask rather than uninitialised memory, while cleanly handling error unwinding
Quoted 8 lines
- Updated
cpuset_can_fork()to pass the destination cpuset's effective CPU mask instead of NULL[1]: https://lore.kernel.org/lkml/[email protected]/
[2]: https://lore.kernel.org/lkml/[email protected]/--- arch/mips/kernel/mips-mt-fpaff.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)
applied to mips-next
Thomas.
Signature · 2 lines
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a good idea. [ RFC1925, 2.3 ]
Quoted 5 lines · Thomas Bogendoerfer
Quoted 3 lines
--- arch/mips/kernel/mips-mt-fpaff.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-)applied to mips-next
Hi Thomas,
Thank you.
Kind regards,
Signature · 1 line
Aaron Tomlin