All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
Cc: linux-trace-kernel@vger.kernel.org,
	Pengfei Xu <pengfei.xu@intel.com>,
	linux-kernel@vger.kernel.org, peterz@infradead.org,
	heng.su@intel.com, "Naveen N . Rao" <naveen.n.rao@linux.ibm.com>
Subject: Re: [PATCH] kprobes: Fix to handle forcibly unoptimized kprobes on freeing_list
Date: Mon, 23 Jan 2023 13:39:31 -0500	[thread overview]
Message-ID: <20230123133931.6f6a711d@gandalf.local.home> (raw)
In-Reply-To: <167448024501.3253718.13037333683110512967.stgit@devnote3>

On Mon, 23 Jan 2023 22:24:05 +0900
"Masami Hiramatsu (Google)" <mhiramat@kernel.org> wrote:

> From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> 
> Sinec forcibly unoptimized kprobes will be put on the freeing_list directly

"Since"

> in the unoptimize_kprobe(), do_unoptimize_kprobes() must continue to check
> the freeing_list even if unoptimizing_list is empty.
> 
> This bug can be happen if a kprobe is put in an instruction which is in the

"This bug can happen if"

> middle of the jump-replaced instruction sequence of an optprobe, *and* the
> optprobe is recently unregistered and queued on unoptimizing_list.
> In this case, the optprobe will be unoptimized forcibly (means immediately)
> and put it into the freeing_list, expecting the optprobe will be handled in
> do_unoptimize_kprobe().
> But if there is no other optprobes on the unoptimizing_list, current code
> returns from the do_unoptimize_kprobe() soon and do not handle the optprobe

                                              "and does not handle'

> which is on the freeing_list, and it will hit the WARN_ON_ONCE() in the
> do_free_cleaned_kprobes(), because it is not handled in the latter loop of
> the do_unoptimize_kprobe().
> 
> To solve this issue, do not return from do_unoptimize_kprobes() immediately
> even if unoptimizing_list is empty.
> 
> Moreover, this change affects another case. kill_optimized_kprobes() expects
> kprobe_optimizer() will just free the optprobe on freeing_list.
> So I changed it to just do list_move() to freeing_list if optprobes are on
> unoptimizing list. And the do_unoptimize_kprobe() will skip
> arch_disarm_kprobe() if the probe on freeing_list has gone flag.
> 
> Link: https://lore.kernel.org/all/Y8URdIfVr3pq2X8w@xpf.sh.intel.com/
> 
> Fixes: e4add247789e ("kprobes: Fix optimize_kprobe()/unoptimize_kprobe() cancellation logic")
> Reported-by: Pengfei Xu <pengfei.xu@intel.com>
> Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> ---
>  kernel/kprobes.c |   23 ++++++++++-------------
>  1 file changed, 10 insertions(+), 13 deletions(-)
> 
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 1c18ecf9f98b..73b150fad936 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -555,17 +555,15 @@ static void do_unoptimize_kprobes(void)
>  	/* See comment in do_optimize_kprobes() */
>  	lockdep_assert_cpus_held();
>  
> -	/* Unoptimization must be done anytime */
> -	if (list_empty(&unoptimizing_list))
> -		return;
> +	if (!list_empty(&unoptimizing_list))
> +		arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list);
>  
> -	arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list);
> -	/* Loop on 'freeing_list' for disarming */
> +	/* Loop on 'freeing_list' for disarming and removing from kprobe hash list */
>  	list_for_each_entry_safe(op, tmp, &freeing_list, list) {
>  		/* Switching from detour code to origin */
>  		op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
> -		/* Disarm probes if marked disabled */
> -		if (kprobe_disabled(&op->kp))
> +		/* Disarm probes if marked disabled and not gone */
> +		if (kprobe_disabled(&op->kp) && !kprobe_gone(&op->kp))
>  			arch_disarm_kprobe(&op->kp);
>  		if (kprobe_unused(&op->kp)) {
>  			/*
> @@ -797,14 +795,13 @@ static void kill_optimized_kprobe(struct kprobe *p)
>  	op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED;
>  
>  	if (kprobe_unused(p)) {
> -		/* Enqueue if it is unused */
> -		list_add(&op->list, &freeing_list);
>  		/*
> -		 * Remove unused probes from the hash list. After waiting
> -		 * for synchronization, this probe is reclaimed.
> -		 * (reclaiming is done by do_free_cleaned_kprobes().)
> +		 * Unused kprobe is on unoptimizing or freeing list. We move it
> +		 * to freeing_list and let the kprobe_optimizer() removes it from

                                                                 "remove it"

> +		 * the kprobe hash list and frees it.

                                        "and free it."

>  		 */
> -		hlist_del_rcu(&op->kp.hlist);
> +		if (optprobe_queued_unopt(op))
> +			list_move(&op->list, &freeing_list);
>  	}
>  
>  	/* Don't touch the code, because it is already freed. */

Other than the spelling issues,

Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>

-- Steve

  reply	other threads:[~2023-01-23 18:39 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-16  8:57 [Syzkaller & bisect] There is "register_kprobe" WARNING in v6.2-rc3 mainline kernel Pengfei Xu
2023-01-19 23:57 ` Masami Hiramatsu
2023-01-23 13:24 ` [PATCH] kprobes: Fix to handle forcibly unoptimized kprobes on freeing_list Masami Hiramatsu (Google)
2023-01-23 18:39   ` Steven Rostedt [this message]
2023-01-24  0:00     ` Masami Hiramatsu

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=20230123133931.6f6a711d@gandalf.local.home \
    --to=rostedt@goodmis.org \
    --cc=heng.su@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=naveen.n.rao@linux.ibm.com \
    --cc=pengfei.xu@intel.com \
    --cc=peterz@infradead.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.