Patch "kasan: test: add memcpy test that avoids out-of-bounds write" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    kasan: test: add memcpy test that avoids out-of-bounds write

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     kasan-test-add-memcpy-test-that-avoids-out-of-bounds.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 78fb0b4c22c41e374374245def3a5cd7200345bf
Author: Peter Collingbourne <pcc@xxxxxxxxxx>
Date:   Fri Nov 5 13:35:56 2021 -0700

    kasan: test: add memcpy test that avoids out-of-bounds write
    
    [ Upstream commit 758cabae312d3aded781aacc6d0c946b299c52df ]
    
    With HW tag-based KASAN, error checks are performed implicitly by the
    load and store instructions in the memcpy implementation.  A failed
    check results in tag checks being disabled and execution will keep
    going.  As a result, under HW tag-based KASAN, prior to commit
    1b0668be62cf ("kasan: test: disable kmalloc_memmove_invalid_size for
    HW_TAGS"), this memcpy would end up corrupting memory until it hits an
    inaccessible page and causes a kernel panic.
    
    This is a pre-existing issue that was revealed by commit 285133040e6c
    ("arm64: Import latest memcpy()/memmove() implementation") which changed
    the memcpy implementation from using signed comparisons (incorrectly,
    resulting in the memcpy being terminated early for negative sizes) to
    using unsigned comparisons.
    
    It is unclear how this could be handled by memcpy itself in a reasonable
    way.  One possibility would be to add an exception handler that would
    force memcpy to return if a tag check fault is detected -- this would
    make the behavior roughly similar to generic and SW tag-based KASAN.
    However, this wouldn't solve the problem for asynchronous mode and also
    makes memcpy behavior inconsistent with manually copying data.
    
    This test was added as a part of a series that taught KASAN to detect
    negative sizes in memory operations, see commit 8cceeff48f23 ("kasan:
    detect negative size in memory operation function").  Therefore we
    should keep testing for negative sizes with generic and SW tag-based
    KASAN.  But there is some value in testing small memcpy overflows, so
    let's add another test with memcpy that does not destabilize the kernel
    by performing out-of-bounds writes, and run it in all modes.
    
    Link: https://linux-review.googlesource.com/id/I048d1e6a9aff766c4a53f989fb0c83de68923882
    Link: https://lkml.kernel.org/r/20210910211356.3603758-1-pcc@xxxxxxxxxx
    Signed-off-by: Peter Collingbourne <pcc@xxxxxxxxxx>
    Reviewed-by: Andrey Konovalov <andreyknvl@xxxxxxxxx>
    Acked-by: Marco Elver <elver@xxxxxxxxxx>
    Cc: Robin Murphy <robin.murphy@xxxxxxx>
    Cc: Will Deacon <will@xxxxxxxxxx>
    Cc: Catalin Marinas <catalin.marinas@xxxxxxx>
    Cc: Mark Rutland <mark.rutland@xxxxxxx>
    Cc: Evgenii Stepanov <eugenis@xxxxxxxxxx>
    Cc: Alexander Potapenko <glider@xxxxxxxxxx>
    Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
    Stable-dep-of: e10aea105e9e ("kasan/test: avoid gcc warning for intentional overflow")
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/lib/test_kasan.c b/lib/test_kasan.c
index 89f444cabd4a8..f0b8b05ccf194 100644
--- a/lib/test_kasan.c
+++ b/lib/test_kasan.c
@@ -500,7 +500,7 @@ static void kmalloc_oob_in_memset(struct kunit *test)
 	kfree(ptr);
 }
 
-static void kmalloc_memmove_invalid_size(struct kunit *test)
+static void kmalloc_memmove_negative_size(struct kunit *test)
 {
 	char *ptr;
 	size_t size = 64;
@@ -522,6 +522,21 @@ static void kmalloc_memmove_invalid_size(struct kunit *test)
 	kfree(ptr);
 }
 
+static void kmalloc_memmove_invalid_size(struct kunit *test)
+{
+	char *ptr;
+	size_t size = 64;
+	volatile size_t invalid_size = size;
+
+	ptr = kmalloc(size, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+
+	memset((char *)ptr, 0, 64);
+	KUNIT_EXPECT_KASAN_FAIL(test,
+		memmove((char *)ptr, (char *)ptr + 4, invalid_size));
+	kfree(ptr);
+}
+
 static void kmalloc_uaf(struct kunit *test)
 {
 	char *ptr;
@@ -1139,6 +1154,7 @@ static struct kunit_case kasan_kunit_test_cases[] = {
 	KUNIT_CASE(kmalloc_oob_memset_4),
 	KUNIT_CASE(kmalloc_oob_memset_8),
 	KUNIT_CASE(kmalloc_oob_memset_16),
+	KUNIT_CASE(kmalloc_memmove_negative_size),
 	KUNIT_CASE(kmalloc_memmove_invalid_size),
 	KUNIT_CASE(kmalloc_uaf),
 	KUNIT_CASE(kmalloc_uaf_memset),




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux