From: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
To: stable@vger.kernel.org
Cc: cascardo@igalia.com, jolsa@kernel.org, daniel@iogearbox.net, yhs@fb.com
Subject: [PATCH 5.15 3/4] bpf: Do cleanup in bpf_bprintf_cleanup only when needed
Date: Sat, 17 Feb 2024 09:13:20 -0300 [thread overview]
Message-ID: <20240217121321.2045993-7-cascardo@igalia.com> (raw)
In-Reply-To: <20240217121321.2045993-1-cascardo@igalia.com>
From: Jiri Olsa <jolsa@kernel.org>
commit f19a4050455aad847fb93f18dc1fe502eb60f989 upstream.
Currently we always cleanup/decrement bpf_bprintf_nest_level variable
in bpf_bprintf_cleanup if it's > 0.
There's possible scenario where this could cause a problem, when
bpf_bprintf_prepare does not get bin_args buffer (because num_args is 0)
and following bpf_bprintf_cleanup call decrements bpf_bprintf_nest_level
variable, like:
in task context:
bpf_bprintf_prepare(num_args != 0) increments 'bpf_bprintf_nest_level = 1'
-> first irq :
bpf_bprintf_prepare(num_args == 0)
bpf_bprintf_cleanup decrements 'bpf_bprintf_nest_level = 0'
-> second irq:
bpf_bprintf_prepare(num_args != 0) bpf_bprintf_nest_level = 1
gets same buffer as task context above
Adding check to bpf_bprintf_cleanup and doing the real cleanup only if we
got bin_args data in the first place.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Yonghong Song <yhs@fb.com>
Link: https://lore.kernel.org/bpf/20221215214430.1336195-3-jolsa@kernel.org
[cascardo: there is no bpf_trace_vprintk in 5.15]
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
---
include/linux/bpf.h | 2 +-
kernel/bpf/helpers.c | 16 +++++++++-------
kernel/trace/bpf_trace.c | 4 ++--
3 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index c738e98b426b..d18f717b6e7e 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -2295,6 +2295,6 @@ struct bpf_bprintf_data {
int bpf_bprintf_prepare(char *fmt, u32 fmt_size, const u64 *raw_args,
u32 num_args, struct bpf_bprintf_data *data);
-void bpf_bprintf_cleanup(void);
+void bpf_bprintf_cleanup(struct bpf_bprintf_data *data);
#endif /* _LINUX_BPF_H */
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 20796e387e2c..cfa23c7112ed 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -738,12 +738,14 @@ static int try_get_fmt_tmp_buf(char **tmp_buf)
return 0;
}
-void bpf_bprintf_cleanup(void)
+void bpf_bprintf_cleanup(struct bpf_bprintf_data *data)
{
- if (this_cpu_read(bpf_bprintf_nest_level)) {
- this_cpu_dec(bpf_bprintf_nest_level);
- preempt_enable();
- }
+ if (!data->bin_args)
+ return;
+ if (WARN_ON_ONCE(this_cpu_read(bpf_bprintf_nest_level) == 0))
+ return;
+ this_cpu_dec(bpf_bprintf_nest_level);
+ preempt_enable();
}
/*
@@ -975,7 +977,7 @@ int bpf_bprintf_prepare(char *fmt, u32 fmt_size, const u64 *raw_args,
err = 0;
out:
if (err)
- bpf_bprintf_cleanup();
+ bpf_bprintf_cleanup(data);
return err;
}
@@ -1001,7 +1003,7 @@ BPF_CALL_5(bpf_snprintf, char *, str, u32, str_size, char *, fmt,
err = bstr_printf(str, str_size, fmt, data.bin_args);
- bpf_bprintf_cleanup();
+ bpf_bprintf_cleanup(&data);
return err + 1;
}
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index 33da2ff59b96..2bc85a87f020 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -387,7 +387,7 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1,
trace_bpf_trace_printk(buf);
raw_spin_unlock_irqrestore(&trace_printk_lock, flags);
- bpf_bprintf_cleanup();
+ bpf_bprintf_cleanup(&data);
return ret;
}
@@ -435,7 +435,7 @@ BPF_CALL_5(bpf_seq_printf, struct seq_file *, m, char *, fmt, u32, fmt_size,
seq_bprintf(m, fmt, data.bin_args);
- bpf_bprintf_cleanup();
+ bpf_bprintf_cleanup(&data);
return seq_has_overflowed(m) ? -EOVERFLOW : 0;
}
--
2.34.1
next prev parent reply other threads:[~2024-02-17 12:13 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-17 12:13 [PATCH 5.15,6.1] Fixup preempt imbalance with bpf_trace_printk Thadeu Lima de Souza Cascardo
2024-02-17 12:13 ` [PATCH 6.1 1/3] bpf: Add struct for bin_args arg in bpf_bprintf_prepare Thadeu Lima de Souza Cascardo
2024-02-17 12:13 ` [PATCH 6.1 2/3] bpf: Do cleanup in bpf_bprintf_cleanup only when needed Thadeu Lima de Souza Cascardo
2024-02-17 12:13 ` [PATCH 6.1 3/3] bpf: Remove trace_printk_lock Thadeu Lima de Souza Cascardo
2024-02-17 12:13 ` [PATCH 5.15 1/4] bpf: Merge printk and seq_printf VARARG max macros Thadeu Lima de Souza Cascardo
2024-02-17 12:13 ` [PATCH 5.15 2/4] bpf: Add struct for bin_args arg in bpf_bprintf_prepare Thadeu Lima de Souza Cascardo
2024-02-17 12:13 ` Thadeu Lima de Souza Cascardo [this message]
2024-02-17 12:13 ` [PATCH 5.15 4/4] bpf: Remove trace_printk_lock Thadeu Lima de Souza Cascardo
2024-02-23 15:43 ` [PATCH 5.15,6.1] Fixup preempt imbalance with bpf_trace_printk Greg KH
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=20240217121321.2045993-7-cascardo@igalia.com \
--to=cascardo@igalia.com \
--cc=daniel@iogearbox.net \
--cc=jolsa@kernel.org \
--cc=stable@vger.kernel.org \
--cc=yhs@fb.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