From: Ian Rogers Date: Sat, 7 Mar 2026 00:22:22 +0000 (-0800) Subject: perf disasm: Fix potential use-after-free on fileloc X-Git-Tag: v7.1-rc1~91^2~109 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ad2f6258dd1d484f328d5cdcc1bc760419636cb2;p=thirdparty%2Fkernel%2Flinux.git 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 --- 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; }