tracing: More fixes for 7.0
Subsystems (2)
cover tracing: More fixes for 7.0
tracing fixes for 7.0:
- Fix possible NULL pointer dereference in trace_data_alloc()
On the error path in trace_data_alloc(), it can call trigger_data_free() with a NULL pointer. This use to be a kfree() but was changed to trigger_data_free() to clean up any partial initialization. The issue is that trigger_data_free() does not expect a NULL pointer. Have trigger_data_free() return safely on NULL pointer.
- Fix multiple events on the command line and bootconfig
If multiple events are enabled on the command line separately and not grouped, only the last event gets enabled. That is:
trace_event=sched_switch trace_event=sched_waking
Will only enable sched_waking where as:
trace_event=sched_switch,sched_waking
Will enable both.
The bootconfig makes it even worse as the second way is the more common method.
The issue is that a temporary buffer is used to store the events to enable later in boot. Each time the cmdline callback is called, it overwrites what was previously there.
Have the callback append the next value (delimited by a comma) if the temporary buffer already has content.
- Fix command line trace_buffer_size if >= 2G
The logic to allocate the trace buffer uses "int" for the size parameter in the command line code causing overflow issues if more that 2G is specified.
git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
trace/fixes
Head SHA1: d008ba8be8984760e36d7dcd4adbd5a41a645708
Andrei-Alexandru Tachici (1):
tracing: Fix enabling multiple events on the kernel command line and bootconfig
Calvin Owens (1):
tracing: Fix trace_buf_size= cmdline parameter with sizes >= 2G
Guenter Roeck (1):
tracing: Add NULL pointer check to trigger_data_free()
----
kernel/trace/trace.c | 6 +++--- kernel/trace/trace_events.c | 6 +++++- kernel/trace/trace_events_trigger.c | 3 +++ 3 files changed, 11 insertions(+), 4 deletions(-)
PATCH 1/3 tracing: Add NULL pointer check to trigger_data_free()
From: Guenter Roeck <[email protected]>
If trigger_data_alloc() fails and returns NULL, event_hist_trigger_parse() jumps to the out_free error path. While kfree() safely handles a NULL pointer, trigger_data_free() does not. This causes a NULL pointer dereference in trigger_data_free() when evaluating data->cmd_ops->set_filter.
Fix the problem by adding a NULL pointer check to trigger_data_free().
The problem was found by an experimental code review agent based on gemini-3.1-pro while reviewing backports into v6.18.y.
--- kernel/trace/trace_events_trigger.c | 3 +++ 1 file changed, 3 insertions(+)
kernel/trace/trace_events_trigger.c +3 -0
@@ -50,6 +50,9 @@ static int trigger_kthread_fn(void *ignore)void trigger_data_free (struct event_trigger_data *data) { +if (!data) +return ; +if (data->cmd_ops->set_filter) data->cmd_ops->set_filter (NULL , data,NULL );
Signature · 1 line
2.51.0
PATCH 2/3 tracing: Fix enabling multiple events on the kernel command line and bootconfig
In reply to Steven RostedtFrom: Andrei-Alexandru Tachici <[email protected]>
Multiple events can be enabled on the kernel command line via a comma separator. But if the are specified one at a time, then only the last event is enabled. This is because the event names are saved in a temporary buffer, and each call by the init cmdline code will reset that buffer.
This also affects names in the boot config file, as it may call the callback multiple times with an example of:
kernel.trace_event = ":mod:rproc_qcom_common", ":mod:qrtr", ":mod:qcom_aoss"
Change the cmdline callback function to append a comma and the next value if the temporary buffer already has content.
--- kernel/trace/trace_events.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/trace/trace_events.c +5 -1
@@ -4493,7 +4493,11 @@ static char bootup_event_buf[COMMAND_LINE_SIZE] __initdata;static __init int setup_trace_event (char *str) { -strscpy (bootup_event_buf, str,COMMAND_LINE_SIZE ); +if (bootup_event_buf[0 ] !='\0' ) +strlcat (bootup_event_buf,"," ,COMMAND_LINE_SIZE ); + +strlcat (bootup_event_buf, str,COMMAND_LINE_SIZE ); +trace_set_ring_buffer_expanded (NULL );disable_tracing_selftest ("running event tracing" );
Signature · 1 line
2.51.0
PATCH 3/3 tracing: Fix trace_buf_size= cmdline parameter with sizes >= 2G
In reply to Steven RostedtFrom: Calvin Owens <[email protected]>
Some of the sizing logic through tracer_alloc_buffers() uses int internally, causing unexpected behavior if the user passes a value that does not fit in an int (on my x86 machine, the result is uselessly tiny buffers).
Fix by plumbing the parameter's real type (unsigned long) through to the ring buffer allocation functions, which already use unsigned long.
It has always been possible to create larger ring buffers via the sysfs
interface: this only affects the cmdline parameter.
--- kernel/trace/trace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/trace/trace.c +3 -3
@@ -9350,7 +9350,7 @@ static void setup_trace_scratch(struct trace_array *tr, }static int -allocate_trace_buffer (struct trace_array *tr,struct array_buffer *buf,int size) +allocate_trace_buffer (struct trace_array *tr,struct array_buffer *buf,unsigned long size) {enum ring_buffer_flags rb_flags;struct trace_scratch *tscratch;
@@ -9405,7 +9405,7 @@ static void free_trace_buffer(struct array_buffer *buf) } } -static int allocate_trace_buffers (struct trace_array *tr,int size) +static int allocate_trace_buffers (struct trace_array *tr,unsigned long size) {int ret;
@@ -10769,7 +10769,7 @@ __init static void enable_instances(void)__init static int tracer_alloc_buffers (void ) { -int ring_buf_size; +unsigned long ring_buf_size;int ret = -ENOMEM ;
Signature · 1 line
2.51.0