ANDROID: fix out-of-bounds error when trace_create_new_event

The global_trace of trace_array is not created with the trace_array_ext
extensions. Add trace_array_get_system_names() function to prevent
access global_trace's system_names.

BUG: KASAN: global-out-of-bounds in trace_create_new_event+0x80/0x35c
Read of size 8 at addr ffffffc081214898 by task insmod/48
Call trace:
 dump_backtrace+0x94/0xec
 show_stack+0x18/0x24
 dump_stack_lvl+0x60/0xac
 print_report+0x1ec/0x5ac
 kasan_report+0xc8/0x110
 __asan_load8+0x9c/0xb8
 trace_create_new_event+0x80/0x35c
 __trace_add_new_event+0x20/0xd8

Bug: 418940629
Bug: 423127606
Fixes: 6af2e78f07 ("ANDROID: fix ABI breakage for trace_array extensions")
Change-Id: Iacf60548d3a08081865761e0fa61da9f87e5c39c
Signed-off-by: Richard Chang <richardycc@google.com>
This commit is contained in:
Richard Chang
2025-06-11 04:11:07 +00:00
parent d9ec0e18f4
commit 4ec55296c6
3 changed files with 13 additions and 4 deletions

View File

@@ -9648,6 +9648,17 @@ out_unlock:
return ret;
}
const char *trace_array_get_system_names(struct trace_array *tr)
{
struct trace_array_ext *tr_ext;
if (tr == &global_trace)
return NULL;
tr_ext = container_of(tr, struct trace_array_ext, trace_array);
return tr_ext->system_names;
}
struct trace_array *trace_array_get_by_name(const char *name)
{
return trace_array_get_by_name_ext(name, NULL);

View File

@@ -425,6 +425,7 @@ extern struct list_head ftrace_trace_arrays;
extern struct mutex trace_types_lock;
extern const char *trace_array_get_system_names(struct trace_array *tr);
extern int trace_array_get(struct trace_array *tr);
extern int tracing_check_open_get_tr(struct trace_array *tr);
extern struct trace_array *trace_array_find(const char *instance);

View File

@@ -3070,11 +3070,8 @@ trace_create_new_event(struct trace_event_call *call,
struct trace_pid_list *pid_list;
struct trace_event_file *file;
unsigned int first;
struct trace_array_ext *tr_ext = container_of(tr,
struct trace_array_ext,
trace_array);
if (!event_in_systems(call, tr_ext->system_names))
if (!event_in_systems(call, trace_array_get_system_names(tr)))
return NULL;
file = kmem_cache_alloc(file_cachep, GFP_TRACE);