perf tools: Use zfree to help detect use after free bugs

Several areas already used this technique, so do some audit to
consistently use it elsewhere.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-9sbere0kkplwe45ak6rk4a1f@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2013-12-27 16:55:14 -03:00
parent 046625231a
commit 74cf249d5c
29 changed files with 83 additions and 80 deletions

View File

@ -654,7 +654,7 @@ static void data__free(struct data__file *d)
for (col = 0; col < PERF_HPP_DIFF__MAX_INDEX; col++) { for (col = 0; col < PERF_HPP_DIFF__MAX_INDEX; col++) {
struct diff_hpp_fmt *fmt = &d->fmt[col]; struct diff_hpp_fmt *fmt = &d->fmt[col];
free(fmt->header); zfree(&fmt->header);
} }
} }

View File

@ -469,7 +469,7 @@ static void *thread_func(void *ctx)
char comm2[22]; char comm2[22];
int fd; int fd;
free(parms); zfree(&parms);
sprintf(comm2, ":%s", this_task->comm); sprintf(comm2, ":%s", this_task->comm);
prctl(PR_SET_NAME, comm2); prctl(PR_SET_NAME, comm2);

View File

@ -1102,9 +1102,9 @@ static struct script_desc *script_desc__new(const char *name)
static void script_desc__delete(struct script_desc *s) static void script_desc__delete(struct script_desc *s)
{ {
free(s->name); zfree(&s->name);
free(s->half_liner); zfree(&s->half_liner);
free(s->args); zfree(&s->args);
free(s); free(s);
} }

View File

@ -1327,7 +1327,7 @@ static int switch_data_file(void)
abs_path[nr_options] = strdup(path); abs_path[nr_options] = strdup(path);
if (!abs_path[nr_options]) { if (!abs_path[nr_options]) {
free(options[nr_options]); zfree(&options[nr_options]);
ui__warning("Can't search all data files due to memory shortage.\n"); ui__warning("Can't search all data files due to memory shortage.\n");
fclose(file); fclose(file);
break; break;

View File

@ -510,7 +510,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
free(line); free(line);
out: out:
free(rem_sq_bracket); zfree(&rem_sq_bracket);
return ret; return ret;
} }

View File

@ -26,10 +26,10 @@ static int disasm_line__parse(char *line, char **namep, char **rawp);
static void ins__delete(struct ins_operands *ops) static void ins__delete(struct ins_operands *ops)
{ {
free(ops->source.raw); zfree(&ops->source.raw);
free(ops->source.name); zfree(&ops->source.name);
free(ops->target.raw); zfree(&ops->target.raw);
free(ops->target.name); zfree(&ops->target.name);
} }
static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size,
@ -204,9 +204,9 @@ static int lock__scnprintf(struct ins *ins, char *bf, size_t size,
static void lock__delete(struct ins_operands *ops) static void lock__delete(struct ins_operands *ops)
{ {
free(ops->locked.ops); zfree(&ops->locked.ops);
free(ops->target.raw); zfree(&ops->target.raw);
free(ops->target.name); zfree(&ops->target.name);
} }
static struct ins_ops lock_ops = { static struct ins_ops lock_ops = {
@ -583,7 +583,7 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privs
return dl; return dl;
out_free_line: out_free_line:
free(dl->line); zfree(&dl->line);
out_delete: out_delete:
free(dl); free(dl);
return NULL; return NULL;
@ -591,8 +591,8 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line, size_t privs
void disasm_line__free(struct disasm_line *dl) void disasm_line__free(struct disasm_line *dl)
{ {
free(dl->line); zfree(&dl->line);
free(dl->name); zfree(&dl->name);
if (dl->ins && dl->ins->ops->free) if (dl->ins && dl->ins->ops->free)
dl->ins->ops->free(&dl->ops); dl->ins->ops->free(&dl->ops);
else else

View File

@ -133,7 +133,7 @@ void close_cgroup(struct cgroup_sel *cgrp)
/* XXX: not reentrant */ /* XXX: not reentrant */
if (--cgrp->refcnt == 0) { if (--cgrp->refcnt == 0) {
close(cgrp->fd); close(cgrp->fd);
free(cgrp->name); zfree(&cgrp->name);
free(cgrp); free(cgrp);
} }
} }

View File

@ -21,7 +21,7 @@ static void comm_str__put(struct comm_str *cs)
{ {
if (!--cs->ref) { if (!--cs->ref) {
rb_erase(&cs->rb_node, &comm_str_root); rb_erase(&cs->rb_node, &comm_str_root);
free(cs->str); zfree(&cs->str);
free(cs); free(cs);
} }
} }

View File

@ -208,7 +208,7 @@ struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int
return evsel; return evsel;
out_free: out_free:
free(evsel->name); zfree(&evsel->name);
free(evsel); free(evsel);
return NULL; return NULL;
} }
@ -766,7 +766,7 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
void perf_evsel__free_counts(struct perf_evsel *evsel) void perf_evsel__free_counts(struct perf_evsel *evsel)
{ {
free(evsel->counts); zfree(&evsel->counts);
} }
void perf_evsel__exit(struct perf_evsel *evsel) void perf_evsel__exit(struct perf_evsel *evsel)
@ -780,10 +780,10 @@ void perf_evsel__delete(struct perf_evsel *evsel)
{ {
perf_evsel__exit(evsel); perf_evsel__exit(evsel);
close_cgroup(evsel->cgrp); close_cgroup(evsel->cgrp);
free(evsel->group_name); zfree(&evsel->group_name);
if (evsel->tp_format) if (evsel->tp_format)
pevent_free_format(evsel->tp_format); pevent_free_format(evsel->tp_format);
free(evsel->name); zfree(&evsel->name);
free(evsel); free(evsel);
} }

View File

@ -800,10 +800,10 @@ static void free_cpu_topo(struct cpu_topo *tp)
return; return;
for (i = 0 ; i < tp->core_sib; i++) for (i = 0 ; i < tp->core_sib; i++)
free(tp->core_siblings[i]); zfree(&tp->core_siblings[i]);
for (i = 0 ; i < tp->thread_sib; i++) for (i = 0 ; i < tp->thread_sib; i++)
free(tp->thread_siblings[i]); zfree(&tp->thread_siblings[i]);
free(tp); free(tp);
} }
@ -1232,8 +1232,8 @@ static void free_event_desc(struct perf_evsel *events)
return; return;
for (evsel = events; evsel->attr.size; evsel++) { for (evsel = events; evsel->attr.size; evsel++) {
free(evsel->name); zfree(&evsel->name);
free(evsel->id); zfree(&evsel->id);
} }
free(events); free(events);
@ -2105,7 +2105,7 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused,
ret = 0; ret = 0;
out_free: out_free:
for (i = 0; i < nr_groups; i++) for (i = 0; i < nr_groups; i++)
free(desc[i].name); zfree(&desc[i].name);
free(desc); free(desc);
return ret; return ret;

View File

@ -22,8 +22,8 @@ static void clean_cmdnames(struct cmdnames *cmds)
unsigned int i; unsigned int i;
for (i = 0; i < cmds->cnt; ++i) for (i = 0; i < cmds->cnt; ++i)
free(cmds->names[i]); zfree(&cmds->names[i]);
free(cmds->names); zfree(&cmds->names);
cmds->cnt = 0; cmds->cnt = 0;
cmds->alloc = 0; cmds->alloc = 0;
} }

View File

@ -372,7 +372,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
* This mem info was allocated from machine__resolve_mem * This mem info was allocated from machine__resolve_mem
* and will not be used anymore. * and will not be used anymore.
*/ */
free(entry->mem_info); zfree(&entry->mem_info);
/* If the map of an existing hist_entry has /* If the map of an existing hist_entry has
* become out-of-date due to an exec() or * become out-of-date due to an exec() or
@ -475,8 +475,8 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
void hist_entry__free(struct hist_entry *he) void hist_entry__free(struct hist_entry *he)
{ {
free(he->branch_info); zfree(&he->branch_info);
free(he->mem_info); zfree(&he->mem_info);
free_srcline(he->srcline); free_srcline(he->srcline);
free(he); free(he);
} }

View File

@ -204,7 +204,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
} }
path->name = malloc(MAX_EVENT_LENGTH); path->name = malloc(MAX_EVENT_LENGTH);
if (!path->name) { if (!path->name) {
free(path->system); zfree(&path->system);
free(path); free(path);
return NULL; return NULL;
} }
@ -236,8 +236,8 @@ struct tracepoint_path *tracepoint_name_to_path(const char *name)
path->name = strdup(str+1); path->name = strdup(str+1);
if (path->system == NULL || path->name == NULL) { if (path->system == NULL || path->name == NULL) {
free(path->system); zfree(&path->system);
free(path->name); zfree(&path->name);
free(path); free(path);
path = NULL; path = NULL;
} }
@ -917,7 +917,7 @@ int parse_events_terms(struct list_head *terms, const char *str)
ret = parse_events__scanner(str, &data, PE_START_TERMS); ret = parse_events__scanner(str, &data, PE_START_TERMS);
if (!ret) { if (!ret) {
list_splice(data.terms, terms); list_splice(data.terms, terms);
free(data.terms); zfree(&data.terms);
return 0; return 0;
} }

View File

@ -755,7 +755,7 @@ void print_pmu_events(const char *event_glob, bool name_only)
continue; continue;
} }
printf(" %-50s [Kernel PMU event]\n", aliases[j]); printf(" %-50s [Kernel PMU event]\n", aliases[j]);
free(aliases[j]); zfree(&aliases[j]);
printed++; printed++;
} }
if (printed) if (printed)

View File

@ -356,7 +356,7 @@ static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,
offset = tevs[i].point.address - stext; offset = tevs[i].point.address - stext;
offset += tevs[i].point.offset; offset += tevs[i].point.offset;
tevs[i].point.offset = 0; tevs[i].point.offset = 0;
free(tevs[i].point.symbol); zfree(&tevs[i].point.symbol);
ret = e_snprintf(buf, 32, "0x%lx", offset); ret = e_snprintf(buf, 32, "0x%lx", offset);
if (ret < 0) if (ret < 0)
break; break;
@ -683,7 +683,7 @@ static int show_available_vars_at(struct debuginfo *dinfo,
*/ */
fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol,
vl->point.offset); vl->point.offset);
free(vl->point.symbol); zfree(&vl->point.symbol);
nvars = 0; nvars = 0;
if (vl->vars) { if (vl->vars) {
strlist__for_each(node, vl->vars) { strlist__for_each(node, vl->vars) {
@ -1592,7 +1592,7 @@ void clear_perf_probe_event(struct perf_probe_event *pev)
field = pev->args[i].field; field = pev->args[i].field;
while (field) { while (field) {
next = field->next; next = field->next;
free(field->name); zfree(&field->name);
free(field); free(field);
field = next; field = next;
} }
@ -2153,7 +2153,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
for (i = 0; i < npevs; i++) { for (i = 0; i < npevs; i++) {
for (j = 0; j < pkgs[i].ntevs; j++) for (j = 0; j < pkgs[i].ntevs; j++)
clear_probe_trace_event(&pkgs[i].tevs[j]); clear_probe_trace_event(&pkgs[i].tevs[j]);
free(pkgs[i].tevs); zfree(&pkgs[i].tevs);
} }
free(pkgs); free(pkgs);

View File

@ -1409,7 +1409,7 @@ int debuginfo__find_available_vars_at(struct debuginfo *dbg,
if (ret < 0) { if (ret < 0) {
/* Free vlist for error */ /* Free vlist for error */
while (af.nvls--) { while (af.nvls--) {
free(af.vls[af.nvls].point.symbol); zfree(&af.vls[af.nvls].point.symbol);
strlist__delete(af.vls[af.nvls].vars); strlist__delete(af.vls[af.nvls].vars);
} }
zfree(vls); zfree(vls);

View File

@ -132,18 +132,18 @@ static void perf_session__delete_threads(struct perf_session *session)
static void perf_session_env__delete(struct perf_session_env *env) static void perf_session_env__delete(struct perf_session_env *env)
{ {
free(env->hostname); zfree(&env->hostname);
free(env->os_release); zfree(&env->os_release);
free(env->version); zfree(&env->version);
free(env->arch); zfree(&env->arch);
free(env->cpu_desc); zfree(&env->cpu_desc);
free(env->cpuid); zfree(&env->cpuid);
free(env->cmdline); zfree(&env->cmdline);
free(env->sibling_cores); zfree(&env->sibling_cores);
free(env->sibling_threads); zfree(&env->sibling_threads);
free(env->numa_nodes); zfree(&env->numa_nodes);
free(env->pmu_mappings); zfree(&env->pmu_mappings);
} }
void perf_session__delete(struct perf_session *session) void perf_session__delete(struct perf_session *session)

View File

@ -129,7 +129,7 @@ static struct a2l_data *addr2line_init(const char *path)
out: out:
if (a2l) { if (a2l) {
free((void *)a2l->input); zfree((void **)&a2l->input);
free(a2l); free(a2l);
} }
bfd_close(abfd); bfd_close(abfd);
@ -140,8 +140,8 @@ static void addr2line_cleanup(struct a2l_data *a2l)
{ {
if (a2l->abfd) if (a2l->abfd)
bfd_close(a2l->abfd); bfd_close(a2l->abfd);
free((void *)a2l->input); zfree((void **)&a2l->input);
free(a2l->syms); zfree(&a2l->syms);
free(a2l); free(a2l);
} }

View File

@ -28,7 +28,7 @@ void strbuf_init(struct strbuf *sb, ssize_t hint)
void strbuf_release(struct strbuf *sb) void strbuf_release(struct strbuf *sb)
{ {
if (sb->alloc) { if (sb->alloc) {
free(sb->buf); zfree(&sb->buf);
strbuf_init(sb, 0); strbuf_init(sb, 0);
} }
} }

View File

@ -14,7 +14,7 @@ static void strfilter_node__delete(struct strfilter_node *node)
{ {
if (node) { if (node) {
if (node->p && !is_operator(*node->p)) if (node->p && !is_operator(*node->p))
free((char *)node->p); zfree((char **)&node->p);
strfilter_node__delete(node->l); strfilter_node__delete(node->l);
strfilter_node__delete(node->r); strfilter_node__delete(node->r);
free(node); free(node);

View File

@ -128,7 +128,7 @@ void argv_free(char **argv)
{ {
char **p; char **p;
for (p = argv; *p; p++) for (p = argv; *p; p++)
free(*p); zfree(p);
free(argv); free(argv);
} }

View File

@ -5,6 +5,7 @@
*/ */
#include "strlist.h" #include "strlist.h"
#include "util.h"
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -38,7 +39,7 @@ struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry)
static void str_node__delete(struct str_node *snode, bool dupstr) static void str_node__delete(struct str_node *snode, bool dupstr)
{ {
if (dupstr) if (dupstr)
free((void *)snode->s); zfree((void **)&snode->s);
free(snode); free(snode);
} }

View File

@ -21,6 +21,7 @@
#include "perf.h" #include "perf.h"
#include "svghelper.h" #include "svghelper.h"
#include "util.h"
#include "cpumap.h" #include "cpumap.h"
static u64 first_time, last_time; static u64 first_time, last_time;
@ -708,8 +709,8 @@ int svg_build_topology_map(char *sib_core, int sib_core_nr,
return 0; return 0;
exit: exit:
free(t.sib_core); zfree(&t.sib_core);
free(t.sib_thr); zfree(&t.sib_thr);
return -1; return -1;
} }

View File

@ -554,7 +554,7 @@ bool symsrc__has_symtab(struct symsrc *ss)
void symsrc__destroy(struct symsrc *ss) void symsrc__destroy(struct symsrc *ss)
{ {
free(ss->name); zfree(&ss->name);
elf_end(ss->elf); elf_end(ss->elf);
close(ss->fd); close(ss->fd);
} }

View File

@ -1,4 +1,5 @@
#include "symbol.h" #include "symbol.h"
#include "util.h"
#include <stdio.h> #include <stdio.h>
#include <fcntl.h> #include <fcntl.h>
@ -275,7 +276,7 @@ bool symsrc__has_symtab(struct symsrc *ss __maybe_unused)
void symsrc__destroy(struct symsrc *ss) void symsrc__destroy(struct symsrc *ss)
{ {
free(ss->name); zfree(&ss->name);
close(ss->fd); close(ss->fd);
} }

View File

@ -796,7 +796,7 @@ static void delete_modules(struct rb_root *modules)
mi = rb_entry(next, struct module_info, rb_node); mi = rb_entry(next, struct module_info, rb_node);
next = rb_next(&mi->rb_node); next = rb_next(&mi->rb_node);
rb_erase(&mi->rb_node, modules); rb_erase(&mi->rb_node, modules);
free(mi->name); zfree(&mi->name);
free(mi); free(mi);
} }
} }

View File

@ -41,7 +41,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid)
} }
for (i=0; i<items; i++) for (i=0; i<items; i++)
free(namelist[i]); zfree(&namelist[i]);
free(namelist); free(namelist);
return threads; return threads;
@ -118,7 +118,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
threads->map[threads->nr + i] = atoi(namelist[i]->d_name); threads->map[threads->nr + i] = atoi(namelist[i]->d_name);
for (i = 0; i < items; i++) for (i = 0; i < items; i++)
free(namelist[i]); zfree(&namelist[i]);
free(namelist); free(namelist);
threads->nr += items; threads->nr += items;
@ -135,7 +135,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
out_free_namelist: out_free_namelist:
for (i = 0; i < items; i++) for (i = 0; i < items; i++)
free(namelist[i]); zfree(&namelist[i]);
free(namelist); free(namelist);
out_free_closedir: out_free_closedir:
@ -194,7 +194,7 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
for (i = 0; i < items; i++) { for (i = 0; i < items; i++) {
threads->map[j++] = atoi(namelist[i]->d_name); threads->map[j++] = atoi(namelist[i]->d_name);
free(namelist[i]); zfree(&namelist[i]);
} }
threads->nr = total_tasks; threads->nr = total_tasks;
free(namelist); free(namelist);
@ -206,7 +206,7 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
out_free_namelist: out_free_namelist:
for (i = 0; i < items; i++) for (i = 0; i < items; i++)
free(namelist[i]); zfree(&namelist[i]);
free(namelist); free(namelist);
out_free_threads: out_free_threads:

View File

@ -397,8 +397,8 @@ put_tracepoints_path(struct tracepoint_path *tps)
struct tracepoint_path *t = tps; struct tracepoint_path *t = tps;
tps = tps->next; tps = tps->next;
free(t->name); zfree(&t->name);
free(t->system); zfree(&t->system);
free(t); free(t);
} }
} }

View File

@ -31,14 +31,14 @@ void perf_read_values_destroy(struct perf_read_values *values)
return; return;
for (i = 0; i < values->threads; i++) for (i = 0; i < values->threads; i++)
free(values->value[i]); zfree(&values->value[i]);
free(values->value); zfree(&values->value);
free(values->pid); zfree(&values->pid);
free(values->tid); zfree(&values->tid);
free(values->counterrawid); zfree(&values->counterrawid);
for (i = 0; i < values->counters; i++) for (i = 0; i < values->counters; i++)
free(values->countername[i]); zfree(&values->countername[i]);
free(values->countername); zfree(&values->countername);
} }
static void perf_read_values__enlarge_threads(struct perf_read_values *values) static void perf_read_values__enlarge_threads(struct perf_read_values *values)