Probes fixes for v6.12-rc4:

- 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.
 -----BEGIN PGP SIGNATURE-----
 
 iQFPBAABCgA5FiEEh7BulGwFlgAOi5DV2/sHvwUrPxsFAmcWarUbHG1hc2FtaS5o
 aXJhbWF0c3VAZ21haWwuY29tAAoJENv7B78FKz8b3R4H/j1k6K4hYlDqiVyEaAgl
 u1b6cJncJShKdhE3laxDDvBv6oLrAypJbxiWv6obuBLpM1VTtjAFFQB84FoJae2w
 3y7UPeVrIHDnxlSDGDW3jwSh8FYaFKgLMr1pLRKw6R1ED4ZhkbEIVJ6G1qFaMrYn
 FCMF7ZX1E7MW2FuUI3L+vaaKop8FLZUKyW1gRDfw+IPy/UTgUJLRohMbxixdprPe
 W+14GHPvf/lh2MiWzVjvzaBRRiUX8OW7nA4UvvCcHQXVmzx0GmPpPuiVHC7YyhTU
 6FiVFKjMsv2jbzyREP4QYPF1n16Us0WZ0ZmGLfrSHyasr7ihj1m//YWCpFxCqzLb
 /Js=
 =VBeG
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2024-10-21 11:08:05 -07:00
commit c1bc09d7bf

View File

@ -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;