Commit 9d47bd21 authored by Jiri Olsa's avatar Jiri Olsa Committed by Greg Kroah-Hartman

tools: bpftool: Fix json dump crash on powerpc

[ Upstream commit aa52bcbe ]

Michael reported crash with by bpf program in json mode on powerpc:

  # bpftool prog -p dump jited id 14
  [{
        "name": "0xd00000000a9aa760",
        "insns": [{
                "pc": "0x0",
                "operation": "nop",
                "operands": [null
                ]
            },{
                "pc": "0x4",
                "operation": "nop",
                "operands": [null
                ]
            },{
                "pc": "0x8",
                "operation": "mflr",
  Segmentation fault (core dumped)

The code is assuming char pointers in format, which is not always
true at least for powerpc. Fixing this by dumping the whole string
into buffer based on its format.

Please note that libopcodes code does not check return values from
fprintf callback, but as per Jakub suggestion returning -1 on allocation
failure so we do the best effort to propagate the error.

Fixes: 107f0412 ("tools: bpftool: add JSON output for `bpftool prog dump jited *` command")
Reported-by: default avatarMichael Petlan <mpetlan@redhat.com>
Signed-off-by: default avatarJiri Olsa <jolsa@kernel.org>
Reviewed-by: default avatarQuentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 2ad04d31
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
* Licensed under the GNU General Public License, version 2.0 (GPLv2) * Licensed under the GNU General Public License, version 2.0 (GPLv2)
*/ */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
...@@ -51,11 +53,13 @@ static int fprintf_json(void *out, const char *fmt, ...) ...@@ -51,11 +53,13 @@ static int fprintf_json(void *out, const char *fmt, ...)
char *s; char *s;
va_start(ap, fmt); va_start(ap, fmt);
if (vasprintf(&s, fmt, ap) < 0)
return -1;
va_end(ap);
if (!oper_count) { if (!oper_count) {
int i; int i;
s = va_arg(ap, char *);
/* Strip trailing spaces */ /* Strip trailing spaces */
i = strlen(s) - 1; i = strlen(s) - 1;
while (s[i] == ' ') while (s[i] == ' ')
...@@ -68,11 +72,10 @@ static int fprintf_json(void *out, const char *fmt, ...) ...@@ -68,11 +72,10 @@ static int fprintf_json(void *out, const char *fmt, ...)
} else if (!strcmp(fmt, ",")) { } else if (!strcmp(fmt, ",")) {
/* Skip */ /* Skip */
} else { } else {
s = va_arg(ap, char *);
jsonw_string(json_wtr, s); jsonw_string(json_wtr, s);
oper_count++; oper_count++;
} }
va_end(ap); free(s);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment