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

bpf, xdp, samples: Fix null pointer dereference in *_user code

Memset on the pointer right after malloc can cause a NULL pointer
deference if it failed to allocate memory. A simple fix is to
replace malloc()/memset() pair with a simple call to calloc().

Fixes: 0fca931a6f21 ("samples/bpf: program demonstrating access to xdp_rxq_info")
Signed-off-by: Gaurav Singh <gaurav1086@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
Acked-by: John Fastabend <john.fastabend@gmail.com>

authored by

Gaurav Singh and committed by
Daniel Borkmann
6903cdae c34a06c5

+7 -21
+2 -6
samples/bpf/xdp_monitor_user.c
··· 509 509 { 510 510 unsigned int nr_cpus = bpf_num_possible_cpus(); 511 511 void *array; 512 - size_t size; 513 512 514 - size = record_size * nr_cpus; 515 - array = malloc(size); 516 - memset(array, 0, size); 513 + array = calloc(nr_cpus, record_size); 517 514 if (!array) { 518 515 fprintf(stderr, "Mem alloc error (nr_cpus:%u)\n", nr_cpus); 519 516 exit(EXIT_FAIL_MEM); ··· 525 528 int i; 526 529 527 530 /* Alloc main stats_record structure */ 528 - rec = malloc(sizeof(*rec)); 529 - memset(rec, 0, sizeof(*rec)); 531 + rec = calloc(1, sizeof(*rec)); 530 532 if (!rec) { 531 533 fprintf(stderr, "Mem alloc error\n"); 532 534 exit(EXIT_FAIL_MEM);
+2 -5
samples/bpf/xdp_redirect_cpu_user.c
··· 207 207 { 208 208 unsigned int nr_cpus = bpf_num_possible_cpus(); 209 209 struct datarec *array; 210 - size_t size; 211 210 212 - size = sizeof(struct datarec) * nr_cpus; 213 - array = malloc(size); 214 - memset(array, 0, size); 211 + array = calloc(nr_cpus, sizeof(struct datarec)); 215 212 if (!array) { 216 213 fprintf(stderr, "Mem alloc error (nr_cpus:%u)\n", nr_cpus); 217 214 exit(EXIT_FAIL_MEM); ··· 223 226 224 227 size = sizeof(*rec) + n_cpus * sizeof(struct record); 225 228 rec = malloc(size); 226 - memset(rec, 0, size); 227 229 if (!rec) { 228 230 fprintf(stderr, "Mem alloc error\n"); 229 231 exit(EXIT_FAIL_MEM); 230 232 } 233 + memset(rec, 0, size); 231 234 rec->rx_cnt.cpu = alloc_record_per_cpu(); 232 235 rec->redir_err.cpu = alloc_record_per_cpu(); 233 236 rec->kthread.cpu = alloc_record_per_cpu();
+3 -10
samples/bpf/xdp_rxq_info_user.c
··· 198 198 { 199 199 unsigned int nr_cpus = bpf_num_possible_cpus(); 200 200 struct datarec *array; 201 - size_t size; 202 201 203 - size = sizeof(struct datarec) * nr_cpus; 204 - array = malloc(size); 205 - memset(array, 0, size); 202 + array = calloc(nr_cpus, sizeof(struct datarec)); 206 203 if (!array) { 207 204 fprintf(stderr, "Mem alloc error (nr_cpus:%u)\n", nr_cpus); 208 205 exit(EXIT_FAIL_MEM); ··· 211 214 { 212 215 unsigned int nr_rxqs = bpf_map__def(rx_queue_index_map)->max_entries; 213 216 struct record *array; 214 - size_t size; 215 217 216 - size = sizeof(struct record) * nr_rxqs; 217 - array = malloc(size); 218 - memset(array, 0, size); 218 + array = calloc(nr_rxqs, sizeof(struct record)); 219 219 if (!array) { 220 220 fprintf(stderr, "Mem alloc error (nr_rxqs:%u)\n", nr_rxqs); 221 221 exit(EXIT_FAIL_MEM); ··· 226 232 struct stats_record *rec; 227 233 int i; 228 234 229 - rec = malloc(sizeof(*rec)); 230 - memset(rec, 0, sizeof(*rec)); 235 + rec = calloc(1, sizeof(struct stats_record)); 231 236 if (!rec) { 232 237 fprintf(stderr, "Mem alloc error\n"); 233 238 exit(EXIT_FAIL_MEM);