Commit bdb7fdb0 authored by Yonghong Song's avatar Yonghong Song Committed by Alexei Starovoitov

bpf: Fix a possible task gone issue with bpf_send_signal[_thread]() helpers

In current bpf_send_signal() and bpf_send_signal_thread() helper
implementation, irq_work is used to handle nmi context. Hao Sun
reported in [1] that the current task at the entry of the helper
might be gone during irq_work callback processing. To fix the issue,
a reference is acquired for the current task before enqueuing into
the irq_work so that the queued task is still available during
irq_work callback processing.

  [1] https://lore.kernel.org/bpf/20230109074425.12556-1-sunhao.th@gmail.com/

Fixes: 8b401f9e ("bpf: implement bpf_send_signal() helper")
Tested-by: default avatarHao Sun <sunhao.th@gmail.com>
Reported-by: default avatarHao Sun <sunhao.th@gmail.com>
Signed-off-by: default avatarYonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/r/20230118204815.3331855-1-yhs@fb.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 36024d02
...@@ -833,6 +833,7 @@ static void do_bpf_send_signal(struct irq_work *entry) ...@@ -833,6 +833,7 @@ static void do_bpf_send_signal(struct irq_work *entry)
work = container_of(entry, struct send_signal_irq_work, irq_work); work = container_of(entry, struct send_signal_irq_work, irq_work);
group_send_sig_info(work->sig, SEND_SIG_PRIV, work->task, work->type); group_send_sig_info(work->sig, SEND_SIG_PRIV, work->task, work->type);
put_task_struct(work->task);
} }
static int bpf_send_signal_common(u32 sig, enum pid_type type) static int bpf_send_signal_common(u32 sig, enum pid_type type)
...@@ -867,7 +868,7 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type) ...@@ -867,7 +868,7 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type)
* to the irq_work. The current task may change when queued * to the irq_work. The current task may change when queued
* irq works get executed. * irq works get executed.
*/ */
work->task = current; work->task = get_task_struct(current);
work->sig = sig; work->sig = sig;
work->type = type; work->type = type;
irq_work_queue(&work->irq_work); irq_work_queue(&work->irq_work);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment