linux/kernel/bpf
Daniel Borkmann bc23105ca0 bpf: fix context access in tracing progs on 32 bit archs
Wang reported that all the testcases for BPF_PROG_TYPE_PERF_EVENT
program type in test_verifier report the following errors on x86_32:

  172/p unpriv: spill/fill of different pointers ldx FAIL
  Unexpected error message!
  0: (bf) r6 = r10
  1: (07) r6 += -8
  2: (15) if r1 == 0x0 goto pc+3
  R1=ctx(id=0,off=0,imm=0) R6=fp-8,call_-1 R10=fp0,call_-1
  3: (bf) r2 = r10
  4: (07) r2 += -76
  5: (7b) *(u64 *)(r6 +0) = r2
  6: (55) if r1 != 0x0 goto pc+1
  R1=ctx(id=0,off=0,imm=0) R2=fp-76,call_-1 R6=fp-8,call_-1 R10=fp0,call_-1 fp-8=fp
  7: (7b) *(u64 *)(r6 +0) = r1
  8: (79) r1 = *(u64 *)(r6 +0)
  9: (79) r1 = *(u64 *)(r1 +68)
  invalid bpf_context access off=68 size=8

  378/p check bpf_perf_event_data->sample_period byte load permitted FAIL
  Failed to load prog 'Permission denied'!
  0: (b7) r0 = 0
  1: (71) r0 = *(u8 *)(r1 +68)
  invalid bpf_context access off=68 size=1

  379/p check bpf_perf_event_data->sample_period half load permitted FAIL
  Failed to load prog 'Permission denied'!
  0: (b7) r0 = 0
  1: (69) r0 = *(u16 *)(r1 +68)
  invalid bpf_context access off=68 size=2

  380/p check bpf_perf_event_data->sample_period word load permitted FAIL
  Failed to load prog 'Permission denied'!
  0: (b7) r0 = 0
  1: (61) r0 = *(u32 *)(r1 +68)
  invalid bpf_context access off=68 size=4

  381/p check bpf_perf_event_data->sample_period dword load permitted FAIL
  Failed to load prog 'Permission denied'!
  0: (b7) r0 = 0
  1: (79) r0 = *(u64 *)(r1 +68)
  invalid bpf_context access off=68 size=8

Reason is that struct pt_regs on x86_32 doesn't fully align to 8 byte
boundary due to its size of 68 bytes. Therefore, bpf_ctx_narrow_access_ok()
will then bail out saying that off & (size_default - 1) which is 68 & 7
doesn't cleanly align in the case of sample_period access from struct
bpf_perf_event_data, hence verifier wrongly thinks we might be doing an
unaligned access here though underlying arch can handle it just fine.
Therefore adjust this down to machine size and check and rewrite the
offset for narrow access on that basis. We also need to fix corresponding
pe_prog_is_valid_access(), since we hit the check for off % size != 0
(e.g. 68 % 8 -> 4) in the first and last test. With that in place, progs
for tracing work on x86_32.

Reported-by: Wang YanQing <udknight@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Tested-by: Wang YanQing <udknight@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-06-03 07:46:56 -07:00
..
arraymap.c bpf: btf: Rename btf_key_id and btf_value_id in bpf_map_info 2018-05-23 12:03:32 +02:00
bpf_lru_list.c
bpf_lru_list.h
btf.c bpf: btf: Ensure t->type == 0 for BTF_KIND_FWD 2018-06-02 11:22:36 -07:00
cgroup.c bpf: Hooks for sys_sendmsg 2018-05-28 17:41:02 +02:00
core.c bpf: bpf_prog_array_copy() should return -ENOENT if exclude_prog not found 2018-05-30 12:37:38 +02:00
cpumap.c xdp: introduce xdp_return_frame_rx_napi 2018-05-24 18:36:15 -07:00
devmap.c bpf: devmap: remove redundant assignment of dev = dev 2018-05-30 14:02:48 -07:00
disasm.c
disasm.h
hashtab.c bpf: avoid retpoline for lookup/update/delete calls on maps 2018-06-03 07:45:37 -07:00
helpers.c
inode.c bpf: remove tracepoints from bpf core 2018-04-30 10:55:56 +02:00
lpm_trie.c
Makefile bpf: introduce new bpf AF_XDP map type BPF_MAP_TYPE_XSKMAP 2018-05-03 15:55:24 -07:00
map_in_map.c
map_in_map.h
offload.c bpf: offload: allow offloaded programs to use perf event arrays 2018-05-04 23:41:03 +02:00
percpu_freelist.c
percpu_freelist.h
sockmap.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next 2018-05-24 22:20:51 -04:00
stackmap.c bpf: avoid -Wmaybe-uninitialized warning 2018-05-28 17:40:59 +02:00
syscall.c bpf: show prog and map id in fdinfo 2018-06-03 07:42:06 -07:00
tnum.c
verifier.c bpf: fix context access in tracing progs on 32 bit archs 2018-06-03 07:46:56 -07:00
xskmap.c xsk: clean up SPDX headers 2018-05-18 16:07:02 +02:00