perf disasm: Fix capstone memory leak
authorIan Rogers <irogers@google.com>
Wed, 16 Oct 2024 23:56:21 +0000 (16:56 -0700)
committerNamhyung Kim <namhyung@kernel.org>
Thu, 17 Oct 2024 19:43:14 +0000 (12:43 -0700)
The insn argument passed to cs_disasm needs freeing. To support
accurately having count, add an additional free_count variable.

Fixes: c5d60de1813a ("perf annotate: Add support to use libcapstone in powerpc")
Signed-off-by: Ian Rogers <irogers@google.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Steinar H. Gunderson <sesse@google.com>
Cc: Alexander Lobakin <aleksander.lobakin@intel.com>
Cc: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Link: https://lore.kernel.org/r/20241016235622.52166-2-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
tools/perf/util/disasm.c

index f05ba7739c1e91e818e345309576fedc8bfcc6c4..2c8063660f2e8cb54917b73f58b48039812fe7ec 100644 (file)
@@ -1627,12 +1627,12 @@ static int symbol__disassemble_capstone(char *filename, struct symbol *sym,
        u64 start = map__rip_2objdump(map, sym->start);
        u64 len;
        u64 offset;
-       int i, count;
+       int i, count, free_count;
        bool is_64bit = false;
        bool needs_cs_close = false;
        u8 *buf = NULL;
        csh handle;
-       cs_insn *insn;
+       cs_insn *insn = NULL;
        char disasm_buf[512];
        struct disasm_line *dl;
 
@@ -1664,7 +1664,7 @@ static int symbol__disassemble_capstone(char *filename, struct symbol *sym,
 
        needs_cs_close = true;
 
-       count = cs_disasm(handle, buf, len, start, len, &insn);
+       free_count = count = cs_disasm(handle, buf, len, start, len, &insn);
        for (i = 0, offset = 0; i < count; i++) {
                int printed;
 
@@ -1702,8 +1702,11 @@ static int symbol__disassemble_capstone(char *filename, struct symbol *sym,
        }
 
 out:
-       if (needs_cs_close)
+       if (needs_cs_close) {
                cs_close(&handle);
+               if (free_count > 0)
+                       cs_free(insn, free_count);
+       }
        free(buf);
        return count < 0 ? count : 0;