In check_synth_field(), when a synthetic event field is a stacktrace
(field->is_stack) and the histogram field is not a "long[" stacktrace
array, validation falls through to the generic size and signedness
comparison.

Because parse_synth_field() sets a stacktrace field's type to
"__data_loc unsigned long[]", its size is sizeof(u64) and
synth_field_signed() marks it as signed.  Consequently, any 8-byte
signed scalar histogram field passes the fallback check, and its scalar
value is subsequently dereferenced as a kernel stacktrace pointer in
get_field_size() and trace_stack().

Reject any mismatch between field->is_stack and a "long[" histogram
field type in check_synth_field().

Fixes: 00cf3d672a9d ("tracing: Allow synthetic events to pass around 
stacktraces")
Cc: [email protected]
Signed-off-by: Lee Jones <[email protected]>
---
 kernel/trace/trace_events_hist.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 8af97fd4ee2d..b09f5043e154 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -3946,7 +3946,10 @@ static int check_synth_field(struct synth_event *event,
            && field->is_dynamic)
                return 0;
 
-       if (strstr(hist_field->type, "long[") && field->is_stack)
+       if (!!strstr(hist_field->type, "long[") != field->is_stack)
+               return -EINVAL;
+
+       if (field->is_stack)
                return 0;
 
        if (strcmp(field->type, hist_field->type) != 0) {
-- 
2.56.0.385.gd3acb90ef8-goog


Reply via email to