]> git.baikalelectronics.ru Git - kernel.git/commitdiff
tracing: Use a struct alignof to determine trace event field alignment
authorSteven Rostedt (Google) <rostedt@goodmis.org>
Sun, 31 Jul 2022 05:59:28 +0000 (01:59 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Aug 2022 12:24:29 +0000 (14:24 +0200)
commit 045e997bfe79d55bb8885d0211a89fe1409e5567 upstream.

alignof() gives an alignment of types as they would be as standalone
variables. But alignment in structures might be different, and when
building the fields of events, the alignment must be the actual
alignment otherwise the field offsets may not match what they actually
are.

This caused trace-cmd to crash, as libtraceevent did not check if the
field offset was bigger than the event. The write_msr and read_msr
events on 32 bit had their fields incorrect, because it had a u64 field
between two ints. alignof(u64) would give 8, but the u64 field was at a
4 byte alignment.

Define a macro as:

   ALIGN_STRUCTFIELD(type) ((int)(offsetof(struct {char a; type b;}, b)))

which gives the actual alignment of types in a structure.

Link: https://lkml.kernel.org/r/20220731015928.7ab3a154@rorschach.local.home
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: stable@vger.kernel.org
Fixes: 45de884aa7537 ("ftrace: Rework event_create_dir()")
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
include/trace/trace_events.h

index 65d927e059d31d82280091791197e45d0b5d13a8..c60e10cd07c9f7f2f8dac4a6a985bb7a8278db69 100644 (file)
@@ -479,16 +479,18 @@ static struct trace_event_functions trace_event_type_funcs_##call = {     \
 
 #include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
 
+#define ALIGN_STRUCTFIELD(type) ((int)(offsetof(struct {char a; type b;}, b)))
+
 #undef __field_ext
 #define __field_ext(_type, _item, _filter_type) {                      \
        .type = #_type, .name = #_item,                                 \
-       .size = sizeof(_type), .align = __alignof__(_type),             \
+       .size = sizeof(_type), .align = ALIGN_STRUCTFIELD(_type),       \
        .is_signed = is_signed_type(_type), .filter_type = _filter_type },
 
 #undef __field_struct_ext
 #define __field_struct_ext(_type, _item, _filter_type) {               \
        .type = #_type, .name = #_item,                                 \
-       .size = sizeof(_type), .align = __alignof__(_type),             \
+       .size = sizeof(_type), .align = ALIGN_STRUCTFIELD(_type),       \
        0, .filter_type = _filter_type },
 
 #undef __field
@@ -500,7 +502,7 @@ static struct trace_event_functions trace_event_type_funcs_##call = {       \
 #undef __array
 #define __array(_type, _item, _len) {                                  \
        .type = #_type"["__stringify(_len)"]", .name = #_item,          \
-       .size = sizeof(_type[_len]), .align = __alignof__(_type),       \
+       .size = sizeof(_type[_len]), .align = ALIGN_STRUCTFIELD(_type), \
        .is_signed = is_signed_type(_type), .filter_type = FILTER_OTHER },
 
 #undef __dynamic_array