public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "Wangnan (F)" <wangnan0@huawei.com>
To: Alexei Starovoitov <ast@plumgrid.com>, <linux-kernel@vger.kernel.org>
Cc: lizefan 00213767 <lizefan@huawei.com>
Subject: Re: [BUG] kernel panic after bpf program removed.
Date: Fri, 15 May 2015 17:20:42 +0800	[thread overview]
Message-ID: <5555BA6A.50906@huawei.com> (raw)
In-Reply-To: <55558634.5000902@plumgrid.com>



在 2015/5/15 13:37, Alexei Starovoitov 写道:
> On 5/14/15 8:54 PM, Wangnan (F) wrote:
>> Hi Alexei Starovoitov and other,
>>
>> I triggered a kernel panic when developing my 'perf bpf' facility. The
>> call stack is listed at the bottom of
>> this mail.
>>
>> I attached two bpf programs on 'kmem_cache_free%return' and
>> '__alloc_pages_nodemask'. The programs is very simple.
>> The panic is raised after closing the bpf program and the perf event
>> file. Looks like the panic is caused
>> by racing between closing perf event fd and bpf program fd. I'm unable
>> to reproduce this problem with similar
>> operations.
>>
>> Following is the exact instruction cause the panic.
>
> thanks for the report.
> Looks like pointer 'prog == 0x6c0' is passed into bpf_prog_put,
> which means that event->tp_event was freed and memory reused before
> free_event_rcu() was called.
>
> I think it's not perf_event_fd racing with prog_fd, but rather
> with kprobe freeing:
> __free_event()
>   event->destroy(event)
>     perf_trace_destroy
>       perf_trace_event_unreg
> which is dropping event->tp_event->perf_refcount
> that allows kprobe freeing to proceed in:
> unregister_kprobe_event
>   trace_remove_event_call
>     probe_remove_event_call
> and eventually tp_event to get freed.
>
> I think calling perf_event_free_bpf_prog()
> from __free_event() instead of free_event_rcu() will fix the race,
> but please double check my analysis.
> Also please send me a reproducer script. I'd like to see it crashing
> first before the fix and not crashing afterwards.
>

I triggered the problem with my 'perf bpf' patch series, and reproduced 
once.

The bpf program is attached.

What I do is to use

  # perf bpf record --object /root/sample_bpf_program.o -- sleep 4

to start recording, then press C-c before sleep finish after about 3 
seconds.

The second call trace is identical to the previous one.

My environment is qemu with v4.1-rc3 kernel.

Thank you.

-------------------------------------------------
  #include <uapi/linux/bpf.h>
  #include <linux/version.h>
  #include <uapi/linux/ptrace.h>

  #define SEC(NAME) __attribute__((section(NAME), used))

  static int (*bpf_map_delete_elem)(void *map, void *key) =
         (void *) BPF_FUNC_map_delete_elem;
  static int (*bpf_trace_printk)(const char *fmt, int fmt_size, ...) =
         (void *) BPF_FUNC_trace_printk;

  struct bpf_map_def {
         unsigned int type;
         unsigned int key_size;
         unsigned int value_size;
         unsigned int max_entries;
  };

  struct pair {
         u64 val;
         u64 ip;
  };

  struct bpf_map_def SEC("maps") my_map = {
         .type = BPF_MAP_TYPE_HASH,
         .key_size = sizeof(long),
         .value_size = sizeof(struct pair),
         .max_entries = 1000000,
  };

  struct bpf_map_def SEC("maps") my_map2 = {
         .type = BPF_MAP_TYPE_HASH,
         .key_size = sizeof(long),
         .value_size = sizeof(struct pair),
         .max_entries = 1000000,
  };

  SEC("cache_free=kmem_cache_free%return")
  int bpf_prog1(struct pt_regs *ctx)
  {
         long ptr = ctx->r14;
         bpf_map_delete_elem(&my_map2, &ptr);
         return 0;
  }

  SEC("mybpfprog=__alloc_pages_nodemask")
  int bpf_prog_my(struct pt_regs *ctx)
  {
         char fmt[] = "Haha\n";

         long ptr = ctx->r14;
         bpf_trace_printk(fmt, sizeof(fmt));
         bpf_map_delete_elem(&my_map, &ptr);
         return 0;
  }

  char _license[] SEC("license") = "GPL";
  u32 _version SEC("version") = LINUX_VERSION_CODE;


      reply	other threads:[~2015-05-15  9:21 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-15  3:54 [BUG] kernel panic after bpf program removed Wangnan (F)
2015-05-15  5:37 ` Alexei Starovoitov
2015-05-15  9:20   ` Wangnan (F) [this message]

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=5555BA6A.50906@huawei.com \
    --to=wangnan0@huawei.com \
    --cc=ast@plumgrid.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizefan@huawei.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