Re: [ammarfaizi2-block:rostedt/linux-trace/ftrace/core 33/41] include/linux/fortify-string.h:47:30: warning: '__builtin_strncat' output truncated before terminating nul copying as many bytes from a string as its length

From: Steven Rostedt
Date: Tue Mar 08 2022 - 10:37:45 EST


On Tue, 8 Mar 2022 21:15:29 +0800
kernel test robot <lkp@xxxxxxxxx> wrote:

> All warnings (new ones prefixed by >>):
>
> In file included from include/linux/string.h:253,
> from include/linux/bitmap.h:11,
> from include/linux/cpumask.h:12,
> from arch/x86/include/asm/cpumask.h:5,
> from arch/x86/include/asm/msr.h:11,
> from arch/x86/include/asm/processor.h:22,
> from arch/x86/include/asm/timex.h:5,
> from include/linux/timex.h:65,
> from include/linux/time32.h:13,
> from include/linux/time.h:60,
> from include/linux/stat.h:19,
> from include/linux/module.h:13,
> from kernel/trace/trace_events_hist.c:8:
> In function 'strncat',
> inlined from 'last_cmd_set' at kernel/trace/trace_events_hist.c:760:2,
> inlined from 'event_hist_trigger_parse' at kernel/trace/trace_events_hist.c:6191:3:
> >> include/linux/fortify-string.h:47:30: warning: '__builtin_strncat' output truncated before terminating nul copying as many bytes from a string as its length [-Wstringop-truncation]
> 47 | #define __underlying_strncat __builtin_strncat
> | ^
> include/linux/fortify-string.h:191:10: note: in expansion of macro '__underlying_strncat'
> 191 | return __underlying_strncat(p, q, count);
> | ^~~~~~~~~~~~~~~~~~~~
> kernel/trace/trace_events_hist.c: In function 'event_hist_trigger_parse':
> include/linux/fortify-string.h:46:29: note: length computed here
> 46 | #define __underlying_strlen __builtin_strlen
> | ^
> include/linux/fortify-string.h:102:10: note: in expansion of macro '__underlying_strlen'
> 102 | return __underlying_strlen(p);
> | ^~~~~~~~~~~~~~~~~~~

I see my mistake. The code it's talking about is this:

len = sizeof(HIST_PREFIX) + strlen(str) + 1;
kfree(last_cmd);
last_cmd = kzalloc(len, GFP_KERNEL);
if (!last_cmd)
return;

strcpy(last_cmd, HIST_PREFIX);
len -= sizeof(HIST_PREFIX) + 1;
strncat(last_cmd, str, len);


Where according to the man page of strncat:

If src contains n or more bytes, strncat() writes n+1 bytes to dest (n
from src plus the terminating null byte). Therefore, the size of dest
must be at least strlen(dest)+n+1.

The above did: len -= sizeof(HIST_PREFIX) + 1; when it meant to do:

len -= strlen(HIST_PREFX) + 1

Or it could just do:

len -= sizeof(HIST_PREFIX)

as sizeof(HIST_PREFIX) contains the nul byte.

Heck, the allocation could be:

len = sizeof(HIST_PREFIX) + strlen(str);

As the sizeof already contains the nul byte.

Will fix.

Thanks,

-- Steve