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;
prev parent 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