Merge tag 'trace-v6.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull tracing fixes from Steven Rostedt:

- Fix a crash with passing a stacktrace between synthetic events

A synthetic event is an event that combines two events into a single
event that can display fields from both events as well as the time
delta that took place between the events. It can also pass a
stacktrace from the first event so that it can be displayed by the
synthetic event (this is useful to get a stacktrace of a task
scheduling out when blocked and recording the time it was blocked
for).

A synthetic event can also connect an existing synthetic event to
another event. An issue was found that if the first synthetic event
had a stacktrace as one of its fields, and that stacktrace field was
passed to the new synthetic event to be displayed, it would crash the
kernel. This was due to the stacktrace not being saved as a
stacktrace but was still marked as one. When the stacktrace was read,
it would try to read an array but instead read the integer metadata
of the stacktrace and dereferenced a bad value.

Fix this by saving the stacktrace field as a stacktrace.

- Fix possible overflow in cmp_mod_entry() compare function

A binary search is used to find a module address and if the addresses
are greater than 2GB apart it could lead to truncation and cause a
bad search result. Use normal compares instead of a subtraction
between addresses to calculate the compare value.

- Fix output of entry arguments in function graph tracer

Depending on the configurations enabled, the entry can be two
different types that hold the argument array. The macro
FGRAPH_ENTRY_ARGS() is used to find the correct arguments from the
given type. One location was missed and still referenced the
arguments directly via entry->args and could produce the wrong value
depending on how the kernel was configured.

- Fix memory leak in scripts/tracepoint-update build tool

If the array fails to allocate, the memory for the values needs to be
freed and was not. Free the allocated values if the array failed to
allocate.

* tag 'trace-v6.19-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
scripts/tracepoint-update: Fix memory leak in add_string() on failure
function_graph: Fix args pointer mismatch in print_graph_retval()
tracing: Avoid possible signed 64-bit truncation
tracing: Fix crash on synthetic stacktrace field usage

+23 -6
+4 -4
kernel/trace/trace.c
··· 6115 6115 unsigned long addr = (unsigned long)key; 6116 6116 const struct trace_mod_entry *ent = pivot; 6117 6117 6118 - if (addr >= ent[0].mod_addr && addr < ent[1].mod_addr) 6119 - return 0; 6120 - else 6121 - return addr - ent->mod_addr; 6118 + if (addr < ent[0].mod_addr) 6119 + return -1; 6120 + 6121 + return addr >= ent[1].mod_addr; 6122 6122 } 6123 6123 6124 6124 /**
+9
kernel/trace/trace_events_hist.c
··· 2057 2057 hist_field->fn_num = HIST_FIELD_FN_RELDYNSTRING; 2058 2058 else 2059 2059 hist_field->fn_num = HIST_FIELD_FN_PSTRING; 2060 + } else if (field->filter_type == FILTER_STACKTRACE) { 2061 + flags |= HIST_FIELD_FL_STACKTRACE; 2062 + 2063 + hist_field->size = MAX_FILTER_STR_VAL; 2064 + hist_field->type = kstrdup_const(field->type, GFP_KERNEL); 2065 + if (!hist_field->type) 2066 + goto free; 2067 + 2068 + hist_field->fn_num = HIST_FIELD_FN_STACK; 2060 2069 } else { 2061 2070 hist_field->size = field->size; 2062 2071 hist_field->is_signed = field->is_signed;
+7 -1
kernel/trace/trace_events_synth.c
··· 130 130 struct synth_event *event = call->data; 131 131 unsigned int i, size, n_u64; 132 132 char *name, *type; 133 + int filter_type; 133 134 bool is_signed; 135 + bool is_stack; 134 136 int ret = 0; 135 137 136 138 for (i = 0, n_u64 = 0; i < event->n_fields; i++) { ··· 140 138 is_signed = event->fields[i]->is_signed; 141 139 type = event->fields[i]->type; 142 140 name = event->fields[i]->name; 141 + is_stack = event->fields[i]->is_stack; 142 + 143 + filter_type = is_stack ? FILTER_STACKTRACE : FILTER_OTHER; 144 + 143 145 ret = trace_define_field(call, type, name, offset, size, 144 - is_signed, FILTER_OTHER); 146 + is_signed, filter_type); 145 147 if (ret) 146 148 break; 147 149
+1 -1
kernel/trace/trace_functions_graph.c
··· 901 901 trace_seq_printf(s, "%ps", func); 902 902 903 903 if (args_size >= FTRACE_REGS_MAX_ARGS * sizeof(long)) { 904 - print_function_args(s, entry->args, (unsigned long)func); 904 + print_function_args(s, FGRAPH_ENTRY_ARGS(entry), (unsigned long)func); 905 905 trace_seq_putc(s, ';'); 906 906 } else 907 907 trace_seq_puts(s, "();");
+2
scripts/tracepoint-update.c
··· 49 49 array = realloc(array, sizeof(char *) * size); 50 50 if (!array) { 51 51 fprintf(stderr, "Failed memory allocation\n"); 52 + free(*vals); 53 + *vals = NULL; 52 54 return -1; 53 55 } 54 56 *vals = array;