From cf372342bd064951411ff03c03ab9b241354c48b Mon Sep 17 00:00:00 2001 From: Ksawlii Date: Sun, 24 Nov 2024 00:23:31 +0100 Subject: [PATCH] Revert "ftrace: Fix possible use-after-free issue in ftrace_location()" This reverts commit 2c12c9f7ef34e0ff520387f70736ee71034beac3. --- kernel/trace/ftrace.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 36182e7e0..a781733b2 100755 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -1566,15 +1566,12 @@ static struct dyn_ftrace *lookup_rec(unsigned long start, unsigned long end) unsigned long ftrace_location_range(unsigned long start, unsigned long end) { struct dyn_ftrace *rec; - unsigned long ip = 0; - rcu_read_lock(); rec = lookup_rec(start, end); if (rec) - ip = rec->ip; - rcu_read_unlock(); + return rec->ip; - return ip; + return 0; } /** @@ -1587,22 +1584,25 @@ unsigned long ftrace_location_range(unsigned long start, unsigned long end) */ unsigned long ftrace_location(unsigned long ip) { - unsigned long loc; + struct dyn_ftrace *rec; unsigned long offset; unsigned long size; - loc = ftrace_location_range(ip, ip); - if (!loc) { + rec = lookup_rec(ip, ip); + if (!rec) { if (!kallsyms_lookup_size_offset(ip, &size, &offset)) goto out; /* map sym+0 to __fentry__ */ if (!offset) - loc = ftrace_location_range(ip, ip + size - 1); + rec = lookup_rec(ip, ip + size - 1); } + if (rec) + return rec->ip; + out: - return loc; + return 0; } /** @@ -6331,8 +6331,6 @@ static int ftrace_process_locs(struct module *mod, /* We should have used all pages unless we skipped some */ if (pg_unuse) { WARN_ON(!skipped); - /* Need to synchronize with ftrace_location_range() */ - synchronize_rcu(); ftrace_free_pages(pg_unuse); } return ret; @@ -6515,9 +6513,6 @@ void ftrace_release_mod(struct module *mod) out_unlock: mutex_unlock(&ftrace_lock); - /* Need to synchronize with ftrace_location_range() */ - if (tmp_page) - synchronize_rcu(); for (pg = tmp_page; pg; pg = tmp_page) { /* Needs to be called outside of ftrace_lock */ @@ -6840,7 +6835,6 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) unsigned long start = (unsigned long)(start_ptr); unsigned long end = (unsigned long)(end_ptr); struct ftrace_page **last_pg = &ftrace_pages_start; - struct ftrace_page *tmp_page = NULL; struct ftrace_page *pg; struct dyn_ftrace *rec; struct dyn_ftrace key; @@ -6884,8 +6878,12 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) ftrace_update_tot_cnt--; if (!pg->index) { *last_pg = pg->next; - pg->next = tmp_page; - tmp_page = pg; + if (pg->records) { + free_pages((unsigned long)pg->records, pg->order); + ftrace_number_of_pages -= 1 << pg->order; + } + ftrace_number_of_groups--; + kfree(pg); pg = container_of(last_pg, struct ftrace_page, next); if (!(*last_pg)) ftrace_pages = pg; @@ -6902,11 +6900,6 @@ void ftrace_free_mem(struct module *mod, void *start_ptr, void *end_ptr) clear_func_from_hashes(func); kfree(func); } - /* Need to synchronize with ftrace_location_range() */ - if (tmp_page) { - synchronize_rcu(); - ftrace_free_pages(tmp_page); - } } void __init ftrace_free_init_mem(void)