Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Prevent misaligned memory access in get_stack_raw_tp test

Perfbuf doesn't guarantee 8-byte alignment of the data like BPF ringbuf
does, so struct get_stack_trace_t can arrive not properly aligned for
subsequent u64 accesses. Easiest fix is to just copy data locally.

Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20211124002325.1737739-10-andrii@kernel.org

authored by

Andrii Nakryiko and committed by
Daniel Borkmann
6c4dedb7 3bd0233f

+10 -4
+10 -4
tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c
··· 24 24 { 25 25 bool good_kern_stack = false, good_user_stack = false; 26 26 const char *nonjit_func = "___bpf_prog_run"; 27 - struct get_stack_trace_t *e = data; 27 + /* perfbuf-submitted data is 4-byte aligned, but we need 8-byte 28 + * alignment, so copy data into a local variable, for simplicity 29 + */ 30 + struct get_stack_trace_t e; 28 31 int i, num_stack; 29 32 static __u64 cnt; 30 33 struct ksym *ks; 31 34 32 35 cnt++; 36 + 37 + memset(&e, 0, sizeof(e)); 38 + memcpy(&e, data, size <= sizeof(e) ? size : sizeof(e)); 33 39 34 40 if (size < sizeof(struct get_stack_trace_t)) { 35 41 __u64 *raw_data = data; ··· 63 57 good_user_stack = true; 64 58 } 65 59 } else { 66 - num_stack = e->kern_stack_size / sizeof(__u64); 60 + num_stack = e.kern_stack_size / sizeof(__u64); 67 61 if (env.jit_enabled) { 68 62 good_kern_stack = num_stack > 0; 69 63 } else { 70 64 for (i = 0; i < num_stack; i++) { 71 - ks = ksym_search(e->kern_stack[i]); 65 + ks = ksym_search(e.kern_stack[i]); 72 66 if (ks && (strcmp(ks->name, nonjit_func) == 0)) { 73 67 good_kern_stack = true; 74 68 break; 75 69 } 76 70 } 77 71 } 78 - if (e->user_stack_size > 0 && e->user_stack_buildid_size > 0) 72 + if (e.user_stack_size > 0 && e.user_stack_buildid_size > 0) 79 73 good_user_stack = true; 80 74 } 81 75