summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2019-01-28 13:01:21 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2019-01-28 17:59:46 -0500
commit8c79b35693380d856dcbbc21629682a90f26ca62 (patch)
tree7d5369d287051417dc10d1c79c492cc5b9728b20
parentc9e4576743eeda8d24dedc164d65b78877f9a98c (diff)
tools: bpftool: fix crash with un-owned prog arrays
Prog arrays don't have 'owner_prog_type' and 'owner_jited' fields in their fdinfo when they are created. Those fields are set and reported when first program is checked for compatibility by bpf_prog_array_compatible(). This means that bpftool cannot expect the fields to always be there. Currently trying to show maps on a system with an un-owned prog array leads to a crash: $ bpftool map show 389: prog_array name tail_call_map flags 0x0 Error: key 'owner_prog_type' not found in fdinfo Error: key 'owner_jited' not found in fdinfo key 4B value 4B max_entries 4 memlock 4096B Segmentation fault (core dumped) We pass a NULL pointer to atoi(). Remove the assumption that fdinfo keys are always present. Add missing validations and remove the p_err() calls which may lead to broken JSON output as caller will not propagate the failure. Fixes: 99a44bef5870 ("tools: bpftool: add owner_prog_type and owner_jited to bpftool output") Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com> Acked-by: Song Liu <songliubraving@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r--tools/bpf/bpftool/common.c6
-rw-r--r--tools/bpf/bpftool/map.c17
2 files changed, 9 insertions, 14 deletions
diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c
index 897483457bf0..f7261fad45c1 100644
--- a/tools/bpf/bpftool/common.c
+++ b/tools/bpf/bpftool/common.c
@@ -297,10 +297,8 @@ char *get_fdinfo(int fd, const char *key)
297 snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", fd); 297 snprintf(path, sizeof(path), "/proc/self/fdinfo/%d", fd);
298 298
299 fdi = fopen(path, "r"); 299 fdi = fopen(path, "r");
300 if (!fdi) { 300 if (!fdi)
301 p_err("can't open fdinfo: %s", strerror(errno));
302 return NULL; 301 return NULL;
303 }
304 302
305 while ((n = getline(&line, &line_n, fdi)) > 0) { 303 while ((n = getline(&line, &line_n, fdi)) > 0) {
306 char *value; 304 char *value;
@@ -313,7 +311,6 @@ char *get_fdinfo(int fd, const char *key)
313 311
314 value = strchr(line, '\t'); 312 value = strchr(line, '\t');
315 if (!value || !value[1]) { 313 if (!value || !value[1]) {
316 p_err("malformed fdinfo!?");
317 free(line); 314 free(line);
318 return NULL; 315 return NULL;
319 } 316 }
@@ -326,7 +323,6 @@ char *get_fdinfo(int fd, const char *key)
326 return line; 323 return line;
327 } 324 }
328 325
329 p_err("key '%s' not found in fdinfo", key);
330 free(line); 326 free(line);
331 fclose(fdi); 327 fclose(fdi);
332 return NULL; 328 return NULL;
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c
index 29a3468c6cf6..1ef1ee2280a2 100644
--- a/tools/bpf/bpftool/map.c
+++ b/tools/bpf/bpftool/map.c
@@ -513,10 +513,9 @@ static int show_map_close_json(int fd, struct bpf_map_info *info)
513 jsonw_uint_field(json_wtr, "owner_prog_type", 513 jsonw_uint_field(json_wtr, "owner_prog_type",
514 prog_type); 514 prog_type);
515 } 515 }
516 if (atoi(owner_jited)) 516 if (owner_jited)
517 jsonw_bool_field(json_wtr, "owner_jited", true); 517 jsonw_bool_field(json_wtr, "owner_jited",
518 else 518 !!atoi(owner_jited));
519 jsonw_bool_field(json_wtr, "owner_jited", false);
520 519
521 free(owner_prog_type); 520 free(owner_prog_type);
522 free(owner_jited); 521 free(owner_jited);
@@ -569,7 +568,8 @@ static int show_map_close_plain(int fd, struct bpf_map_info *info)
569 char *owner_prog_type = get_fdinfo(fd, "owner_prog_type"); 568 char *owner_prog_type = get_fdinfo(fd, "owner_prog_type");
570 char *owner_jited = get_fdinfo(fd, "owner_jited"); 569 char *owner_jited = get_fdinfo(fd, "owner_jited");
571 570
572 printf("\n\t"); 571 if (owner_prog_type || owner_jited)
572 printf("\n\t");
573 if (owner_prog_type) { 573 if (owner_prog_type) {
574 unsigned int prog_type = atoi(owner_prog_type); 574 unsigned int prog_type = atoi(owner_prog_type);
575 575
@@ -579,10 +579,9 @@ static int show_map_close_plain(int fd, struct bpf_map_info *info)
579 else 579 else
580 printf("owner_prog_type %d ", prog_type); 580 printf("owner_prog_type %d ", prog_type);
581 } 581 }
582 if (atoi(owner_jited)) 582 if (owner_jited)
583 printf("owner jited"); 583 printf("owner%s jited",
584 else 584 atoi(owner_jited) ? "" : " not");
585 printf("owner not jited");
586 585
587 free(owner_prog_type); 586 free(owner_prog_type);
588 free(owner_jited); 587 free(owner_jited);