Re: [PATCH 2/4] tracing/user_events: Validate explicit struct field sizes

Steven Rostedt <[email protected]>
Newsgroups org.kernel.vger.linux-trace-kernel,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
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)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.