stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* FAILED: patch "[PATCH] sched/core: Fix use-after-free bug in dup_user_cpus_ptr()" failed to apply to 6.1-stable tree
@ 2023-01-14  9:53 gregkh
  2023-01-14 19:28 ` Waiman Long
  0 siblings, 1 reply; 6+ messages in thread
From: gregkh @ 2023-01-14  9:53 UTC (permalink / raw)
  To: longman, mingo, peterz, wangbiao3; +Cc: stable


The patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.

Possible dependencies:

87ca4f9efbd7 ("sched/core: Fix use-after-free bug in dup_user_cpus_ptr()")
8f9ea86fdf99 ("sched: Always preserve the user requested cpumask")
713a2e21a513 ("sched: Introduce affinity_context")

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 87ca4f9efbd7cc649ff43b87970888f2812945b8 Mon Sep 17 00:00:00 2001
From: Waiman Long <longman@redhat.com>
Date: Fri, 30 Dec 2022 23:11:19 -0500
Subject: [PATCH] sched/core: Fix use-after-free bug in dup_user_cpus_ptr()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Since commit 07ec77a1d4e8 ("sched: Allow task CPU affinity to be
restricted on asymmetric systems"), the setting and clearing of
user_cpus_ptr are done under pi_lock for arm64 architecture. However,
dup_user_cpus_ptr() accesses user_cpus_ptr without any lock
protection. Since sched_setaffinity() can be invoked from another
process, the process being modified may be undergoing fork() at
the same time.  When racing with the clearing of user_cpus_ptr in
__set_cpus_allowed_ptr_locked(), it can lead to user-after-free and
possibly double-free in arm64 kernel.

Commit 8f9ea86fdf99 ("sched: Always preserve the user requested
cpumask") fixes this problem as user_cpus_ptr, once set, will never
be cleared in a task's lifetime. However, this bug was re-introduced
in commit 851a723e45d1 ("sched: Always clear user_cpus_ptr in
do_set_cpus_allowed()") which allows the clearing of user_cpus_ptr in
do_set_cpus_allowed(). This time, it will affect all arches.

Fix this bug by always clearing the user_cpus_ptr of the newly
cloned/forked task before the copying process starts and check the
user_cpus_ptr state of the source task under pi_lock.

Note to stable, this patch won't be applicable to stable releases.
Just copy the new dup_user_cpus_ptr() function over.

Fixes: 07ec77a1d4e8 ("sched: Allow task CPU affinity to be restricted on asymmetric systems")
Fixes: 851a723e45d1 ("sched: Always clear user_cpus_ptr in do_set_cpus_allowed()")
Reported-by: David Wang 王标 <wangbiao3@xiaomi.com>
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Peter Zijlstra <peterz@infradead.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20221231041120.440785-2-longman@redhat.com

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 965d813c28ad..f9f6e5413dcf 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2612,19 +2612,43 @@ void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
 int dup_user_cpus_ptr(struct task_struct *dst, struct task_struct *src,
 		      int node)
 {
+	cpumask_t *user_mask;
 	unsigned long flags;
 
-	if (!src->user_cpus_ptr)
+	/*
+	 * Always clear dst->user_cpus_ptr first as their user_cpus_ptr's
+	 * may differ by now due to racing.
+	 */
+	dst->user_cpus_ptr = NULL;
+
+	/*
+	 * This check is racy and losing the race is a valid situation.
+	 * It is not worth the extra overhead of taking the pi_lock on
+	 * every fork/clone.
+	 */
+	if (data_race(!src->user_cpus_ptr))
 		return 0;
 
-	dst->user_cpus_ptr = kmalloc_node(cpumask_size(), GFP_KERNEL, node);
-	if (!dst->user_cpus_ptr)
+	user_mask = kmalloc_node(cpumask_size(), GFP_KERNEL, node);
+	if (!user_mask)
 		return -ENOMEM;
 
-	/* Use pi_lock to protect content of user_cpus_ptr */
+	/*
+	 * Use pi_lock to protect content of user_cpus_ptr
+	 *
+	 * Though unlikely, user_cpus_ptr can be reset to NULL by a concurrent
+	 * do_set_cpus_allowed().
+	 */
 	raw_spin_lock_irqsave(&src->pi_lock, flags);
-	cpumask_copy(dst->user_cpus_ptr, src->user_cpus_ptr);
+	if (src->user_cpus_ptr) {
+		swap(dst->user_cpus_ptr, user_mask);
+		cpumask_copy(dst->user_cpus_ptr, src->user_cpus_ptr);
+	}
 	raw_spin_unlock_irqrestore(&src->pi_lock, flags);
+
+	if (unlikely(user_mask))
+		kfree(user_mask);
+
 	return 0;
 }
 


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: FAILED: patch "[PATCH] sched/core: Fix use-after-free bug in dup_user_cpus_ptr()" failed to apply to 6.1-stable tree
  2023-01-14  9:53 FAILED: patch "[PATCH] sched/core: Fix use-after-free bug in dup_user_cpus_ptr()" failed to apply to 6.1-stable tree gregkh
@ 2023-01-14 19:28 ` Waiman Long
  2023-01-14 19:33   ` Waiman Long
  0 siblings, 1 reply; 6+ messages in thread
From: Waiman Long @ 2023-01-14 19:28 UTC (permalink / raw)
  To: gregkh, mingo, peterz, wangbiao3; +Cc: stable

On 1/14/23 04:53, gregkh@linuxfoundation.org wrote:
> The patch below does not apply to the 6.1-stable tree.
> If someone wants it applied there, or to any other stable or longterm
> tree, then please email the backport, including the original git commit
> id to <stable@vger.kernel.org>.
>
> Possible dependencies:
>
> 87ca4f9efbd7 ("sched/core: Fix use-after-free bug in dup_user_cpus_ptr()")
> 8f9ea86fdf99 ("sched: Always preserve the user requested cpumask")
> 713a2e21a513 ("sched: Introduce affinity_context")
>
> thanks,
>
> greg k-h
>
> ------------------ original commit in Linus's tree ------------------
>
>  From 87ca4f9efbd7cc649ff43b87970888f2812945b8 Mon Sep 17 00:00:00 2001
> From: Waiman Long <longman@redhat.com>
> Date: Fri, 30 Dec 2022 23:11:19 -0500
> Subject: [PATCH] sched/core: Fix use-after-free bug in dup_user_cpus_ptr()
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
>
> Since commit 07ec77a1d4e8 ("sched: Allow task CPU affinity to be
> restricted on asymmetric systems"), the setting and clearing of
> user_cpus_ptr are done under pi_lock for arm64 architecture. However,
> dup_user_cpus_ptr() accesses user_cpus_ptr without any lock
> protection. Since sched_setaffinity() can be invoked from another
> process, the process being modified may be undergoing fork() at
> the same time.  When racing with the clearing of user_cpus_ptr in
> __set_cpus_allowed_ptr_locked(), it can lead to user-after-free and
> possibly double-free in arm64 kernel.
>
> Commit 8f9ea86fdf99 ("sched: Always preserve the user requested
> cpumask") fixes this problem as user_cpus_ptr, once set, will never
> be cleared in a task's lifetime. However, this bug was re-introduced
> in commit 851a723e45d1 ("sched: Always clear user_cpus_ptr in
> do_set_cpus_allowed()") which allows the clearing of user_cpus_ptr in
> do_set_cpus_allowed(). This time, it will affect all arches.
>
> Fix this bug by always clearing the user_cpus_ptr of the newly
> cloned/forked task before the copying process starts and check the
> user_cpus_ptr state of the source task under pi_lock.
>
> Note to stable, this patch won't be applicable to stable releases.
> Just copy the new dup_user_cpus_ptr() function over.

I have a note here about what to do when backporting to stable. Just 
copy the new function over will be fine.

Cheers,
Longman

>
> Fixes: 07ec77a1d4e8 ("sched: Allow task CPU affinity to be restricted on asymmetric systems")
> Fixes: 851a723e45d1 ("sched: Always clear user_cpus_ptr in do_set_cpus_allowed()")
> Reported-by: David Wang 王标 <wangbiao3@xiaomi.com>
> Signed-off-by: Waiman Long <longman@redhat.com>
> Signed-off-by: Ingo Molnar <mingo@kernel.org>
> Reviewed-by: Peter Zijlstra <peterz@infradead.org>
> Cc: stable@vger.kernel.org
> Link: https://lore.kernel.org/r/20221231041120.440785-2-longman@redhat.com


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: FAILED: patch "[PATCH] sched/core: Fix use-after-free bug in dup_user_cpus_ptr()" failed to apply to 6.1-stable tree
  2023-01-14 19:28 ` Waiman Long
@ 2023-01-14 19:33   ` Waiman Long
  2023-01-15  2:26     ` Waiman Long
  0 siblings, 1 reply; 6+ messages in thread
From: Waiman Long @ 2023-01-14 19:33 UTC (permalink / raw)
  To: gregkh, mingo, peterz, wangbiao3; +Cc: stable

On 1/14/23 14:28, Waiman Long wrote:
> On 1/14/23 04:53, gregkh@linuxfoundation.org wrote:
>> The patch below does not apply to the 6.1-stable tree.
>> If someone wants it applied there, or to any other stable or longterm
>> tree, then please email the backport, including the original git commit
>> id to <stable@vger.kernel.org>.
>>
>> Possible dependencies:
>>
>> 87ca4f9efbd7 ("sched/core: Fix use-after-free bug in 
>> dup_user_cpus_ptr()")
>> 8f9ea86fdf99 ("sched: Always preserve the user requested cpumask")
>> 713a2e21a513 ("sched: Introduce affinity_context")
>>
>> thanks,
>>
>> greg k-h
>>
>> ------------------ original commit in Linus's tree ------------------
>>
>>  From 87ca4f9efbd7cc649ff43b87970888f2812945b8 Mon Sep 17 00:00:00 2001
>> From: Waiman Long <longman@redhat.com>
>> Date: Fri, 30 Dec 2022 23:11:19 -0500
>> Subject: [PATCH] sched/core: Fix use-after-free bug in 
>> dup_user_cpus_ptr()
>> MIME-Version: 1.0
>> Content-Type: text/plain; charset=UTF-8
>> Content-Transfer-Encoding: 8bit
>>
>> Since commit 07ec77a1d4e8 ("sched: Allow task CPU affinity to be
>> restricted on asymmetric systems"), the setting and clearing of
>> user_cpus_ptr are done under pi_lock for arm64 architecture. However,
>> dup_user_cpus_ptr() accesses user_cpus_ptr without any lock
>> protection. Since sched_setaffinity() can be invoked from another
>> process, the process being modified may be undergoing fork() at
>> the same time.  When racing with the clearing of user_cpus_ptr in
>> __set_cpus_allowed_ptr_locked(), it can lead to user-after-free and
>> possibly double-free in arm64 kernel.
>>
>> Commit 8f9ea86fdf99 ("sched: Always preserve the user requested
>> cpumask") fixes this problem as user_cpus_ptr, once set, will never
>> be cleared in a task's lifetime. However, this bug was re-introduced
>> in commit 851a723e45d1 ("sched: Always clear user_cpus_ptr in
>> do_set_cpus_allowed()") which allows the clearing of user_cpus_ptr in
>> do_set_cpus_allowed(). This time, it will affect all arches.
>>
>> Fix this bug by always clearing the user_cpus_ptr of the newly
>> cloned/forked task before the copying process starts and check the
>> user_cpus_ptr state of the source task under pi_lock.
>>
>> Note to stable, this patch won't be applicable to stable releases.
>> Just copy the new dup_user_cpus_ptr() function over.
>
> I have a note here about what to do when backporting to stable. Just 
> copy the new function over will be fine.

That will be before the application of the subsequent patch which will 
modify it in a way for suitable for stable. I can send out a separate 
stable patch for that later today.

Cheers,
Longman


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: FAILED: patch "[PATCH] sched/core: Fix use-after-free bug in dup_user_cpus_ptr()" failed to apply to 6.1-stable tree
  2023-01-14 19:33   ` Waiman Long
@ 2023-01-15  2:26     ` Waiman Long
  2023-01-15  8:01       ` Greg KH
  2023-01-15  8:55       ` Ingo Molnar
  0 siblings, 2 replies; 6+ messages in thread
From: Waiman Long @ 2023-01-15  2:26 UTC (permalink / raw)
  To: gregkh; +Cc: stable, mingo, peterz, wangbiao3

[-- Attachment #1: Type: text/plain, Size: 2835 bytes --]


On 1/14/23 14:33, Waiman Long wrote:
> On 1/14/23 14:28, Waiman Long wrote:
>> On 1/14/23 04:53, gregkh@linuxfoundation.org wrote:
>>> The patch below does not apply to the 6.1-stable tree.
>>> If someone wants it applied there, or to any other stable or longterm
>>> tree, then please email the backport, including the original git commit
>>> id to <stable@vger.kernel.org>.
>>>
>>> Possible dependencies:
>>>
>>> 87ca4f9efbd7 ("sched/core: Fix use-after-free bug in 
>>> dup_user_cpus_ptr()")
>>> 8f9ea86fdf99 ("sched: Always preserve the user requested cpumask")
>>> 713a2e21a513 ("sched: Introduce affinity_context")
>>>
>>> thanks,
>>>
>>> greg k-h
>>>
>>> ------------------ original commit in Linus's tree ------------------
>>>
>>>  From 87ca4f9efbd7cc649ff43b87970888f2812945b8 Mon Sep 17 00:00:00 2001
>>> From: Waiman Long <longman@redhat.com>
>>> Date: Fri, 30 Dec 2022 23:11:19 -0500
>>> Subject: [PATCH] sched/core: Fix use-after-free bug in 
>>> dup_user_cpus_ptr()
>>> MIME-Version: 1.0
>>> Content-Type: text/plain; charset=UTF-8
>>> Content-Transfer-Encoding: 8bit
>>>
>>> Since commit 07ec77a1d4e8 ("sched: Allow task CPU affinity to be
>>> restricted on asymmetric systems"), the setting and clearing of
>>> user_cpus_ptr are done under pi_lock for arm64 architecture. However,
>>> dup_user_cpus_ptr() accesses user_cpus_ptr without any lock
>>> protection. Since sched_setaffinity() can be invoked from another
>>> process, the process being modified may be undergoing fork() at
>>> the same time.  When racing with the clearing of user_cpus_ptr in
>>> __set_cpus_allowed_ptr_locked(), it can lead to user-after-free and
>>> possibly double-free in arm64 kernel.
>>>
>>> Commit 8f9ea86fdf99 ("sched: Always preserve the user requested
>>> cpumask") fixes this problem as user_cpus_ptr, once set, will never
>>> be cleared in a task's lifetime. However, this bug was re-introduced
>>> in commit 851a723e45d1 ("sched: Always clear user_cpus_ptr in
>>> do_set_cpus_allowed()") which allows the clearing of user_cpus_ptr in
>>> do_set_cpus_allowed(). This time, it will affect all arches.
>>>
>>> Fix this bug by always clearing the user_cpus_ptr of the newly
>>> cloned/forked task before the copying process starts and check the
>>> user_cpus_ptr state of the source task under pi_lock.
>>>
>>> Note to stable, this patch won't be applicable to stable releases.
>>> Just copy the new dup_user_cpus_ptr() function over.
>>
>> I have a note here about what to do when backporting to stable. Just 
>> copy the new function over will be fine.
>
> That will be before the application of the subsequent patch which will 
> modify it in a way for suitable for stable. I can send out a separate 
> stable patch for that later today.

The attached patch will apply to linux-6.1.y as well as linux-5.15.y.

Cheers,
Longman

[-- Attachment #2: 0001-sched-core-Fix-use-after-free-bug-in-dup_user_cpus_p.patch --]
[-- Type: text/x-patch, Size: 3755 bytes --]

From 36feebbfa2b18a02102f136fdfaa53a7f25830d8 Mon Sep 17 00:00:00 2001
From: Waiman Long <longman@redhat.com>
Date: Sat, 14 Jan 2023 20:05:34 -0500
Subject: [PATCH] sched/core: Fix use-after-free bug in dup_user_cpus_ptr()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

commit 87ca4f9efbd7cc649ff43b87970888f2812945b8 upstream.

Since commit 07ec77a1d4e8 ("sched: Allow task CPU affinity to be
restricted on asymmetric systems"), the setting and clearing of
user_cpus_ptr are done under pi_lock for arm64 architecture. However,
dup_user_cpus_ptr() accesses user_cpus_ptr without any lock
protection. Since sched_setaffinity() can be invoked from another
process, the process being modified may be undergoing fork() at
the same time.  When racing with the clearing of user_cpus_ptr in
__set_cpus_allowed_ptr_locked(), it can lead to user-after-free and
possibly double-free in arm64 kernel.

Commit 8f9ea86fdf99 ("sched: Always preserve the user requested
cpumask") fixes this problem as user_cpus_ptr, once set, will never
be cleared in a task's lifetime. However, this bug was re-introduced
in commit 851a723e45d1 ("sched: Always clear user_cpus_ptr in
do_set_cpus_allowed()") which allows the clearing of user_cpus_ptr in
do_set_cpus_allowed(). This time, it will affect all arches.

Fix this bug by always clearing the user_cpus_ptr of the newly
cloned/forked task before the copying process starts and check the
user_cpus_ptr state of the source task under pi_lock.

Note to stable, this patch won't be applicable to stable releases.
Just copy the new dup_user_cpus_ptr() function over.

Fixes: 07ec77a1d4e8 ("sched: Allow task CPU affinity to be restricted on asymmetric systems")
Fixes: 851a723e45d1 ("sched: Always clear user_cpus_ptr in do_set_cpus_allowed()")
Reported-by: David Wang 王标 <wangbiao3@xiaomi.com>
Signed-off-by: Waiman Long <longman@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Peter Zijlstra <peterz@infradead.org>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20221231041120.440785-2-longman@redhat.com
---
 kernel/sched/core.c | 37 +++++++++++++++++++++++++++++++++----
 1 file changed, 33 insertions(+), 4 deletions(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 535af9fbea7b..981e41cc4121 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2587,14 +2587,43 @@ void do_set_cpus_allowed(struct task_struct *p, const struct cpumask *new_mask)
 int dup_user_cpus_ptr(struct task_struct *dst, struct task_struct *src,
 		      int node)
 {
-	if (!src->user_cpus_ptr)
+	cpumask_t *user_mask;
+	unsigned long flags;
+
+	/*
+	 * Always clear dst->user_cpus_ptr first as their user_cpus_ptr's
+	 * may differ by now due to racing.
+	 */
+	dst->user_cpus_ptr = NULL;
+
+	/*
+	 * This check is racy and losing the race is a valid situation.
+	 * It is not worth the extra overhead of taking the pi_lock on
+	 * every fork/clone.
+	 */
+	if (data_race(!src->user_cpus_ptr))
 		return 0;
 
-	dst->user_cpus_ptr = kmalloc_node(cpumask_size(), GFP_KERNEL, node);
-	if (!dst->user_cpus_ptr)
+	user_mask = kmalloc_node(cpumask_size(), GFP_KERNEL, node);
+	if (!user_mask)
 		return -ENOMEM;
 
-	cpumask_copy(dst->user_cpus_ptr, src->user_cpus_ptr);
+	/*
+	 * Use pi_lock to protect content of user_cpus_ptr
+	 *
+	 * Though unlikely, user_cpus_ptr can be reset to NULL by a concurrent
+	 * do_set_cpus_allowed().
+	 */
+	raw_spin_lock_irqsave(&src->pi_lock, flags);
+	if (src->user_cpus_ptr) {
+		swap(dst->user_cpus_ptr, user_mask);
+		cpumask_copy(dst->user_cpus_ptr, src->user_cpus_ptr);
+	}
+	raw_spin_unlock_irqrestore(&src->pi_lock, flags);
+
+	if (unlikely(user_mask))
+		kfree(user_mask);
+
 	return 0;
 }
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: FAILED: patch "[PATCH] sched/core: Fix use-after-free bug in dup_user_cpus_ptr()" failed to apply to 6.1-stable tree
  2023-01-15  2:26     ` Waiman Long
@ 2023-01-15  8:01       ` Greg KH
  2023-01-15  8:55       ` Ingo Molnar
  1 sibling, 0 replies; 6+ messages in thread
From: Greg KH @ 2023-01-15  8:01 UTC (permalink / raw)
  To: Waiman Long; +Cc: stable, mingo, peterz, wangbiao3

On Sat, Jan 14, 2023 at 09:26:54PM -0500, Waiman Long wrote:
> 
> On 1/14/23 14:33, Waiman Long wrote:
> > On 1/14/23 14:28, Waiman Long wrote:
> > > On 1/14/23 04:53, gregkh@linuxfoundation.org wrote:
> > > > The patch below does not apply to the 6.1-stable tree.
> > > > If someone wants it applied there, or to any other stable or longterm
> > > > tree, then please email the backport, including the original git commit
> > > > id to <stable@vger.kernel.org>.
> > > > 
> > > > Possible dependencies:
> > > > 
> > > > 87ca4f9efbd7 ("sched/core: Fix use-after-free bug in
> > > > dup_user_cpus_ptr()")
> > > > 8f9ea86fdf99 ("sched: Always preserve the user requested cpumask")
> > > > 713a2e21a513 ("sched: Introduce affinity_context")
> > > > 
> > > > thanks,
> > > > 
> > > > greg k-h
> > > > 
> > > > ------------------ original commit in Linus's tree ------------------
> > > > 
> > > >  From 87ca4f9efbd7cc649ff43b87970888f2812945b8 Mon Sep 17 00:00:00 2001
> > > > From: Waiman Long <longman@redhat.com>
> > > > Date: Fri, 30 Dec 2022 23:11:19 -0500
> > > > Subject: [PATCH] sched/core: Fix use-after-free bug in
> > > > dup_user_cpus_ptr()
> > > > MIME-Version: 1.0
> > > > Content-Type: text/plain; charset=UTF-8
> > > > Content-Transfer-Encoding: 8bit
> > > > 
> > > > Since commit 07ec77a1d4e8 ("sched: Allow task CPU affinity to be
> > > > restricted on asymmetric systems"), the setting and clearing of
> > > > user_cpus_ptr are done under pi_lock for arm64 architecture. However,
> > > > dup_user_cpus_ptr() accesses user_cpus_ptr without any lock
> > > > protection. Since sched_setaffinity() can be invoked from another
> > > > process, the process being modified may be undergoing fork() at
> > > > the same time.  When racing with the clearing of user_cpus_ptr in
> > > > __set_cpus_allowed_ptr_locked(), it can lead to user-after-free and
> > > > possibly double-free in arm64 kernel.
> > > > 
> > > > Commit 8f9ea86fdf99 ("sched: Always preserve the user requested
> > > > cpumask") fixes this problem as user_cpus_ptr, once set, will never
> > > > be cleared in a task's lifetime. However, this bug was re-introduced
> > > > in commit 851a723e45d1 ("sched: Always clear user_cpus_ptr in
> > > > do_set_cpus_allowed()") which allows the clearing of user_cpus_ptr in
> > > > do_set_cpus_allowed(). This time, it will affect all arches.
> > > > 
> > > > Fix this bug by always clearing the user_cpus_ptr of the newly
> > > > cloned/forked task before the copying process starts and check the
> > > > user_cpus_ptr state of the source task under pi_lock.
> > > > 
> > > > Note to stable, this patch won't be applicable to stable releases.
> > > > Just copy the new dup_user_cpus_ptr() function over.
> > > 
> > > I have a note here about what to do when backporting to stable. Just
> > > copy the new function over will be fine.
> > 
> > That will be before the application of the subsequent patch which will
> > modify it in a way for suitable for stable. I can send out a separate
> > stable patch for that later today.
> 
> The attached patch will apply to linux-6.1.y as well as linux-5.15.y.

Thanks for the backport, now queued up.

greg k-h

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: FAILED: patch "[PATCH] sched/core: Fix use-after-free bug in dup_user_cpus_ptr()" failed to apply to 6.1-stable tree
  2023-01-15  2:26     ` Waiman Long
  2023-01-15  8:01       ` Greg KH
@ 2023-01-15  8:55       ` Ingo Molnar
  1 sibling, 0 replies; 6+ messages in thread
From: Ingo Molnar @ 2023-01-15  8:55 UTC (permalink / raw)
  To: Waiman Long; +Cc: gregkh, stable, peterz, wangbiao3


* Waiman Long <longman@redhat.com> wrote:

> 
> On 1/14/23 14:33, Waiman Long wrote:
> > On 1/14/23 14:28, Waiman Long wrote:
> > > On 1/14/23 04:53, gregkh@linuxfoundation.org wrote:
> > > > The patch below does not apply to the 6.1-stable tree.
> > > > If someone wants it applied there, or to any other stable or longterm
> > > > tree, then please email the backport, including the original git commit
> > > > id to <stable@vger.kernel.org>.
> > > > 
> > > > Possible dependencies:
> > > > 
> > > > 87ca4f9efbd7 ("sched/core: Fix use-after-free bug in
> > > > dup_user_cpus_ptr()")
> > > > 8f9ea86fdf99 ("sched: Always preserve the user requested cpumask")
> > > > 713a2e21a513 ("sched: Introduce affinity_context")
> > > > 
> > > > thanks,
> > > > 
> > > > greg k-h
> > > > 
> > > > ------------------ original commit in Linus's tree ------------------
> > > > 
> > > >  From 87ca4f9efbd7cc649ff43b87970888f2812945b8 Mon Sep 17 00:00:00 2001
> > > > From: Waiman Long <longman@redhat.com>
> > > > Date: Fri, 30 Dec 2022 23:11:19 -0500
> > > > Subject: [PATCH] sched/core: Fix use-after-free bug in
> > > > dup_user_cpus_ptr()
> > > > MIME-Version: 1.0
> > > > Content-Type: text/plain; charset=UTF-8
> > > > Content-Transfer-Encoding: 8bit
> > > > 
> > > > Since commit 07ec77a1d4e8 ("sched: Allow task CPU affinity to be
> > > > restricted on asymmetric systems"), the setting and clearing of
> > > > user_cpus_ptr are done under pi_lock for arm64 architecture. However,
> > > > dup_user_cpus_ptr() accesses user_cpus_ptr without any lock
> > > > protection. Since sched_setaffinity() can be invoked from another
> > > > process, the process being modified may be undergoing fork() at
> > > > the same time.  When racing with the clearing of user_cpus_ptr in
> > > > __set_cpus_allowed_ptr_locked(), it can lead to user-after-free and
> > > > possibly double-free in arm64 kernel.
> > > > 
> > > > Commit 8f9ea86fdf99 ("sched: Always preserve the user requested
> > > > cpumask") fixes this problem as user_cpus_ptr, once set, will never
> > > > be cleared in a task's lifetime. However, this bug was re-introduced
> > > > in commit 851a723e45d1 ("sched: Always clear user_cpus_ptr in
> > > > do_set_cpus_allowed()") which allows the clearing of user_cpus_ptr in
> > > > do_set_cpus_allowed(). This time, it will affect all arches.
> > > > 
> > > > Fix this bug by always clearing the user_cpus_ptr of the newly
> > > > cloned/forked task before the copying process starts and check the
> > > > user_cpus_ptr state of the source task under pi_lock.
> > > > 
> > > > Note to stable, this patch won't be applicable to stable releases.
> > > > Just copy the new dup_user_cpus_ptr() function over.
> > > 
> > > I have a note here about what to do when backporting to stable. Just
> > > copy the new function over will be fine.
> > 
> > That will be before the application of the subsequent patch which will
> > modify it in a way for suitable for stable. I can send out a separate
> > stable patch for that later today.
> 
> The attached patch will apply to linux-6.1.y as well as linux-5.15.y.

Thanks!

Acked-by: Ingo Molnar <mingo@kernel.org>


	Ingo

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-01-15  8:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-14  9:53 FAILED: patch "[PATCH] sched/core: Fix use-after-free bug in dup_user_cpus_ptr()" failed to apply to 6.1-stable tree gregkh
2023-01-14 19:28 ` Waiman Long
2023-01-14 19:33   ` Waiman Long
2023-01-15  2:26     ` Waiman Long
2023-01-15  8:01       ` Greg KH
2023-01-15  8:55       ` Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).