@@ -1570,7 +1570,9 @@ static void kasan_memcmp(struct kunit *test)
static void kasan_strings(struct kunit *test)
{
char *ptr;
- size_t size = 24;
+ char *src, *src2;
+ u8 tag;
+ size_t size = 2 * KASAN_GRANULE_SIZE;
/*
* str* functions are not instrumented with CONFIG_AMD_MEM_ENCRYPT.
@@ -1581,6 +1583,33 @@ static void kasan_strings(struct kunit *test)
ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+ src = kmalloc(size, GFP_KERNEL | __GFP_ZERO);
+ strscpy(src, "f0cacc1a00000000f0cacc1a00000000", size);
+
+ tag = get_tag(src);
+
+ src2 = src + KASAN_GRANULE_SIZE;
+
+ /*
+ * Shorten string and poison the granule after it so that the unaligned
+ * read in strscpy() triggers a tag mismatch.
+ */
+ src[KASAN_GRANULE_SIZE - 1] = '\0';
+ kasan_poison(src2, KASAN_GRANULE_SIZE, tag + 1, false);
+
+ /*
+ * The expected size does not include the terminator '\0'
+ * so it is (KASAN_GRANULE_SIZE - 2) ==
+ * KASAN_GRANULE_SIZE - ("initial removed character" + "\0").
+ */
+ KUNIT_EXPECT_EQ(test, KASAN_GRANULE_SIZE - 2,
+ strscpy(ptr, src + 1, size));
+
+ /* Undo operations above. */
+ src[KASAN_GRANULE_SIZE - 1] = '0';
+ kasan_poison(src2, KASAN_GRANULE_SIZE, tag, false);
+
+ kfree(src);
kfree(ptr);
/*