[PATCH v2 13/18] rtla: Fix buffer size for strncpy in timerlat_aa

Wander Lairson Costa posted 18 patches 1 month ago
[PATCH v2 13/18] rtla: Fix buffer size for strncpy in timerlat_aa
Posted by Wander Lairson Costa 1 month ago
The run_thread_comm and current_comm character arrays in struct
timerlat_aa_data are defined with size MAX_COMM (24 bytes), but
strncpy() is called with MAX_COMM as the size parameter. If the
source string is exactly MAX_COMM bytes or longer, strncpy() will
copy exactly MAX_COMM bytes without null termination, potentially
causing buffer overruns when these strings are later used.

Increase the buffer sizes to MAX_COMM+1 to ensure there is always
room for the null terminator. This guarantees that even when strncpy()
copies the maximum number of characters, the buffer remains properly
null-terminated and safe to use in subsequent string operations.

Signed-off-by: Wander Lairson Costa <wander@redhat.com>
---
 tools/tracing/rtla/src/timerlat_aa.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/tracing/rtla/src/timerlat_aa.c b/tools/tracing/rtla/src/timerlat_aa.c
index 31e66ea2b144c..d310fe65abace 100644
--- a/tools/tracing/rtla/src/timerlat_aa.c
+++ b/tools/tracing/rtla/src/timerlat_aa.c
@@ -47,7 +47,7 @@ struct timerlat_aa_data {
 	 * note: "unsigned long long" because they are fetch using tep_get_field_val();
 	 */
 	unsigned long long	run_thread_pid;
-	char			run_thread_comm[MAX_COMM];
+	char			run_thread_comm[MAX_COMM+1];
 	unsigned long long	thread_blocking_duration;
 	unsigned long long	max_exit_idle_latency;
 
@@ -88,7 +88,7 @@ struct timerlat_aa_data {
 	/*
 	 * Current thread.
 	 */
-	char			current_comm[MAX_COMM];
+	char			current_comm[MAX_COMM+1];
 	unsigned long long	current_pid;
 
 	/*
-- 
2.52.0
Re: [PATCH v2 13/18] rtla: Fix buffer size for strncpy in timerlat_aa
Posted by Steven Rostedt 1 month ago
On Tue,  6 Jan 2026 08:49:49 -0300
Wander Lairson Costa <wander@redhat.com> wrote:

> The run_thread_comm and current_comm character arrays in struct
> timerlat_aa_data are defined with size MAX_COMM (24 bytes), but
> strncpy() is called with MAX_COMM as the size parameter. If the
> source string is exactly MAX_COMM bytes or longer, strncpy() will
> copy exactly MAX_COMM bytes without null termination, potentially
> causing buffer overruns when these strings are later used.

We should implement something like the kernel has of "strscpy()" which not
only truncates but also adds a null terminating byte.

> 
> Increase the buffer sizes to MAX_COMM+1 to ensure there is always
> room for the null terminator. This guarantees that even when strncpy()
> copies the maximum number of characters, the buffer remains properly
> null-terminated and safe to use in subsequent string operations.
> 
> Signed-off-by: Wander Lairson Costa <wander@redhat.com>
> ---
>  tools/tracing/rtla/src/timerlat_aa.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/tracing/rtla/src/timerlat_aa.c b/tools/tracing/rtla/src/timerlat_aa.c
> index 31e66ea2b144c..d310fe65abace 100644
> --- a/tools/tracing/rtla/src/timerlat_aa.c
> +++ b/tools/tracing/rtla/src/timerlat_aa.c
> @@ -47,7 +47,7 @@ struct timerlat_aa_data {
>  	 * note: "unsigned long long" because they are fetch using tep_get_field_val();
>  	 */
>  	unsigned long long	run_thread_pid;
> -	char			run_thread_comm[MAX_COMM];
> +	char			run_thread_comm[MAX_COMM+1];

The reason why I suggest strscpy() is because now you just made every this
unaligned in the struct. 24 bytes fits nicely as 3 8 byte words. Now by
adding another byte, you just added 7 bytes of useless padding between this
and the next field.

-- Steve


>  	unsigned long long	thread_blocking_duration;
>  	unsigned long long	max_exit_idle_latency;
>  
> @@ -88,7 +88,7 @@ struct timerlat_aa_data {
>  	/*
>  	 * Current thread.
>  	 */
> -	char			current_comm[MAX_COMM];
> +	char			current_comm[MAX_COMM+1];
>  	unsigned long long	current_pid;
>  
>  	/*
Re: [PATCH v2 13/18] rtla: Fix buffer size for strncpy in timerlat_aa
Posted by Wander Lairson Costa 1 month ago
On Tue, Jan 6, 2026 at 1:03 PM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Tue,  6 Jan 2026 08:49:49 -0300
> Wander Lairson Costa <wander@redhat.com> wrote:
>
...
> >       unsigned long long      run_thread_pid;
> > -     char                    run_thread_comm[MAX_COMM];
> > +     char                    run_thread_comm[MAX_COMM+1];
>
> The reason why I suggest strscpy() is because now you just made every this
> unaligned in the struct. 24 bytes fits nicely as 3 8 byte words. Now by
> adding another byte, you just added 7 bytes of useless padding between this
> and the next field.
>

Hrm, I missed that issue. Maybe I should have set MAX_COMM to 23.
Anyway, in v3 I will switch to strscpy() (maybe strlcpy() does the job).

> -- Steve
>
>
> >       unsigned long long      thread_blocking_duration;
> >       unsigned long long      max_exit_idle_latency;
> >
> > @@ -88,7 +88,7 @@ struct timerlat_aa_data {
> >       /*
> >        * Current thread.
> >        */
> > -     char                    current_comm[MAX_COMM];
> > +     char                    current_comm[MAX_COMM+1];
> >       unsigned long long      current_pid;
> >
> >       /*
>