diff options
Diffstat (limited to 'kernel/trace/bpf_trace.c')
-rw-r--r-- | kernel/trace/bpf_trace.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 01e6b3a38871..7f9691c86b6e 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c | |||
@@ -738,8 +738,7 @@ static const struct bpf_func_proto *pe_prog_func_proto(enum bpf_func_id func_id) | |||
738 | static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type, | 738 | static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type, |
739 | struct bpf_insn_access_aux *info) | 739 | struct bpf_insn_access_aux *info) |
740 | { | 740 | { |
741 | const int size_sp = FIELD_SIZEOF(struct bpf_perf_event_data, | 741 | const int size_u64 = sizeof(u64); |
742 | sample_period); | ||
743 | 742 | ||
744 | if (off < 0 || off >= sizeof(struct bpf_perf_event_data)) | 743 | if (off < 0 || off >= sizeof(struct bpf_perf_event_data)) |
745 | return false; | 744 | return false; |
@@ -750,8 +749,13 @@ static bool pe_prog_is_valid_access(int off, int size, enum bpf_access_type type | |||
750 | 749 | ||
751 | switch (off) { | 750 | switch (off) { |
752 | case bpf_ctx_range(struct bpf_perf_event_data, sample_period): | 751 | case bpf_ctx_range(struct bpf_perf_event_data, sample_period): |
753 | bpf_ctx_record_field_size(info, size_sp); | 752 | bpf_ctx_record_field_size(info, size_u64); |
754 | if (!bpf_ctx_narrow_access_ok(off, size, size_sp)) | 753 | if (!bpf_ctx_narrow_access_ok(off, size, size_u64)) |
754 | return false; | ||
755 | break; | ||
756 | case bpf_ctx_range(struct bpf_perf_event_data, addr): | ||
757 | bpf_ctx_record_field_size(info, size_u64); | ||
758 | if (!bpf_ctx_narrow_access_ok(off, size, size_u64)) | ||
755 | return false; | 759 | return false; |
756 | break; | 760 | break; |
757 | default: | 761 | default: |
@@ -778,6 +782,14 @@ static u32 pe_prog_convert_ctx_access(enum bpf_access_type type, | |||
778 | bpf_target_off(struct perf_sample_data, period, 8, | 782 | bpf_target_off(struct perf_sample_data, period, 8, |
779 | target_size)); | 783 | target_size)); |
780 | break; | 784 | break; |
785 | case offsetof(struct bpf_perf_event_data, addr): | ||
786 | *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern, | ||
787 | data), si->dst_reg, si->src_reg, | ||
788 | offsetof(struct bpf_perf_event_data_kern, data)); | ||
789 | *insn++ = BPF_LDX_MEM(BPF_DW, si->dst_reg, si->dst_reg, | ||
790 | bpf_target_off(struct perf_sample_data, addr, 8, | ||
791 | target_size)); | ||
792 | break; | ||
781 | default: | 793 | default: |
782 | *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern, | 794 | *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_perf_event_data_kern, |
783 | regs), si->dst_reg, si->src_reg, | 795 | regs), si->dst_reg, si->src_reg, |