Thread (9 messages) 9 messages, 3 authors, 2021-06-27

Re: [PATCH] tracepoint: Do not warn on EEXIST or ENOENT

From: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Date: 2021-06-26 15:14:29
Also in: bpf, lkml

On 2021/06/26 23:18, Steven Rostedt wrote:
On Sat, 26 Jun 2021 22:58:45 +0900
Tetsuo Handa [off-list ref] wrote:
quoted
syzbot is hitting WARN_ON_ONCE() at tracepoint_add_func() [1], but
func_add() returning -EEXIST and func_remove() returning -ENOENT are
not kernel bugs that can justify crashing the system.
There should be no path that registers a tracepoint twice. That's a bug
in the kernel. Looking at the link below, I see the backtrace:

Call Trace:
 tracepoint_probe_register_prio kernel/tracepoint.c:369 [inline]
 tracepoint_probe_register+0x9c/0xe0 kernel/tracepoint.c:389
 __bpf_probe_register kernel/trace/bpf_trace.c:2154 [inline]
 bpf_probe_register+0x15a/0x1c0 kernel/trace/bpf_trace.c:2159
 bpf_raw_tracepoint_open+0x34a/0x720 kernel/bpf/syscall.c:2878
 __do_sys_bpf+0x2586/0x4f40 kernel/bpf/syscall.c:4435
 do_syscall_64+0x3a/0xb0 arch/x86/entry/common.c:47

So BPF is allowing the user to register the same tracepoint more than
once? That looks to be a bug in the BPF code where it shouldn't be
allowing user space to register the same tracepoint multiple times.
I didn't catch your question.

  (1) func_add() can reject an attempt to add same tracepoint multiple times
      by returning -EINVAL to the caller.
  (2) But tracepoint_add_func() (the caller of func_add()) is calling WARN_ON_ONCE()
      if func_add() returned -EINVAL.
  (3) And tracepoint_add_func() is triggerable via request from userspace.
  (4) tracepoint_probe_register_prio() serializes tracepoint_add_func() call
      triggered by concurrent request from userspace using tracepoints_mutex mutex.
  (5) But tracepoint_add_func() does not check whether same tracepoint multiple
      is already registered before calling func_add().
  (6) As a result, tracepoint_add_func() receives -EINVAL from func_add(), and
      calls WARN_ON_ONCE() and the system crashes due to panic_on_warn == 1.

Why this is a bug in the BPF code? The BPF code is not allowing userspace to
register the same tracepoint multiple times. I think that tracepoint_add_func()
is stupid enough to crash the kernel instead of rejecting when an attempt to
register the same tracepoint multiple times is made.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help