Re: [PATCHv2] trace: allocate fields with elt struct

From: Steven Rostedt

Date: Thu May 28 2026 - 16:37:08 EST


On Tue, 26 May 2026 13:43:17 +0900
Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx> wrote:

> > > #define DEFINE_TRACING_MAP_CMP_FN(type) \
> > > -static int tracing_map_cmp_##type(void *val_a, void *val_b) \
> > > +static int tracing_map_cmp_##type(const void *val_a, const void *val_b) \
> > > { \
> > > - type a = (type)(*(u64 *)val_a); \
> > > - type b = (type)(*(u64 *)val_b); \
> > > + type a = (type)(*(const u64 *)val_a); \
> > > + type b = (type)(*(const u64 *)val_b); \
> > > \
> > > return (a > b) ? 1 : ((a < b) ? -1 : 0); \
> > > }
> > This is a pre-existing issue, but does unconditionally reading 8 bytes
> > via the u64 cast cause unaligned access exceptions on architectures that
> > do not support them?
> > Additionally, for fields near the end of the dynamically allocated elt->key
> > buffer, can this trigger KASAN slab-out-of-bounds reads?
> > Also, on big-endian architectures, reading a smaller integer as a 64-bit
> > value and casting it down extracts the least-significant bytes rather than
> > the correct field value. Could this result in completely incorrect sorting
> > for small types?
>
> Steve, it seems this comes from your commit 106f41f5a302 ("tracing: Have
> the histogram compare functions convert to u64 first").
>
> I think neither of them is a problem, but could you check it?

This should not be a problem because the pointer being passed in was a
number to begin with. In fact that commit you shared was to fix this
compare on big endian machines. The typecast was specifically made to allow
big endian to work here.

The value is already in a 8 byte (64bit) memory location. It is copied into
it as a 64 bit number. Hence it has to be read as a 64 bit number for the
conversions.

A short would be copied into the location via:

u64 location;

location = short_word;

On big endian, for a short word of 0xabcd, it would be in the memory as:

0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xab 0xcd

on little endian, it would be:

0xcd 0xab 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

For big endian to work, it would need to read that first into a 64 bit word
and then convert it back to short.

Thus, Sashiko doesn't know enough here to comment.

-- Steve