forked from Minki/linux
perf tools: Use list_del_init() more thorougly
To allow for destructors to check if they're operating on a object still in a list, and to avoid going from use after free list entries into still valid, or even also other already removed from list entries. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Link: https://lkml.kernel.org/n/tip-deh17ub44atyox3j90e6rksu@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
d8f9da2404
commit
e56fbc9dc7
@ -431,7 +431,7 @@ static void delete_filter_func(struct list_head *head)
|
||||
struct filter_entry *pos, *tmp;
|
||||
|
||||
list_for_each_entry_safe(pos, tmp, head, list) {
|
||||
list_del(&pos->list);
|
||||
list_del_init(&pos->list);
|
||||
free(pos);
|
||||
}
|
||||
}
|
||||
|
@ -454,7 +454,7 @@ broken:
|
||||
/* broken lock sequence, discard it */
|
||||
ls->discard = 1;
|
||||
bad_hist[BROKEN_ACQUIRE]++;
|
||||
list_del(&seq->list);
|
||||
list_del_init(&seq->list);
|
||||
free(seq);
|
||||
goto end;
|
||||
default:
|
||||
@ -515,7 +515,7 @@ static int report_lock_acquired_event(struct perf_evsel *evsel,
|
||||
/* broken lock sequence, discard it */
|
||||
ls->discard = 1;
|
||||
bad_hist[BROKEN_ACQUIRED]++;
|
||||
list_del(&seq->list);
|
||||
list_del_init(&seq->list);
|
||||
free(seq);
|
||||
goto end;
|
||||
default:
|
||||
@ -570,7 +570,7 @@ static int report_lock_contended_event(struct perf_evsel *evsel,
|
||||
/* broken lock sequence, discard it */
|
||||
ls->discard = 1;
|
||||
bad_hist[BROKEN_CONTENDED]++;
|
||||
list_del(&seq->list);
|
||||
list_del_init(&seq->list);
|
||||
free(seq);
|
||||
goto end;
|
||||
default:
|
||||
@ -639,7 +639,7 @@ static int report_lock_release_event(struct perf_evsel *evsel,
|
||||
|
||||
ls->nr_release++;
|
||||
free_seq:
|
||||
list_del(&seq->list);
|
||||
list_del_init(&seq->list);
|
||||
free(seq);
|
||||
end:
|
||||
return 0;
|
||||
|
@ -407,7 +407,7 @@ static void free_arch_std_events(void)
|
||||
|
||||
list_for_each_entry_safe(es, next, &arch_std_events, list) {
|
||||
FOR_ALL_EVENT_STRUCT_FIELDS(FREE_EVENT_FIELD);
|
||||
list_del(&es->list);
|
||||
list_del_init(&es->list);
|
||||
free(es);
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ static void free_event_nodes(struct list_head *events)
|
||||
|
||||
while (!list_empty(events)) {
|
||||
node = list_entry(events->next, struct event_node, list);
|
||||
list_del(&node->list);
|
||||
list_del_init(&node->list);
|
||||
free(node);
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
|
||||
gtk_container_add(GTK_CONTAINER(window), view);
|
||||
|
||||
list_for_each_entry_safe(pos, n, ¬es->src->source, al.node) {
|
||||
list_del(&pos->al.node);
|
||||
list_del_init(&pos->al.node);
|
||||
disasm_line__free(pos);
|
||||
}
|
||||
|
||||
|
@ -1586,7 +1586,7 @@ static void delete_last_nop(struct symbol *sym)
|
||||
return;
|
||||
}
|
||||
|
||||
list_del(&dl->al.node);
|
||||
list_del_init(&dl->al.node);
|
||||
disasm_line__free(dl);
|
||||
}
|
||||
}
|
||||
@ -2463,7 +2463,7 @@ void annotated_source__purge(struct annotated_source *as)
|
||||
struct annotation_line *al, *n;
|
||||
|
||||
list_for_each_entry_safe(al, n, &as->source, node) {
|
||||
list_del(&al->node);
|
||||
list_del_init(&al->node);
|
||||
disasm_line__free(disasm_line(al));
|
||||
}
|
||||
}
|
||||
|
@ -408,7 +408,7 @@ void auxtrace_queues__free(struct auxtrace_queues *queues)
|
||||
|
||||
buffer = list_entry(queues->queue_array[i].head.next,
|
||||
struct auxtrace_buffer, list);
|
||||
list_del(&buffer->list);
|
||||
list_del_init(&buffer->list);
|
||||
auxtrace_buffer__free(buffer);
|
||||
}
|
||||
}
|
||||
@ -612,7 +612,7 @@ void auxtrace_index__free(struct list_head *head)
|
||||
struct auxtrace_index *auxtrace_index, *n;
|
||||
|
||||
list_for_each_entry_safe(auxtrace_index, n, head, list) {
|
||||
list_del(&auxtrace_index->list);
|
||||
list_del_init(&auxtrace_index->list);
|
||||
free(auxtrace_index);
|
||||
}
|
||||
}
|
||||
|
@ -829,7 +829,7 @@ static void
|
||||
bpf_map_op__delete(struct bpf_map_op *op)
|
||||
{
|
||||
if (!list_empty(&op->list))
|
||||
list_del(&op->list);
|
||||
list_del_init(&op->list);
|
||||
if (op->key_type == BPF_MAP_KEY_RANGES)
|
||||
parse_events__clear_array(&op->k.array);
|
||||
free(op);
|
||||
|
@ -40,7 +40,7 @@ void call_path_root__free(struct call_path_root *cpr)
|
||||
struct call_path_block *pos, *n;
|
||||
|
||||
list_for_each_entry_safe(pos, n, &cpr->blocks, node) {
|
||||
list_del(&pos->node);
|
||||
list_del_init(&pos->node);
|
||||
free(pos);
|
||||
}
|
||||
free(cpr);
|
||||
|
@ -636,7 +636,7 @@ add_child(struct callchain_node *parent,
|
||||
struct callchain_list *call, *tmp;
|
||||
|
||||
list_for_each_entry_safe(call, tmp, &new->val, list) {
|
||||
list_del(&call->list);
|
||||
list_del_init(&call->list);
|
||||
map__zput(call->ms.map);
|
||||
free(call);
|
||||
}
|
||||
@ -1002,7 +1002,7 @@ merge_chain_branch(struct callchain_cursor *cursor,
|
||||
callchain_cursor_append(cursor, list->ip,
|
||||
list->ms.map, list->ms.sym,
|
||||
false, NULL, 0, 0, 0, list->srcline);
|
||||
list_del(&list->list);
|
||||
list_del_init(&list->list);
|
||||
map__zput(list->ms.map);
|
||||
free(list);
|
||||
}
|
||||
@ -1453,13 +1453,13 @@ static void free_callchain_node(struct callchain_node *node)
|
||||
struct rb_node *n;
|
||||
|
||||
list_for_each_entry_safe(list, tmp, &node->parent_val, list) {
|
||||
list_del(&list->list);
|
||||
list_del_init(&list->list);
|
||||
map__zput(list->ms.map);
|
||||
free(list);
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(list, tmp, &node->val, list) {
|
||||
list_del(&list->list);
|
||||
list_del_init(&list->list);
|
||||
map__zput(list->ms.map);
|
||||
free(list);
|
||||
}
|
||||
@ -1544,7 +1544,7 @@ int callchain_node__make_parent_list(struct callchain_node *node)
|
||||
|
||||
out:
|
||||
list_for_each_entry_safe(chain, new, &head, list) {
|
||||
list_del(&chain->list);
|
||||
list_del_init(&chain->list);
|
||||
map__zput(chain->ms.map);
|
||||
free(chain);
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ static int db_export__deferred(struct db_export *dbe)
|
||||
de = list_entry(dbe->deferred.next, struct deferred_export,
|
||||
node);
|
||||
err = dbe->export_comm(dbe, de->comm);
|
||||
list_del(&de->node);
|
||||
list_del_init(&de->node);
|
||||
free(de);
|
||||
if (err)
|
||||
return err;
|
||||
@ -50,7 +50,7 @@ static void db_export__free_deferred(struct db_export *dbe)
|
||||
while (!list_empty(&dbe->deferred)) {
|
||||
de = list_entry(dbe->deferred.next, struct deferred_export,
|
||||
node);
|
||||
list_del(&de->node);
|
||||
list_del_init(&de->node);
|
||||
free(de);
|
||||
}
|
||||
}
|
||||
|
@ -434,7 +434,7 @@ static void dso__list_add(struct dso *dso)
|
||||
|
||||
static void dso__list_del(struct dso *dso)
|
||||
{
|
||||
list_del(&dso->data.open_entry);
|
||||
list_del_init(&dso->data.open_entry);
|
||||
WARN_ONCE(dso__data_open_cnt <= 0,
|
||||
"DSO data fd counter out of bounds.");
|
||||
dso__data_open_cnt--;
|
||||
|
@ -1298,7 +1298,7 @@ static void perf_evsel__free_config_terms(struct perf_evsel *evsel)
|
||||
struct perf_evsel_config_term *term, *h;
|
||||
|
||||
list_for_each_entry_safe(term, h, &evsel->config_terms, list) {
|
||||
list_del(&term->list);
|
||||
list_del_init(&term->list);
|
||||
free(term);
|
||||
}
|
||||
}
|
||||
|
@ -2741,10 +2741,10 @@ static void hists_evsel__exit(struct perf_evsel *evsel)
|
||||
|
||||
list_for_each_entry_safe(node, tmp, &hists->hpp_formats, list) {
|
||||
perf_hpp_list__for_each_format_safe(&node->hpp, fmt, pos) {
|
||||
list_del(&fmt->list);
|
||||
list_del_init(&fmt->list);
|
||||
free(fmt);
|
||||
}
|
||||
list_del(&node->list);
|
||||
list_del_init(&node->list);
|
||||
free(node);
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ static struct ordered_event *alloc_event(struct ordered_events *oe,
|
||||
|
||||
if (!list_empty(cache)) {
|
||||
new = list_entry(cache->next, struct ordered_event, list);
|
||||
list_del(&new->list);
|
||||
list_del_init(&new->list);
|
||||
} else if (oe->buffer) {
|
||||
new = &oe->buffer->event[oe->buffer_idx];
|
||||
if (++oe->buffer_idx == MAX_SAMPLE_BUFFER)
|
||||
@ -394,13 +394,13 @@ void ordered_events__free(struct ordered_events *oe)
|
||||
* yet, we need to free only allocated ones ...
|
||||
*/
|
||||
if (oe->buffer) {
|
||||
list_del(&oe->buffer->list);
|
||||
list_del_init(&oe->buffer->list);
|
||||
ordered_events_buffer__free(oe->buffer, oe->buffer_idx, oe);
|
||||
}
|
||||
|
||||
/* ... and continue with the rest */
|
||||
list_for_each_entry_safe(buffer, tmp, &oe->to_free, list) {
|
||||
list_del(&buffer->list);
|
||||
list_del_init(&buffer->list);
|
||||
ordered_events_buffer__free(buffer, MAX_SAMPLE_BUFFER, oe);
|
||||
}
|
||||
}
|
||||
|
@ -652,7 +652,7 @@ static int add_bpf_event(const char *group, const char *event, int fd,
|
||||
pr_debug("Failed to add BPF event %s:%s\n",
|
||||
group, event);
|
||||
list_for_each_entry_safe(evsel, tmp, &new_evsels, node) {
|
||||
list_del(&evsel->node);
|
||||
list_del_init(&evsel->node);
|
||||
perf_evsel__delete(evsel);
|
||||
}
|
||||
return err;
|
||||
|
@ -1245,7 +1245,7 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms,
|
||||
info->metric_expr = alias->metric_expr;
|
||||
info->metric_name = alias->metric_name;
|
||||
|
||||
list_del(&term->list);
|
||||
list_del_init(&term->list);
|
||||
free(term);
|
||||
}
|
||||
|
||||
|
@ -2333,7 +2333,7 @@ static void kprobe_blacklist__delete(struct list_head *blacklist)
|
||||
while (!list_empty(blacklist)) {
|
||||
node = list_first_entry(blacklist,
|
||||
struct kprobe_blacklist_node, list);
|
||||
list_del(&node->list);
|
||||
list_del_init(&node->list);
|
||||
zfree(&node->symbol);
|
||||
free(node);
|
||||
}
|
||||
|
@ -756,7 +756,7 @@ static int s390_cpumsf_run_decoder(struct s390_cpumsf_queue *sfq,
|
||||
*/
|
||||
if (err) {
|
||||
sfq->buffer = NULL;
|
||||
list_del(&buffer->list);
|
||||
list_del_init(&buffer->list);
|
||||
auxtrace_buffer__free(buffer);
|
||||
if (err > 0) /* Buffer done, no error */
|
||||
err = 0;
|
||||
|
@ -83,7 +83,7 @@ static void fill_lines(char **lines, int maxline, char *map, int maplen)
|
||||
|
||||
static void free_srcfile(struct srcfile *sf)
|
||||
{
|
||||
list_del(&sf->nd);
|
||||
list_del_init(&sf->nd);
|
||||
hlist_del(&sf->hash_nd);
|
||||
map_total_sz -= sf->maplen;
|
||||
munmap(sf->map, sf->maplen);
|
||||
|
@ -1478,7 +1478,7 @@ static void kcore_copy__free_phdrs(struct kcore_copy_info *kci)
|
||||
struct phdr_data *p, *tmp;
|
||||
|
||||
list_for_each_entry_safe(p, tmp, &kci->phdrs, node) {
|
||||
list_del(&p->node);
|
||||
list_del_init(&p->node);
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
@ -1501,7 +1501,7 @@ static void kcore_copy__free_syms(struct kcore_copy_info *kci)
|
||||
struct sym_data *s, *tmp;
|
||||
|
||||
list_for_each_entry_safe(s, tmp, &kci->syms, node) {
|
||||
list_del(&s->node);
|
||||
list_del_init(&s->node);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
@ -2252,7 +2252,7 @@ int cleanup_sdt_note_list(struct list_head *sdt_notes)
|
||||
int nr_free = 0;
|
||||
|
||||
list_for_each_entry_safe(pos, tmp, sdt_notes, note_list) {
|
||||
list_del(&pos->note_list);
|
||||
list_del_init(&pos->note_list);
|
||||
zfree(&pos->name);
|
||||
zfree(&pos->provider);
|
||||
free(pos);
|
||||
|
@ -93,14 +93,14 @@ void thread__delete(struct thread *thread)
|
||||
down_write(&thread->namespaces_lock);
|
||||
list_for_each_entry_safe(namespaces, tmp_namespaces,
|
||||
&thread->namespaces_list, list) {
|
||||
list_del(&namespaces->list);
|
||||
list_del_init(&namespaces->list);
|
||||
namespaces__free(namespaces);
|
||||
}
|
||||
up_write(&thread->namespaces_lock);
|
||||
|
||||
down_write(&thread->comm_lock);
|
||||
list_for_each_entry_safe(comm, tmp_comm, &thread->comm_list, list) {
|
||||
list_del(&comm->list);
|
||||
list_del_init(&comm->list);
|
||||
comm__free(comm);
|
||||
}
|
||||
up_write(&thread->comm_lock);
|
||||
|
Loading…
Reference in New Issue
Block a user