Beau, Can you review this?
Thanks, -- Steve On Wed, 22 Jul 2026 14:10:38 +0800 Li Qiang <[email protected]> wrote: > User event declarations permit an explicit size for a struct field. The > parser accumulated that size in an unsigned offset, then assigned the > parsed unsigned value directly to signed field metadata. Oversized > declarations or cumulative offsets could wrap or become invalid signed > values. > > Validate an explicit size is representable as int before storing it. Keep > the running offset signed and reject additions exceeding INT_MAX, so > invalid field layouts are rejected during declaration parsing. > > Fixes: 7f5a08c79df3 ("user_events: Add minimal support for trace_event into > ftrace") > Cc: [email protected] > Signed-off-by: Li Qiang <[email protected]> > --- > kernel/trace/trace_events_user.c | 16 ++++++++++++---- > 1 file changed, 12 insertions(+), 4 deletions(-) > > diff --git a/kernel/trace/trace_events_user.c > b/kernel/trace/trace_events_user.c > index 8c82ecb735f4..fd5b3946921c 100644 > --- a/kernel/trace/trace_events_user.c > +++ b/kernel/trace/trace_events_user.c > @@ -1197,10 +1197,12 @@ static int user_event_add_field(struct user_event > *user, const char *type, > * Format: type name [size] > */ > static int user_event_parse_field(char *field, struct user_event *user, > - u32 *offset) > + int *offset) > { > char *part, *type, *name; > - u32 depth = 0, saved_offset = *offset; > + u32 depth = 0; > + unsigned int field_size; > + int saved_offset = *offset; > int len, size = -EINVAL; > bool is_struct = false; > > @@ -1261,8 +1263,11 @@ static int user_event_parse_field(char *field, struct > user_event *user, > if (!is_struct) > return -EINVAL; > > - if (kstrtou32(part, 10, &size)) > + if (kstrtouint(part, 10, &field_size)) > return -EINVAL; > + if (field_size > INT_MAX) > + return -E2BIG; > + size = field_size; > break; > default: > return -EINVAL; > @@ -1281,6 +1286,9 @@ static int user_event_parse_field(char *field, struct > user_event *user, > if (size < 0) > return size; > > + if (size > INT_MAX - saved_offset) > + return -E2BIG; > + > *offset = saved_offset + size; > > return user_event_add_field(user, type, name, saved_offset, size, > @@ -1290,7 +1298,7 @@ static int user_event_parse_field(char *field, struct > user_event *user, > static int user_event_parse_fields(struct user_event *user, char *args) > { > char *field; > - u32 offset = sizeof(struct trace_entry); > + int offset = sizeof(struct trace_entry); > int ret = -EINVAL; > > if (args == NULL)
