summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-10-21 20:08:05 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2024-10-21 20:08:05 +0200
commitc1bc09d7bfcbe90c6df3a630ec1fb0fcd4799236 (patch)
tree8418fa91fe3778ab1bf751680dd4976de306fbb6
parentMerge tag 'vfs-6.12-rc5.fixes' of git://git.kernel.org/pub/scm/linux/kernel/g... (diff)
parentuprobe: avoid out-of-bounds memory access of fetching args (diff)
downloadlinux-c1bc09d7bfcbe90c6df3a630ec1fb0fcd4799236.tar.xz
linux-c1bc09d7bfcbe90c6df3a630ec1fb0fcd4799236.zip
Merge tag 'probes-fixes-v6.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull uprobe fix from Masami Hiramatsu: - uprobe: avoid out-of-bounds memory access of fetching args Uprobe trace events can cause out-of-bounds memory access when fetching user-space data which is bigger than one page, because it does not check the local CPU buffer size when reading the data. This checks the read data size and cut it down to the local CPU buffer size. * tag 'probes-fixes-v6.12-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: uprobe: avoid out-of-bounds memory access of fetching args
-rw-r--r--kernel/trace/trace_uprobe.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index c40531d2cbad..13f9270ed5ab 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -875,6 +875,7 @@ struct uprobe_cpu_buffer {
};
static struct uprobe_cpu_buffer __percpu *uprobe_cpu_buffer;
static int uprobe_buffer_refcnt;
+#define MAX_UCB_BUFFER_SIZE PAGE_SIZE
static int uprobe_buffer_init(void)
{
@@ -979,6 +980,11 @@ static struct uprobe_cpu_buffer *prepare_uprobe_buffer(struct trace_uprobe *tu,
ucb = uprobe_buffer_get();
ucb->dsize = tu->tp.size + dsize;
+ if (WARN_ON_ONCE(ucb->dsize > MAX_UCB_BUFFER_SIZE)) {
+ ucb->dsize = MAX_UCB_BUFFER_SIZE;
+ dsize = MAX_UCB_BUFFER_SIZE - tu->tp.size;
+ }
+
store_trace_args(ucb->buf, &tu->tp, regs, NULL, esize, dsize);
*ucbp = ucb;
@@ -998,9 +1004,6 @@ static void __uprobe_trace_func(struct trace_uprobe *tu,
WARN_ON(call != trace_file->event_call);
- if (WARN_ON_ONCE(ucb->dsize > PAGE_SIZE))
- return;
-
if (trace_trigger_soft_disabled(trace_file))
return;