From ad2f6258dd1d484f328d5cdcc1bc760419636cb2 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Fri, 6 Mar 2026 16:22:22 -0800 Subject: [PATCH] perf disasm: Fix potential use-after-free on fileloc The fileloc is a copy of a pointer to a string but in places like symbol_disassemble__llvm this string appears to be freed setting up potential use-after-frees: llvm.c: ``` dl = disasm_line__new(args); if (dl == NULL) goto err; annotation_line__add(&dl->al, ¬es->src->source); free(args->fileloc); ``` disasm.c: ``` static void annotation_line__init(struct annotation_line *al, struct annotate_args *args, int nr) { al->offset = args->offset; al->line = strdup(args->line); al->line_nr = args->line_nr; al->fileloc = args->fileloc; al->data_nr = nr; } struct disasm_line *disasm_line__new(struct annotate_args *args) { struct disasm_line *dl = NULL; struct annotation *notes = symbol__annotation(args->ms->sym); int nr = notes->src->nr_events; dl = zalloc(disasm_line_size(nr)); if (!dl) return NULL; annotation_line__init(&dl->al, args, nr); ``` Fix this by making the fileloc a copy of the underlying string in its init/exit. Signed-off-by: Ian Rogers Signed-off-by: Namhyung Kim --- tools/perf/util/disasm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index ddcc488f2e5f0..3fcb3634a7e03 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -908,13 +908,14 @@ static void annotation_line__init(struct annotation_line *al, al->offset = args->offset; al->line = strdup(args->line); al->line_nr = args->line_nr; - al->fileloc = args->fileloc; + al->fileloc = args->fileloc ? strdup(args->fileloc) : NULL; al->data_nr = nr; } static void annotation_line__exit(struct annotation_line *al) { zfree_srcline(&al->path); + zfree(&al->fileloc); zfree(&al->line); zfree(&al->cycles); zfree(&al->br_cntr); @@ -950,7 +951,7 @@ struct disasm_line *disasm_line__new(struct annotate_args *args) annotation_line__init(&dl->al, args, nr); if (dl->al.line == NULL) - goto out_delete; + goto out_free_line; if (args->offset != -1) { if (arch__is_powerpc(args->arch)) { @@ -965,8 +966,7 @@ struct disasm_line *disasm_line__new(struct annotate_args *args) return dl; out_free_line: - zfree(&dl->al.line); -out_delete: + annotation_line__exit(&dl->al); free(dl); return NULL; } -- 2.47.3