diff options
| author | Alexei Starovoitov <ast@fb.com> | 2016-06-15 21:25:38 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-06-16 02:37:54 -0400 |
| commit | 19de99f70b87fcc3338da52a89c439b088cbff71 (patch) | |
| tree | 43b5ff80043ee9ea62e09fe568502c9d68a188ee /kernel/trace | |
| parent | e582615ad33dbd39623084a02e95567b116e1eea (diff) | |
bpf: fix matching of data/data_end in verifier
The ctx structure passed into bpf programs is different depending on bpf
program type. The verifier incorrectly marked ctx->data and ctx->data_end
access based on ctx offset only. That caused loads in tracing programs
int bpf_prog(struct pt_regs *ctx) { .. ctx->ax .. }
to be incorrectly marked as PTR_TO_PACKET which later caused verifier
to reject the program that was actually valid in tracing context.
Fix this by doing program type specific matching of ctx offsets.
Fixes: 969bf05eb3ce ("bpf: direct packet access")
Reported-by: Sasha Goldshtein <goldshtn@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/trace')
| -rw-r--r-- | kernel/trace/bpf_trace.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 720b7bb01d43..e7af6cb9d5cf 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c | |||
| @@ -349,7 +349,8 @@ static const struct bpf_func_proto *kprobe_prog_func_proto(enum bpf_func_id func | |||
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | /* bpf+kprobe programs can access fields of 'struct pt_regs' */ | 351 | /* bpf+kprobe programs can access fields of 'struct pt_regs' */ |
| 352 | static bool kprobe_prog_is_valid_access(int off, int size, enum bpf_access_type type) | 352 | static bool kprobe_prog_is_valid_access(int off, int size, enum bpf_access_type type, |
| 353 | enum bpf_reg_type *reg_type) | ||
| 353 | { | 354 | { |
| 354 | /* check bounds */ | 355 | /* check bounds */ |
| 355 | if (off < 0 || off >= sizeof(struct pt_regs)) | 356 | if (off < 0 || off >= sizeof(struct pt_regs)) |
| @@ -427,7 +428,8 @@ static const struct bpf_func_proto *tp_prog_func_proto(enum bpf_func_id func_id) | |||
| 427 | } | 428 | } |
| 428 | } | 429 | } |
| 429 | 430 | ||
| 430 | static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type) | 431 | static bool tp_prog_is_valid_access(int off, int size, enum bpf_access_type type, |
| 432 | enum bpf_reg_type *reg_type) | ||
| 431 | { | 433 | { |
| 432 | if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE) | 434 | if (off < sizeof(void *) || off >= PERF_MAX_TRACE_SIZE) |
| 433 | return false; | 435 | return false; |
