Skip to content

Commit 938aa33

Browse files
committed
tracing: Add length protection to histogram string copies
The string copies to the histogram storage has a max size of 256 bytes (defined by MAX_FILTER_STR_VAL). Only the string size of the event field needs to be copied to the event storage, but no more than what is in the event storage. Although nothing should be bigger than 256 bytes, there's no protection against overwriting of the storage if one day there is. Copy no more than the destination size, and enforce it. Also had to turn MAX_FILTER_STR_VAL into an unsigned int, to keep the min() comparison of the string sizes of comparable types. Link: https://lore.kernel.org/all/CAHk-=wjREUihCGrtRBwfX47y_KrLCGjiq3t6QtoNJpmVrAEb1w@mail.gmail.com/ Link: https://lkml.kernel.org/r/[email protected] Cc: Ingo Molnar <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Tom Zanussi <[email protected]> Reported-by: Linus Torvalds <[email protected]> Reviewed-by: Masami Hiramatsu <[email protected]> Fixes: 63f84ae ("tracing/histogram: Do not copy the fixed-size char array field over the field size") Signed-off-by: Steven Rostedt (VMware) <[email protected]>
1 parent 1cab6bc commit 938aa33

File tree

2 files changed

+8
-3
lines changed

2 files changed

+8
-3
lines changed

include/linux/trace_events.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ struct trace_event_file {
673673

674674
#define PERF_MAX_TRACE_SIZE 8192
675675

676-
#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */
676+
#define MAX_FILTER_STR_VAL 256U /* Should handle KSYM_SYMBOL_LEN */
677677

678678
enum event_trigger_type {
679679
ETT_NONE = (0),

kernel/trace/trace_events_hist.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3026,8 +3026,10 @@ static inline void __update_field_vars(struct tracing_map_elt *elt,
30263026
if (val->flags & HIST_FIELD_FL_STRING) {
30273027
char *str = elt_data->field_var_str[j++];
30283028
char *val_str = (char *)(uintptr_t)var_val;
3029+
unsigned int size;
30293030

3030-
strscpy(str, val_str, val->size);
3031+
size = min(val->size, STR_VAR_LEN_MAX);
3032+
strscpy(str, val_str, size);
30313033
var_val = (u64)(uintptr_t)str;
30323034
}
30333035
tracing_map_set_var(elt, var_idx, var_val);
@@ -4914,6 +4916,7 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data,
49144916
if (hist_field->flags & HIST_FIELD_FL_STRING) {
49154917
unsigned int str_start, var_str_idx, idx;
49164918
char *str, *val_str;
4919+
unsigned int size;
49174920

49184921
str_start = hist_data->n_field_var_str +
49194922
hist_data->n_save_var_str;
@@ -4922,7 +4925,9 @@ static void hist_trigger_elt_update(struct hist_trigger_data *hist_data,
49224925

49234926
str = elt_data->field_var_str[idx];
49244927
val_str = (char *)(uintptr_t)hist_val;
4925-
strscpy(str, val_str, hist_field->size);
4928+
4929+
size = min(hist_field->size, STR_VAR_LEN_MAX);
4930+
strscpy(str, val_str, size);
49264931

49274932
hist_val = (u64)(uintptr_t)str;
49284933
}

0 commit comments

Comments
 (0)