Cc Andrew and Steven.

Any other comments or someone can add this to the queue for the
merge window? It's worth fixing it.

On Sat, Aug 22, 2020 at 11:01 AM Muchun Song <[email protected]> wrote:
>
> If a kprobe is marked as gone, we should not kill it again. Otherwise,
> we can disarm the kprobe more than once. In that case, the statistics
> of kprobe_ftrace_enabled can unbalance which can lead to that kprobe
> do not work.
>
> Fixes: e8386a0cb22f ("kprobes: support probing module __exit function")
> Signed-off-by: Muchun Song <[email protected]>
> Co-developed-by: Chengming Zhou <[email protected]>
> Signed-off-by: Chengming Zhou <[email protected]>
> Acked-by: Masami Hiramatsu <[email protected]>
> ---
> changelogs in v2:
>  1. Add a WARN_ON_ONCE in the kill_kprobe() to catch incorrect use of it.
>  2. Update 'Fixes' tag in the commmit log.
>
>  kernel/kprobes.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index d36e2b017588..9348b0c36ae0 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -2143,6 +2143,9 @@ static void kill_kprobe(struct kprobe *p)
>
>         lockdep_assert_held(&kprobe_mutex);
>
> +       if (WARN_ON_ONCE(kprobe_gone(p)))
> +               return;
> +
>         p->flags |= KPROBE_FLAG_GONE;
>         if (kprobe_aggrprobe(p)) {
>                 /*
> @@ -2422,7 +2425,10 @@ static int kprobes_module_callback(struct 
> notifier_block *nb,
>         mutex_lock(&kprobe_mutex);
>         for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
>                 head = &kprobe_table[i];
> -               hlist_for_each_entry(p, head, hlist)
> +               hlist_for_each_entry(p, head, hlist) {
> +                       if (kprobe_gone(p))
> +                               continue;
> +
>                         if (within_module_init((unsigned long)p->addr, mod) ||
>                             (checkcore &&
>                              within_module_core((unsigned long)p->addr, 
> mod))) {
> @@ -2439,6 +2445,7 @@ static int kprobes_module_callback(struct 
> notifier_block *nb,
>                                  */
>                                 kill_kprobe(p);
>                         }
> +               }
>         }
>         if (val == MODULE_STATE_GOING)
>                 remove_module_kprobe_blacklist(mod);
> --
> 2.11.0
>


--
Yours,
Muchun

Reply via email to