diff options
| author | Alexei Starovoitov <ast@kernel.org> | 2026-10-17 23:09:36 +0000 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-10-18 00:36:43 +0000 |
| commit | fcbfa99aa657627528b75e7dc1023bcb0b84e558 (patch) | |
| tree | 0d6a3268703b3afc650923c855773eb27cb7fe46 /kernel | |
| parent | b83bacf2161d0f8583e3f1e9c90402638992ad82 (diff) | |
| download | linux-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.c | 13 |
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) |
