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

samples/bpf: syscall_tp_user: Fix array out-of-bound access

Commit 06744f24696e ("samples/bpf: Add openat2() enter/exit tracepoint
to syscall_tp sample") added two more eBPF programs to support the
openat2() syscall. However, it did not increase the size of the array
that holds the corresponding bpf_links. This leads to an out-of-bound
access on that array in the bpf_object__for_each_program loop and could
corrupt other variables on the stack. On our testing QEMU, it corrupts
the map1_fds array and causes the sample to fail:

# ./syscall_tp
prog #0: map ids 4 5
verify map:4 val: 5
map_lookup failed: Bad file descriptor

Dynamically allocate the array based on the number of programs reported
by libbpf to prevent similar inconsistencies in the future

Fixes: 06744f24696e ("samples/bpf: Add openat2() enter/exit tracepoint to syscall_tp sample")
Signed-off-by: Jinghao Jia <jinghao@linux.ibm.com>
Signed-off-by: Ruowen Qin <ruowenq2@illinois.edu>
Signed-off-by: Jinghao Jia <jinghao7@illinois.edu>
Link: https://lore.kernel.org/r/20230917214220.637721-4-jinghao7@illinois.edu
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Jinghao Jia and committed by
Alexei Starovoitov
9220c3ef 0ee352fe

+20 -3
+20 -3
samples/bpf/syscall_tp_user.c
··· 48 48 static int test(char *filename, int nr_tests) 49 49 { 50 50 int map0_fds[nr_tests], map1_fds[nr_tests], fd, i, j = 0; 51 - struct bpf_link *links[nr_tests * 4]; 51 + struct bpf_link **links = NULL; 52 52 struct bpf_object *objs[nr_tests]; 53 53 struct bpf_program *prog; 54 54 ··· 58 58 fprintf(stderr, "opening BPF object file failed\n"); 59 59 objs[i] = NULL; 60 60 goto cleanup; 61 + } 62 + 63 + /* One-time initialization */ 64 + if (!links) { 65 + int nr_progs = 0; 66 + 67 + bpf_object__for_each_program(prog, objs[i]) 68 + nr_progs += 1; 69 + 70 + links = calloc(nr_progs * nr_tests, sizeof(struct bpf_link *)); 71 + 72 + if (!links) 73 + goto cleanup; 61 74 } 62 75 63 76 /* load BPF program */ ··· 120 107 } 121 108 122 109 cleanup: 123 - for (j--; j >= 0; j--) 124 - bpf_link__destroy(links[j]); 110 + if (links) { 111 + for (j--; j >= 0; j--) 112 + bpf_link__destroy(links[j]); 113 + 114 + free(links); 115 + } 125 116 126 117 for (i--; i >= 0; i--) 127 118 bpf_object__close(objs[i]);