diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/btf.c | 4 | ||||
| -rw-r--r-- | kernel/trace/preemptirq_delay_test.c | 9 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 4 | ||||
| -rw-r--r-- | kernel/trace/trace_events.c | 139 | ||||
| -rw-r--r-- | kernel/trace/trace_events_hist.c | 96 | ||||
| -rw-r--r-- | kernel/trace/trace_events_trigger.c | 16 | ||||
| -rw-r--r-- | kernel/trace/trace_events_user.c | 10 | ||||
| -rw-r--r-- | kernel/trace/trace_functions_graph.c | 2 | ||||
| -rw-r--r-- | kernel/trace/trace_mmiotrace.c | 7 | ||||
| -rw-r--r-- | kernel/trace/trace_printk.c | 3 | ||||
| -rw-r--r-- | kernel/trace/trace_sched_switch.c | 6 | ||||
| -rw-r--r-- | kernel/trace/trace_syscalls.c | 18 |
13 files changed, 241 insertions, 75 deletions
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 7e25051dc1ea..f56437e626c9 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -6467,7 +6467,7 @@ err_out: * split BTF ids will need to be mapped to actual base/split ids for * BTF now that it has been relocated. */ -static __u32 btf_relocate_id(const struct btf *btf, __u32 id) +__u32 btf_relocate_id(const struct btf *btf, __u32 id) { if (!btf->base_btf || !btf->base_id_map) return id; @@ -8623,7 +8623,7 @@ struct module *btf_try_get_module(const struct btf *btf) /* Returns struct btf corresponding to the struct module. * This function can return NULL or ERR_PTR. */ -static struct btf *btf_get_module_btf(const struct module *module) +struct btf *btf_get_module_btf(const struct module *module) { #ifdef CONFIG_DEBUG_INFO_BTF_MODULES struct btf_module *btf_mod, *tmp; diff --git a/kernel/trace/preemptirq_delay_test.c b/kernel/trace/preemptirq_delay_test.c index acb0c971a408..69e5238737ed 100644 --- a/kernel/trace/preemptirq_delay_test.c +++ b/kernel/trace/preemptirq_delay_test.c @@ -6,6 +6,7 @@ */ #include <linux/trace_clock.h> +#include <linux/cpumask.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/irq.h> @@ -123,6 +124,13 @@ static int preemptirq_delay_run(void *data) return -ENOMEM; if (cpu_affinity > -1) { + unsigned int cpu = cpu_affinity; + + if (cpu >= nr_cpu_ids || !cpu_possible(cpu)) { + pr_err("cpu_affinity:%d, invalid CPU\n", cpu_affinity); + goto out; + } + cpumask_clear(cpu_mask); cpumask_set_cpu(cpu_affinity, cpu_mask); if (set_cpus_allowed_ptr(current, cpu_mask)) @@ -132,6 +140,7 @@ static int preemptirq_delay_run(void *data) for (i = 0; i < s; i++) (testfuncs[i])(i); +out: complete(&done); set_current_state(TASK_INTERRUPTIBLE); diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 395238b2b715..89dc1c0ebb90 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4669,7 +4669,7 @@ trace_event_update_with_eval_map(struct module *mod, map = start; - trace_event_update_all(map, len); + trace_event_update_all(map, len, mod); if (len <= 0) return; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index bf77331f56a4..74a7a50d1e78 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -2285,13 +2285,13 @@ static inline const char *get_syscall_name(int syscall) #ifdef CONFIG_EVENT_TRACING void trace_event_init(void); -void trace_event_update_all(struct trace_eval_map **map, int len); +void trace_event_update_all(struct trace_eval_map **map, int len, struct module *mod); /* Used from boot time tracer */ extern int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set); extern int trigger_process_regex(struct trace_event_file *file, char *buff); #else static inline void __init trace_event_init(void) { } -static inline void trace_event_update_all(struct trace_eval_map **map, int len) { } +static inline void trace_event_update_all(struct trace_eval_map **map, int len, struct module *mod) { } #endif #ifdef CONFIG_TRACER_SNAPSHOT diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 3650d84d4f16..7ce862c92a85 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -14,6 +14,7 @@ #include <linux/workqueue.h> #include <linux/security.h> #include <linux/spinlock.h> +#include <linux/seq_buf.h> #include <linux/kthread.h> #include <linux/tracefs.h> #include <linux/uaccess.h> @@ -22,6 +23,7 @@ #include <linux/sort.h> #include <linux/slab.h> #include <linux/delay.h> +#include <linux/btf.h> #include <trace/events/sched.h> #include <trace/syscall.h> @@ -400,6 +402,33 @@ static bool process_string(const char *fmt, int len, struct trace_event_call *ca return true; } +static void test_double_dereference(const char *str, int len, + struct trace_event_call *call) +{ + const char *ptr; + const char *end = str + len; + + ptr = strstr(str, "REC->"); + + while (ptr && ptr < end) { + + ptr += 5; + for (; ptr < end; ptr++) { + if (ptr[0] == '-' && ptr[1] == '>') { + pr_warn("TRACE EVENT ERROR: Event %s has double dereference in TP_printk: %.*s\n", + trace_event_name(call), len, str); + WARN_ONCE(1, "Event %s has double dereference in TP_printk: %.*s\n", + trace_event_name(call), len, str); + return; + } + if (!isalnum(*ptr) && *ptr != '_') + break; + } + + ptr = strstr(ptr, "REC->"); + } +} + static void handle_dereference_arg(const char *arg_str, u64 string_flags, int len, u64 *dereference_flags, int arg, struct trace_event_call *call) @@ -459,12 +488,6 @@ static void test_event_printk(struct trace_event_call *call) if (in_quote) { arg = 0; first = false; - /* - * If there was no %p* uses - * the fmt is OK. - */ - if (!dereference_flags) - return; } } if (in_quote) { @@ -576,6 +599,8 @@ static void test_event_printk(struct trace_event_call *call) continue; } + test_double_dereference(fmt + start_arg, e - start_arg, call); + if (dereference_flags & (1ULL << arg)) { handle_dereference_arg(fmt + start_arg, string_flags, e - start_arg, @@ -589,6 +614,8 @@ static void test_event_printk(struct trace_event_call *call) } } + test_double_dereference(fmt + start_arg, i - start_arg, call); + if (dereference_flags & (1ULL << arg)) { handle_dereference_arg(fmt + start_arg, string_flags, i - start_arg, @@ -2202,6 +2229,61 @@ event_id_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) } #endif +#ifdef CONFIG_BPF_EVENTS +static ssize_t +event_btf_ids_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) +{ + struct trace_event_file *file; + struct trace_event_call *call; + const struct btf_type *t; + struct module *mod = NULL; + u32 raw_id = 0, tp_id = 0, obj_id = 0; + const u32 *ids; + struct btf *btf; + char buf[128]; + int len; + + /* Module unload could free call->class and ids[] mid-read. */ + scoped_guard(mutex, &event_mutex) { + file = event_file_file(filp); + if (!file) + return -ENODEV; + + call = file->event_call; + ids = call->class->btf_ids; + if (!ids) + return -ENOENT; + if (!(call->flags & TRACE_EVENT_FL_DYNAMIC)) + mod = (struct module *)call->module; + + btf = btf_get_module_btf(mod); + if (IS_ERR_OR_NULL(btf)) + return -ENOENT; + + /* Module-local ids in ids[] need base+local relocation. */ + tp_id = btf_relocate_id(btf, ids[1]); + + /* + * Without FL_TRACEPOINT the dispatcher is shared (e.g. all + * per-syscall events fan out from __bpf_trace_sys_enter), so + * raw_btf_id has no per-event attach point — report 0. + */ + if (call->flags & TRACE_EVENT_FL_TRACEPOINT) { + t = btf_type_by_id(btf, btf_relocate_id(btf, ids[0])); + raw_id = t ? t->type : 0; + } + obj_id = btf_obj_id(btf); + btf_put(btf); + } + + len = scnprintf(buf, sizeof(buf), + "btf_obj_id: %u\nraw_btf_id: %u\ntp_btf_id: %u\n", + obj_id, raw_id, tp_id); + + return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); +} +#endif + static ssize_t event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) @@ -2702,6 +2784,13 @@ static const struct file_operations ftrace_event_id_fops = { }; #endif +#ifdef CONFIG_BPF_EVENTS +static const struct file_operations ftrace_event_btf_ids_fops = { + .read = event_btf_ids_read, + .llseek = default_llseek, +}; +#endif + static const struct file_operations ftrace_event_filter_fops = { .open = tracing_open_file_tr, .read = event_filter_read, @@ -3095,6 +3184,14 @@ static int event_callback(const char *name, umode_t *mode, void **data, } #endif +#ifdef CONFIG_BPF_EVENTS + if (call->class->btf_ids && strcmp(name, "btf_ids") == 0) { + *mode = TRACE_MODE_READ; + *fops = &ftrace_event_btf_ids_fops; + return 1; + } +#endif + #ifdef CONFIG_HIST_TRIGGERS if (strcmp(name, "hist") == 0) { *mode = TRACE_MODE_READ; @@ -3149,7 +3246,14 @@ event_create_dir(struct eventfs_inode *parent, struct trace_event_file *file) .callback = event_callback, }, #endif -#define NR_RO_EVENT_ENTRIES (1 + IS_ENABLED(CONFIG_PERF_EVENTS)) +#ifdef CONFIG_BPF_EVENTS + { + .name = "btf_ids", + .callback = event_callback, + }, +#endif +#define NR_RO_EVENT_ENTRIES (1 + IS_ENABLED(CONFIG_PERF_EVENTS) + \ + IS_ENABLED(CONFIG_BPF_EVENTS)) /* Readonly files must be above this line and counted by NR_RO_EVENT_ENTRIES. */ { .name = "enable", @@ -3557,7 +3661,7 @@ static void update_event_fields(struct trace_event_call *call, } /* Update all events for replacing eval and sanitizing */ -void trace_event_update_all(struct trace_eval_map **map, int len) +void trace_event_update_all(struct trace_eval_map **map, int len, struct module *mod) { struct trace_event_call *call, *p; const char *last_system = NULL; @@ -3569,6 +3673,10 @@ void trace_event_update_all(struct trace_eval_map **map, int len) mutex_lock(&event_mutex); down_write(&trace_event_sem); list_for_each_entry_safe(call, p, &ftrace_events, list) { + + if (mod && call->module != mod) + continue; + /* events are usually grouped together with systems */ if (!last_system || call->class->system != last_system) { first = true; @@ -4505,13 +4613,20 @@ extern struct trace_event_call *__start_ftrace_events[]; extern struct trace_event_call *__stop_ftrace_events[]; static char bootup_event_buf[COMMAND_LINE_SIZE] __initdata; +static struct seq_buf bootup_event_seq __initdata = { + .buffer = bootup_event_buf, + .size = sizeof(bootup_event_buf), +}; static __init int setup_trace_event(char *str) { - if (bootup_event_buf[0] != '\0') - strlcat(bootup_event_buf, ",", COMMAND_LINE_SIZE); + if (seq_buf_used(&bootup_event_seq) > 0) + seq_buf_puts(&bootup_event_seq, ","); + + seq_buf_puts(&bootup_event_seq, str); - strlcat(bootup_event_buf, str, COMMAND_LINE_SIZE); + if (seq_buf_has_overflowed(&bootup_event_seq)) + return -ENOMEM; trace_set_ring_buffer_expanded(NULL); disable_tracing_selftest("running event tracing"); @@ -4770,6 +4885,7 @@ static __init int event_trace_enable(void) */ __trace_early_add_events(tr); + seq_buf_str(&bootup_event_seq); early_enable_events(tr, bootup_event_buf, false); trace_printk_start_comm(); @@ -4798,6 +4914,7 @@ static __init int event_trace_enable_again(void) if (!tr) return -ENODEV; + seq_buf_str(&bootup_event_seq); early_enable_events(tr, bootup_event_buf, true); return 0; diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index 58d28cd1afa3..893bd8b0e48a 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -94,7 +94,6 @@ typedef u64 (*hist_field_fn_t) (struct hist_field *field, #define HIST_FIELD_OPERANDS_MAX 2 #define HIST_FIELDS_MAX (TRACING_MAP_FIELDS_MAX + TRACING_MAP_VARS_MAX) #define HIST_ACTIONS_MAX 8 -#define HIST_CONST_DIGITS_MAX 21 #define HIST_DIV_SHIFT 20 /* For optimizing division by constants */ enum field_op_id { @@ -1733,86 +1732,94 @@ static const char *get_hist_field_flags(struct hist_field *hist_field) return flags_str; } -static void expr_field_str(struct hist_field *field, char *expr) +static bool expr_field_str(struct hist_field *field, struct seq_buf *s) { + const char *field_name; + if (field->flags & HIST_FIELD_FL_VAR_REF) { if (!field->system) - strcat(expr, "$"); - } else if (field->flags & HIST_FIELD_FL_CONST) { - char str[HIST_CONST_DIGITS_MAX]; + seq_buf_putc(s, '$'); + } else if (field->flags & HIST_FIELD_FL_CONST) + seq_buf_printf(s, "%llu", field->constant); - snprintf(str, HIST_CONST_DIGITS_MAX, "%llu", field->constant); - strcat(expr, str); - } + field_name = hist_field_name(field, 0); + if (!field_name) + return false; - strcat(expr, hist_field_name(field, 0)); + seq_buf_puts(s, field_name); if (field->flags && !(field->flags & HIST_FIELD_FL_VAR_REF)) { const char *flags_str = get_hist_field_flags(field); - if (flags_str) { - strcat(expr, "."); - strcat(expr, flags_str); - } + if (flags_str) + seq_buf_printf(s, ".%s", flags_str); } + + return !seq_buf_has_overflowed(s); } static char *expr_str(struct hist_field *field, unsigned int level) { - char *expr; + char *expr __free(kfree) = NULL; + struct seq_buf s; if (level > 1) - return NULL; + return ERR_PTR(-EINVAL); expr = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL); if (!expr) - return NULL; + return ERR_PTR(-ENOMEM); + + seq_buf_init(&s, expr, MAX_FILTER_STR_VAL); if (!field->operands[0]) { - expr_field_str(field, expr); - return expr; + if (!expr_field_str(field, &s)) + return ERR_PTR(-E2BIG); + + return_ptr(expr); } if (field->operator == FIELD_OP_UNARY_MINUS) { char *subexpr; - strcat(expr, "-("); subexpr = expr_str(field->operands[0], ++level); - if (!subexpr) { - kfree(expr); - return NULL; - } - strcat(expr, subexpr); - strcat(expr, ")"); + if (IS_ERR(subexpr)) + return subexpr; + seq_buf_printf(&s, "-(%s)", subexpr); kfree(subexpr); - return expr; + if (seq_buf_has_overflowed(&s)) + return ERR_PTR(-E2BIG); + + return_ptr(expr); } - expr_field_str(field->operands[0], expr); + if (!expr_field_str(field->operands[0], &s)) + return ERR_PTR(-E2BIG); switch (field->operator) { case FIELD_OP_MINUS: - strcat(expr, "-"); + seq_buf_putc(&s, '-'); break; case FIELD_OP_PLUS: - strcat(expr, "+"); + seq_buf_putc(&s, '+'); break; case FIELD_OP_DIV: - strcat(expr, "/"); + seq_buf_putc(&s, '/'); break; case FIELD_OP_MULT: - strcat(expr, "*"); + seq_buf_putc(&s, '*'); break; default: - kfree(expr); - return NULL; + return ERR_PTR(-EINVAL); } - expr_field_str(field->operands[1], expr); + if (seq_buf_has_overflowed(&s) || + !expr_field_str(field->operands[1], &s)) + return ERR_PTR(-E2BIG); - return expr; + return_ptr(expr); } /* @@ -1984,9 +1991,7 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, if (flags & HIST_FIELD_FL_CONST) { hist_field->fn_num = HIST_FIELD_FN_CONST; hist_field->size = sizeof(u64); - hist_field->type = kstrdup("u64", GFP_KERNEL); - if (!hist_field->type) - goto free; + hist_field->type = "u64"; goto out; } @@ -2626,6 +2631,11 @@ static struct hist_field *parse_unary(struct hist_trigger_data *hist_data, expr->is_signed = operand1->is_signed; expr->operator = FIELD_OP_UNARY_MINUS; expr->name = expr_str(expr, 0); + if (IS_ERR(expr->name)) { + ret = PTR_ERR(expr->name); + expr->name = NULL; + goto free; + } expr->type = kstrdup_const(operand1->type, GFP_KERNEL); if (!expr->type) { ret = -ENOMEM; @@ -2838,6 +2848,11 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, destroy_hist_field(operand1, 0); expr->name = expr_str(expr, 0); + if (IS_ERR(expr->name)) { + ret = PTR_ERR(expr->name); + expr->name = NULL; + goto free_expr; + } } else { /* The operand sizes should be the same, so just pick one */ expr->size = operand1->size; @@ -2851,6 +2866,11 @@ static struct hist_field *parse_expr(struct hist_trigger_data *hist_data, } expr->name = expr_str(expr, 0); + if (IS_ERR(expr->name)) { + ret = PTR_ERR(expr->name); + expr->name = NULL; + goto free_expr; + } } return expr; diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c index ad83419cb420..149300cc5e8a 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -1753,7 +1753,7 @@ int event_enable_trigger_parse(struct event_command *cmd_ops, char *glob, char *cmd, char *param_and_filter) { struct trace_event_file *event_enable_file; - struct enable_trigger_data *enable_data; + struct enable_trigger_data *enable_data __free(kfree) = NULL; struct event_trigger_data *trigger_data; struct trace_array *tr = file->tr; char *param, *filter; @@ -1803,17 +1803,13 @@ int event_enable_trigger_parse(struct event_command *cmd_ops, enable_data->file = event_enable_file; trigger_data = trigger_data_alloc(cmd_ops, cmd, param, enable_data); - if (!trigger_data) { - kfree(enable_data); + if (!trigger_data) return ret; - } if (remove) { event_trigger_unregister(cmd_ops, file, glob+1, trigger_data); kfree(trigger_data); - kfree(enable_data); - ret = 0; - return ret; + return 0; } /* Up the trigger_data count to make sure nothing frees it on failure */ @@ -1842,7 +1838,12 @@ int event_enable_trigger_parse(struct event_command *cmd_ops, if (ret) goto out_disable; + /* It's now safe to free the reference taken earlier */ event_trigger_free(trigger_data); + + /* The enabled_data is assigned to trigger_data->private_data */ + retain_and_null_ptr(enable_data); + return ret; out_disable: trace_event_enable_disable(event_enable_file, 0, 1); @@ -1851,7 +1852,6 @@ int event_enable_trigger_parse(struct event_command *cmd_ops, out_free: event_trigger_reset_filter(cmd_ops, trigger_data); event_trigger_free(trigger_data); - kfree(enable_data); return ret; } diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c index 8c82ecb735f4..2bbc89d4a266 100644 --- a/kernel/trace/trace_events_user.c +++ b/kernel/trace/trace_events_user.c @@ -1838,7 +1838,7 @@ static int user_event_show(struct seq_file *m, struct dyn_event *ev) list_for_each_entry_reverse(field, head, link) { if (depth == 0) - seq_puts(m, " "); + seq_putc(m, ' '); else seq_puts(m, "; "); @@ -1850,7 +1850,7 @@ static int user_event_show(struct seq_file *m, struct dyn_event *ev) depth++; } - seq_puts(m, "\n"); + seq_putc(m, '\n'); return 0; } @@ -2806,7 +2806,7 @@ static int user_seq_show(struct seq_file *m, void *p) hash_for_each(group->register_table, i, user, node) { status = user->status; - seq_printf(m, "%s", EVENT_TP_NAME(user)); + seq_puts(m, EVENT_TP_NAME(user)); if (status != 0) { seq_puts(m, " # Used by"); @@ -2819,13 +2819,13 @@ static int user_seq_show(struct seq_file *m, void *p) busy++; } - seq_puts(m, "\n"); + seq_putc(m, '\n'); active++; } mutex_unlock(&group->reg_mutex); - seq_puts(m, "\n"); + seq_putc(m, '\n'); seq_printf(m, "Active: %d\n", active); seq_printf(m, "Busy: %d\n", busy); diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 0d2d3a2ea7dd..ff7cb1a76b95 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -1349,7 +1349,7 @@ print_graph_return(struct ftrace_graph_ret_entry *retentry, struct trace_seq *s, * that if the funcgraph-tail option is enabled. */ if (func_match && !(flags & TRACE_GRAPH_PRINT_TAIL)) - trace_seq_puts(s, "}"); + trace_seq_putc(s, '}'); else trace_seq_printf(s, "} /* %ps */", (void *)func); } diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index df8692c2dea8..77120d467e11 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c @@ -244,13 +244,16 @@ static enum print_line_t mmio_print_map(struct trace_iterator *iter) static enum print_line_t mmio_print_mark(struct trace_iterator *iter) { struct trace_entry *entry = iter->ent; - struct print_entry *print = (struct print_entry *)entry; - const char *msg = print->buf; + struct print_entry *print; + const char *msg; struct trace_seq *s = &iter->seq; unsigned long long t = ns2usecs(iter->ts); unsigned long usec_rem = do_div(t, USEC_PER_SEC); unsigned secs = (unsigned long)t; + trace_assign_type(print, entry); + msg = print->buf; + /* The trailing newline must be in the message. */ trace_seq_printf(s, "MARK %u.%06lu %s", secs, usec_rem, msg); diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c index 3ea17af60169..98171a2398e4 100644 --- a/kernel/trace/trace_printk.c +++ b/kernel/trace/trace_printk.c @@ -71,10 +71,9 @@ void hold_module_trace_bprintk_format(const char **start, const char **end) fmt = NULL; tb_fmt = kmalloc_obj(*tb_fmt); if (tb_fmt) { - fmt = kmalloc(strlen(*iter) + 1, GFP_KERNEL); + fmt = kstrdup(*iter, GFP_KERNEL); if (fmt) { list_add_tail(&tb_fmt->list, &trace_bprintk_fmt_list); - strcpy(fmt, *iter); tb_fmt->fmt = fmt; } else kfree(tb_fmt); diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index e9f0ff962660..1bd351c1fbfb 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -286,12 +286,12 @@ static void __trace_find_cmdline(int pid, char comm[]) int tpid; if (!pid) { - strcpy(comm, "<idle>"); + strscpy(comm, "<idle>", TASK_COMM_LEN); return; } if (WARN_ON_ONCE(pid < 0)) { - strcpy(comm, "<XXX>"); + strscpy(comm, "<XXX>", TASK_COMM_LEN); return; } @@ -304,7 +304,7 @@ static void __trace_find_cmdline(int pid, char comm[]) return; } } - strcpy(comm, "<...>"); + strscpy(comm, "<...>", TASK_COMM_LEN); } void trace_find_cmdline(int pid, char comm[]) diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 8a4f3c75e39f..e35744049e3f 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -9,6 +9,7 @@ #include <linux/ftrace.h> #include <linux/perf_event.h> #include <linux/xarray.h> +#include <linux/btf_ids.h> #include <asm/syscall.h> #include "trace_output.h" @@ -1303,12 +1304,26 @@ struct trace_event_functions exit_syscall_print_funcs = { .trace = print_syscall_exit, }; +#if defined(CONFIG_BPF_EVENTS) && defined(CONFIG_DEBUG_INFO_BTF) +/* BTF id lists for the shared sys_enter/sys_exit dispatcher tracepoints. */ +BTF_ID_LIST(syscall_enter_btf_ids) +BTF_ID(func, __bpf_trace_sys_enter) +BTF_ID(struct, trace_event_raw_sys_enter) + +BTF_ID_LIST(syscall_exit_btf_ids) +BTF_ID(func, __bpf_trace_sys_exit) +BTF_ID(struct, trace_event_raw_sys_exit) +#endif + struct trace_event_class __refdata event_class_syscall_enter = { .system = "syscalls", .reg = syscall_enter_register, .fields_array = syscall_enter_fields_array, .get_fields = syscall_get_enter_fields, .raw_init = init_syscall_trace, +#if defined(CONFIG_BPF_EVENTS) && defined(CONFIG_DEBUG_INFO_BTF) + .btf_ids = syscall_enter_btf_ids, +#endif }; struct trace_event_class __refdata event_class_syscall_exit = { @@ -1321,6 +1336,9 @@ struct trace_event_class __refdata event_class_syscall_exit = { }, .fields = LIST_HEAD_INIT(event_class_syscall_exit.fields), .raw_init = init_syscall_trace, +#if defined(CONFIG_BPF_EVENTS) && defined(CONFIG_DEBUG_INFO_BTF) + .btf_ids = syscall_exit_btf_ids, +#endif }; unsigned long __init __weak arch_syscall_addr(int nr) |
