diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-10-21 20:08:05 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-10-21 20:08:05 +0200 |
commit | c1bc09d7bfcbe90c6df3a630ec1fb0fcd4799236 (patch) | |
tree | 8418fa91fe3778ab1bf751680dd4976de306fbb6 | |
parent | Merge tag 'vfs-6.12-rc5.fixes' of git://git.kernel.org/pub/scm/linux/kernel/g... (diff) | |
parent | uprobe: avoid out-of-bounds memory access of fetching args (diff) | |
download | linux-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.c | 9 |
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; |