Skip to content

Commit baa333b

Browse files
neosys007gregkh
authored andcommitted
tracing: Bound synthetic-field strings with seq_buf
[ Upstream commit f078834 ] The synthetic field helpers build a prefixed synthetic variable name and a generated hist command in fixed MAX_FILTER_STR_VAL buffers. The current code appends those strings with raw strcat(), so long key lists, field names, or saved filters can run past the end of the staging buffers. Build both strings with seq_buf and propagate -E2BIG if either the synthetic variable name or the generated command exceeds MAX_FILTER_STR_VAL. This keeps the existing tracing-side limit while using the helper intended for bounded command construction. Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Tom Zanussi <tom.zanussi@linux.intel.com> Link: https://patch.msgid.link/20260430043350.57928-1-pengpeng@iscas.ac.cn Fixes: 02205a6 ("tracing: Add support for 'field variables'") Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Reviewed-by: Tom Zanussi <zanussi@kernel.org> Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> [ sdr: Moved struct seq_buf *s for upside-down x-mas tree formatting ] Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 09a2a7d commit baa333b

1 file changed

Lines changed: 29 additions & 12 deletions

File tree

kernel/trace/trace_events_hist.c

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/module.h>
99
#include <linux/kallsyms.h>
1010
#include <linux/security.h>
11+
#include <linux/seq_buf.h>
1112
#include <linux/mutex.h>
1213
#include <linux/slab.h>
1314
#include <linux/stacktrace.h>
@@ -2957,13 +2958,22 @@ find_synthetic_field_var(struct hist_trigger_data *target_hist_data,
29572958
{
29582959
struct hist_field *event_var;
29592960
char *synthetic_name;
2961+
struct seq_buf s;
29602962

29612963
synthetic_name = kzalloc(MAX_FILTER_STR_VAL, GFP_KERNEL);
29622964
if (!synthetic_name)
29632965
return ERR_PTR(-ENOMEM);
29642966

2965-
strcpy(synthetic_name, "synthetic_");
2966-
strcat(synthetic_name, field_name);
2967+
seq_buf_init(&s, synthetic_name, MAX_FILTER_STR_VAL);
2968+
seq_buf_printf(&s, "synthetic_%s", field_name);
2969+
2970+
/* Terminate synthetic_name with a NUL. */
2971+
seq_buf_str(&s);
2972+
2973+
if (seq_buf_has_overflowed(&s)) {
2974+
kfree(synthetic_name);
2975+
return ERR_PTR(-E2BIG);
2976+
}
29672977

29682978
event_var = find_event_var(target_hist_data, system, event_name, synthetic_name);
29692979

@@ -3009,6 +3019,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data,
30093019
struct hist_field *key_field;
30103020
struct hist_field *event_var;
30113021
char *saved_filter;
3022+
struct seq_buf s;
30123023
char *cmd;
30133024
int ret;
30143025

@@ -3053,28 +3064,34 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data,
30533064
return ERR_PTR(-ENOMEM);
30543065
}
30553066

3067+
seq_buf_init(&s, cmd, MAX_FILTER_STR_VAL);
3068+
30563069
/* Use the same keys as the compatible histogram */
3057-
strcat(cmd, "keys=");
3070+
seq_buf_puts(&s, "keys=");
30583071

30593072
for_each_hist_key_field(i, hist_data) {
30603073
key_field = hist_data->fields[i];
30613074
if (!first)
3062-
strcat(cmd, ",");
3063-
strcat(cmd, key_field->field->name);
3075+
seq_buf_putc(&s, ',');
3076+
seq_buf_puts(&s, key_field->field->name);
30643077
first = false;
30653078
}
30663079

30673080
/* Create the synthetic field variable specification */
3068-
strcat(cmd, ":synthetic_");
3069-
strcat(cmd, field_name);
3070-
strcat(cmd, "=");
3071-
strcat(cmd, field_name);
3081+
seq_buf_printf(&s, ":synthetic_%s=%s", field_name, field_name);
30723082

30733083
/* Use the same filter as the compatible histogram */
30743084
saved_filter = find_trigger_filter(hist_data, file);
3075-
if (saved_filter) {
3076-
strcat(cmd, " if ");
3077-
strcat(cmd, saved_filter);
3085+
if (saved_filter)
3086+
seq_buf_printf(&s, " if %s", saved_filter);
3087+
3088+
/* Terminate cmd with a NUL. */
3089+
seq_buf_str(&s);
3090+
3091+
if (seq_buf_has_overflowed(&s)) {
3092+
kfree(cmd);
3093+
kfree(var_hist);
3094+
return ERR_PTR(-E2BIG);
30783095
}
30793096

30803097
var_hist->cmd = kstrdup(cmd, GFP_KERNEL);

0 commit comments

Comments
 (0)