Hi, On Mon, Apr 8, 2024 at 4:19 PM Kees Cook <keescook@xxxxxxxxxxxx> wrote: > I think something like this, memtostr: > > diff --git a/include/linux/string.h b/include/linux/string.h > index 9ba8b4597009..5def02c7c0ce 100644 > --- a/include/linux/string.h > +++ b/include/linux/string.h > @@ -422,6 +422,30 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count, > memcpy(dest, src, strnlen(src, min(_src_len, _dest_len))); \ > } while (0) > > +/** > + * memtostr - Copy a possibly non-NUL-term string to a NUL-term string > + * @dest: Pointer to destination NUL-terminates string > + * @src: Pointer to character array (likely marked as __nonstring) > + * > + * This is a replacement for strncpy() uses where the source is not > + * a NUL-terminated string. > + * > + * Note that sizes of @dest and @src must be known at compile-time. > + */ > +#define memtostr(dest, src) do { \ > + const size_t _dest_len = __builtin_object_size(dest, 1); \ > + const size_t _src_len = __builtin_object_size(src, 1); \ > + const size_t _src_chars = strnlen(src, _src_len); \ > + const size_t _copy_len = min(_dest_len - 1, _src_chars); \ > + \ > + BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ > + !__builtin_constant_p(_src_len) || \ > + _dest_len == 0 || _dest_len == (size_t)-1 || \ > + _src_len == 0 || _src_len == (size_t)-1); \ > + memcpy(dest, src, _copy_len); \ > + dest[_copy_len] = '\0'; \ > +} while (0) > + > /** > * memset_after - Set a value after a struct member to the end of a struct > * > > > I've also identified other cases where this pattern exists, so I think > we can apply this and any needed fixes using it instead of strscpy(). > For visibility, Kees has a series [1] which introduces memtostr and also fixes up drivers/message/fusion/mptsas.c. Charles, can you try out that series? > -- > Kees Cook [1]: https://lore.kernel.org/all/20240410023155.2100422-2-keescook@xxxxxxxxxxxx/ Thanks Justin