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)
+
+/**
+ * memtostr_pad - Copy a possibly non-NUL-term string to a NUL-term string
+ *                with NUL padding in the destination
+ * @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_pad(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);                                   \
+       memset(&dest[_copy_len], 0, _dest_len - _copy_len);             \
+} while (0)
+
 /**
  * memset_after - Set a value after a struct member to the end of a struct
  *
 
        KUNIT_EXPECT_STREQ(test, dest, "fourABE");
 }
 
+static void string_test_memtostr(struct kunit *test)
+{
+       char nonstring[7] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
+       char nonstring_small[3] = { 'a', 'b', 'c' };
+       char dest[sizeof(nonstring) + 1];
+
+       /* Copy in a non-NUL-terminated string into exactly right-sized dest. */
+       KUNIT_EXPECT_EQ(test, sizeof(dest), sizeof(nonstring) + 1);
+       memset(dest, 'X', sizeof(dest));
+       memtostr(dest, nonstring);
+       KUNIT_EXPECT_STREQ(test, dest, "abcdefg");
+       memset(dest, 'X', sizeof(dest));
+       memtostr(dest, nonstring_small);
+       KUNIT_EXPECT_STREQ(test, dest, "abc");
+       KUNIT_EXPECT_EQ(test, dest[7], 'X');
+
+       memset(dest, 'X', sizeof(dest));
+       memtostr_pad(dest, nonstring);
+       KUNIT_EXPECT_STREQ(test, dest, "abcdefg");
+       memset(dest, 'X', sizeof(dest));
+       memtostr_pad(dest, nonstring_small);
+       KUNIT_EXPECT_STREQ(test, dest, "abc");
+       KUNIT_EXPECT_EQ(test, dest[7], '\0');
+}
+
 static struct kunit_case string_test_cases[] = {
        KUNIT_CASE(string_test_memset16),
        KUNIT_CASE(string_test_memset32),
        KUNIT_CASE(string_test_strcat),
        KUNIT_CASE(string_test_strncat),
        KUNIT_CASE(string_test_strlcat),
+       KUNIT_CASE(string_test_memtostr),
        {}
 };