linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Waiman Long <longman@redhat.com>
To: Ingo Molnar <mingo@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Juri Lelli <juri.lelli@redhat.com>,
	Vincent Guittot <vincent.guittot@linaro.org>,
	Dietmar Eggemann <dietmar.eggemann@arm.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Ben Segall <bsegall@google.com>, Mel Gorman <mgorman@suse.de>,
	Daniel Bristot de Oliveira <bristot@redhat.com>
Cc: "Phil Auld" <pauld@redhat.com>,
	"Wenjie Li" <wenjieli@qti.qualcomm.com>,
	"David Wang 王标" <wangbiao3@xiaomi.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH-tip v4] sched: Fix NULL user_cpus_ptr check in dup_user_cpus_ptr()
Date: Sun, 27 Nov 2022 20:43:27 -0500	[thread overview]
Message-ID: <92b99a5e-1588-4e08-a652-72e9c51421cf@redhat.com> (raw)
In-Reply-To: <20221125023943.1118603-1-longman@redhat.com>

On 11/24/22 21:39, Waiman Long wrote:
> In general, a non-null user_cpus_ptr will remain set until the task dies.
> A possible exception to this is the fact that do_set_cpus_allowed()
> will clear a non-null user_cpus_ptr. To allow this possible racing
> condition, we need to check for NULL user_cpus_ptr under the pi_lock
> before duping the user mask.
>
> Fixes: 851a723e45d1 ("sched: Always clear user_cpus_ptr in do_set_cpus_allowed()")
> Signed-off-by: Waiman Long <longman@redhat.com>

This is actually a pre-existing use-after-free bug since commit 
07ec77a1d4e8 ("sched: Allow task CPU affinity to be restricted on 
asymmetric systems"). So it needs to be fixed in the stable release as 
well. Will resend the patch with an additional fixes tag and updated 
commit log.

Cheers,
Longman

> ---
>   kernel/sched/core.c | 32 ++++++++++++++++++++++++++++----
>   1 file changed, 28 insertions(+), 4 deletions(-)
>
>   [v4] Minor comment update
>
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 8df51b08bb38..f2b75faaf71a 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -2624,19 +2624,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;
>   
> +	/*
> +	 * 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 (!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;
>   }
>   


  reply	other threads:[~2022-11-28  1:44 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-25  2:39 [PATCH-tip v4] sched: Fix NULL user_cpus_ptr check in dup_user_cpus_ptr() Waiman Long
2022-11-28  1:43 ` Waiman Long [this message]
2022-11-28 12:00   ` Will Deacon
2022-11-28 15:11     ` Waiman Long
2022-11-29 14:07       ` Will Deacon
2022-11-29 15:32         ` Waiman Long
2022-11-29 15:57           ` Will Deacon
2022-11-29 16:03             ` Waiman Long
2022-11-30 11:51               ` 答复: [External Mail]Re: " David Wang 王标
2022-11-30 14:07                 ` Wenjie Li (Evan)
2022-12-01 13:36               ` Will Deacon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=92b99a5e-1588-4e08-a652-72e9c51421cf@redhat.com \
    --to=longman@redhat.com \
    --cc=bristot@redhat.com \
    --cc=bsegall@google.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=juri.lelli@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mgorman@suse.de \
    --cc=mingo@redhat.com \
    --cc=pauld@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=vincent.guittot@linaro.org \
    --cc=wangbiao3@xiaomi.com \
    --cc=wenjieli@qti.qualcomm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).