summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2026-10-17 23:09:36 +0000
committerAlexei Starovoitov <ast@kernel.org>2026-10-18 00:36:43 +0000
commitfcbfa99aa657627528b75e7dc1023bcb0b84e558 (patch)
tree0d6a3268703b3afc650923c855773eb27cb7fe46 /kernel
parentb83bacf2161d0f8583e3f1e9c90402638992ad82 (diff)
downloadlinux-fcbfa99aa657627528b75e7dc1023bcb0b84e558.tar.gz
linux-fcbfa99aa657627528b75e7dc1023bcb0b84e558.zip
bpf: Don't let an extension reach further into the context than its target
How large the context of a raw tracepoint, tracepoint or syscall program is depends on what the program is attached to, or is run with. bpf_probe_register(), perf_event_set_bpf_prog() and the test runs compare that with max_ctx_offset of the program. An extension of the program, or of one of its global functions, gets the same context. How far it reaches is noted in its own max_ctx_offset, which nobody looks at. On a tracepoint with one argument it reads the stack behind the arguments, in a test run the memory behind the context, or from NULL if there is none: BUG: KASAN: stack-out-of-bounds in bpf_prog_954b5d2051843629_ts28_ext_far+0x7e/0x113 Read of size 8 at addr ffffc90000def7b8 by task ts28/104 BUG: KASAN: slab-out-of-bounds in bpf_prog_954b5d2051843629_ts28_ext_far+0x7e/0x113 Read of size 8 at addr ffff88810712c3e8 by task ts28/104 Refuse to attach an extension that reaches further than the program which it extends. A program that leaves the context to its extensions has to touch as much of it as they do. Fixes: be8704ff07d2 ("bpf: Introduce dynamic program extensions") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261017230950.802052-3-alexei.starovoitov@gmail.com
Diffstat (limited to 'kernel')
-rw-r--r--kernel/bpf/syscall.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index c412bcd1903f..d026ab779ce8 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -3851,6 +3851,19 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog,
err = -EINVAL;
goto out_unlock;
}
+ /*
+ * The size of these contexts depends on what the program is attached
+ * to, or run with. That is compared with max_ctx_offset of the program,
+ * and nobody looks at the one of its extensions.
+ */
+ if (prog->type == BPF_PROG_TYPE_EXT &&
+ (tgt_prog->type == BPF_PROG_TYPE_RAW_TRACEPOINT ||
+ tgt_prog->type == BPF_PROG_TYPE_TRACEPOINT ||
+ tgt_prog->type == BPF_PROG_TYPE_SYSCALL) &&
+ prog->aux->max_ctx_offset > tgt_prog->aux->max_ctx_offset) {
+ err = -EINVAL;
+ goto out_unlock;
+ }
err = bpf_link_prime(&link->link.link, &link_primer);
if (err)