On Wed, Jul 26, 2023 at 04:12:23PM +0200, Arnd Bergmann wrote: > From: Arnd Bergmann <arnd@xxxxxxxx> > > Building with W=1 in some configurations produces a false positive > warning for kallsyms: > > kernel/kallsyms.c: In function '__sprint_symbol.isra': > kernel/kallsyms.c:503:17: error: 'strcpy' source argument is the same as destination [-Werror=restrict] > 503 | strcpy(buffer, name); > | ^~~~~~~~~~~~~~~~~~~~ > > This originally showed up while building with -O3, but later started > happening in other configurations as well, depending on inlining > decisions. The underlying issue is that the local 'name' variable is > always initialized to the be the same as 'buffer' in the called functions > that fill the buffer, which gcc notices while inlining, though it could > see that the address check always skips the copy. > > The calling conventions here are rather unusual, as all of the internal > lookup functions (bpf_address_lookup, ftrace_mod_address_lookup, > ftrace_func_address_lookup, module_address_lookup and > kallsyms_lookup_buildid) already use the provided buffer and either return > the address of that buffer to indicate success, or NULL for failure, > but the callers are written to also expect an arbitrary other buffer > to be returned. > > Rework the calling conventions to return the length of the filled buffer > instead of its address, which is simpler and easier to follow as well > as avoiding the warning. Leave only the kallsyms_lookup() calling conventions > unchanged, since that is called from 16 different functions and > adapting this would be a much bigger change. > > Link: https://lore.kernel.org/all/20200107214042.855757-1-arnd@xxxxxxxx/ > Reviewed-by: Luis Chamberlain <mcgrof@xxxxxxxxxx> > Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx> > --- > v3: use strscpy() instead of strlcpy() Thank you! :) (Though see my notes below...) > [...] > @@ -344,13 +345,12 @@ const char *module_address_lookup(unsigned long addr, > #endif > } > > - ret = find_kallsyms_symbol(mod, addr, size, offset); > - } > - /* Make a copy in here where it's safe */ > - if (ret) { > - strncpy(namebuf, ret, KSYM_NAME_LEN - 1); This -1 was to keep the buffer NUL-terminated. > - ret = namebuf; > + sym = find_kallsyms_symbol(mod, addr, size, offset); > + > + if (sym) > + ret = strscpy(namebuf, sym, KSYM_NAME_LEN - 1); This strscpy should use KSYM_NAME_LEN without the "- 1". > } > + > preempt_enable(); > -Kees -- Kees Cook