From 5ce083d434999da29ad1ffc425e6fb0ba4c64b0b Mon Sep 17 00:00:00 2001 From: Puranjay Mohan Date: Thu, 6 Mar 2025 01:46:42 +0000 Subject: [PATCH 1/2] bpf: Send signals asynchronously if !preemptible mainline inclusion from mainline-v6.14-rc1 commit 87c544108b612512b254c8f79aa5c0a8546e2cc4 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBOK8S Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=87c544108b612512b254c8f79aa5c0a8546e2cc4 -------------------------------- BPF programs can execute in all kinds of contexts and when a program running in a non-preemptible context uses the bpf_send_signal() kfunc, it will cause issues because this kfunc can sleep. Change `irqs_disabled()` to `!preemptible()`. Reported-by: syzbot+97da3d7e0112d59971de@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/67486b09.050a0220.253251.0084.GAE@google.com/ Fixes: 1bc7896e9ef4 ("bpf: Fix deadlock with rq_lock in bpf_send_signal()") Signed-off-by: Puranjay Mohan Acked-by: Yonghong Song Link: https://lore.kernel.org/r/20250115103647.38487-1-puranjay@kernel.org Signed-off-by: Alexei Starovoitov Conflicts: kernel/trace/bpf_trace.c [The conflicts were due to not merge dee19d6147581] Signed-off-by: Xiaomeng Zhang --- kernel/trace/bpf_trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index a05e1221948e..6068a014ab65 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -852,7 +852,7 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type) if (unlikely(is_global_init(current))) return -EPERM; - if (irqs_disabled()) { + if (!preemptible()) { /* Do an early check on signal validity. Otherwise, * the error is lost in deferred irq_work. */ -- Gitee From ea2232b39ada9e0f079c557d5f9ad8dfc8e9cebb Mon Sep 17 00:00:00 2001 From: Hou Tao Date: Thu, 6 Mar 2025 01:46:43 +0000 Subject: [PATCH 2/2] bpf: Use preempt_count() directly in bpf_send_signal_common() maillist inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBQWD8 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=b4a8b5bba712 -------------------------------- bpf_send_signal_common() uses preemptible() to check whether or not the current context is preemptible. If it is preemptible, it will use irq_work to send the signal asynchronously instead of trying to hold a spin-lock, because spin-lock is sleepable under PREEMPT_RT. However, preemptible() depends on CONFIG_PREEMPT_COUNT. When CONFIG_PREEMPT_COUNT is turned off (e.g., CONFIG_PREEMPT_VOLUNTARY=y), !preemptible() will be evaluated as 1 and bpf_send_signal_common() will use irq_work unconditionally. Fix it by unfolding "!preemptible()" and using "preempt_count() != 0 || irqs_disabled()" instead. Fixes: 87c544108b61 ("bpf: Send signals asynchronously if !preemptible") Signed-off-by: Hou Tao Link: https://lore.kernel.org/r/20250220042259.1583319-1-houtao@huaweicloud.com Signed-off-by: Alexei Starovoitov Signed-off-by: Xiaomeng Zhang z --- kernel/trace/bpf_trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 6068a014ab65..7945b765ef47 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -852,7 +852,7 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type) if (unlikely(is_global_init(current))) return -EPERM; - if (!preemptible()) { + if (preempt_count() != 0 || irqs_disabled()) { /* Do an early check on signal validity. Otherwise, * the error is lost in deferred irq_work. */ -- Gitee