kasan: test: fix compatibility with FORTIFY_SOURCE
Subsystems (2)
PATCH 1/1 kasan: test: fix compatibility with FORTIFY_SOURCE
With CONFIG_FORTIFY_SOURCE enabled, string functions will also perform dynamic checks using __builtin_object_size(ptr), which when failed will panic the kernel.
Because the KASAN test deliberately performs out-of-bounds operations, the kernel panics with FORITY_SOURCE, for example:
| kernel BUG at lib/string_helpers.c:910! | invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI | CPU: 1 PID: 137 Comm: kunit_try_catch Tainted: G B 5.16.0-rc3+ #3 | Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 | RIP: 0010:fortify_panic+0x19/0x1b | ... | Call Trace: | <TASK> | kmalloc_oob_in_memset.cold+0x16/0x16 | ...
Fix it by also hiding ptr from the optimizer, which will ensure that __builtin_object_size() does not return a valid size, preventing fortified string functions from panicking.
--- lib/test_kasan.c | 5 +++++ 1 file changed, 5 insertions(+)
lib/test_kasan.c +5 -0
@@ -492,6 +492,7 @@ static void kmalloc_oob_in_memset(struct kunit *test) ptr =kmalloc (size,GFP_KERNEL );KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr); +OPTIMIZER_HIDE_VAR (ptr);OPTIMIZER_HIDE_VAR (size);KUNIT_EXPECT_KASAN_FAIL (test,memset (ptr,0 , size +KASAN_GRANULE_SIZE ));
@@ -515,6 +516,7 @@ static void kmalloc_memmove_negative_size(struct kunit *test)KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr);memset ((char *)ptr,0 ,64 ); +OPTIMIZER_HIDE_VAR (ptr);OPTIMIZER_HIDE_VAR (invalid_size);KUNIT_EXPECT_KASAN_FAIL (test,memmove ((char *)ptr, (char *)ptr +4 , invalid_size));
@@ -531,6 +533,7 @@ static void kmalloc_memmove_invalid_size(struct kunit *test)KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr);memset ((char *)ptr,0 ,64 ); +OPTIMIZER_HIDE_VAR (ptr);KUNIT_EXPECT_KASAN_FAIL (test,memmove ((char *)ptr, (char *)ptr +4 , invalid_size));kfree (ptr);
@@ -893,6 +896,7 @@ static void kasan_memchr(struct kunit *test) ptr =kmalloc (size,GFP_KERNEL | __GFP_ZERO);KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr); +OPTIMIZER_HIDE_VAR (ptr);OPTIMIZER_HIDE_VAR (size);KUNIT_EXPECT_KASAN_FAIL (test, kasan_ptr_result =memchr (ptr,'1' , size +1 ));
@@ -919,6 +923,7 @@ static void kasan_memcmp(struct kunit *test)KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr);memset (arr,0 ,sizeof (arr)); +OPTIMIZER_HIDE_VAR (ptr);OPTIMIZER_HIDE_VAR (size);KUNIT_EXPECT_KASAN_FAIL (test, kasan_int_result =memcmp (ptr, arr, size+1 ));
Signature · 1 line
2.35.0.rc0.227.g00780c9af4-goog
Quoted 7 lines · Marco Elver
With
CONFIG_FORTIFY_SOURCEenabled, string functions will also perform dynamic checks using__builtin_object_size(ptr), which when failed will panic the kernel.Because the KASAN test deliberately performs out-of-bounds operations, the kernel panics with
FORITY_SOURCE, for example:
Nit: FORITY_SOURCE -> FORTIFY_SOURCE
Quoted 67 lines
| kernel BUG at lib/string_helpers.c:910! | invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI | CPU: 1 PID: 137 Comm: kunit_try_catch Tainted: G B 5.16.0-rc3+ #3 | Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 | RIP: 0010:fortify_panic+0x19/0x1b | ... | Call Trace: | <TASK> | kmalloc_oob_in_memset.cold+0x16/0x16 | ...Fix it by also hiding
ptrfrom the optimizer, which will ensure that__builtin_object_size()does not return a valid size, preventing fortified string functions from panicking.Reported-by Nico Pache <[email protected]>Signed-off-by Marco Elver <[email protected]>--- lib/test_kasan.c | 5 +++++ 1 file changed, 5 insertions(+)lib/test_kasan.c +5
-1@@ -492,6 +492,7 @@ static void kmalloc_oob_in_memset(struct kunit *test) ptr =kmalloc (size,GFP_KERNEL );KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr); +OPTIMIZER_HIDE_VAR (ptr);OPTIMIZER_HIDE_VAR (size);KUNIT_EXPECT_KASAN_FAIL (test,memset (ptr,0 , size +KASAN_GRANULE_SIZE ));@@ -515,6 +516,7 @@ static void kmalloc_memmove_negative_size(struct kunit *test)KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr);memset ((char *)ptr,0 ,64 ); +OPTIMIZER_HIDE_VAR (ptr);OPTIMIZER_HIDE_VAR (invalid_size);KUNIT_EXPECT_KASAN_FAIL (test,memmove ((char *)ptr, (char *)ptr +4 , invalid_size));@@ -531,6 +533,7 @@ static void kmalloc_memmove_invalid_size(struct kunit *test)KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr);memset ((char *)ptr,0 ,64 ); +OPTIMIZER_HIDE_VAR (ptr);KUNIT_EXPECT_KASAN_FAIL (test,memmove ((char *)ptr, (char *)ptr +4 , invalid_size));kfree (ptr);@@ -893,6 +896,7 @@ static void kasan_memchr(struct kunit *test) ptr =kmalloc (size,GFP_KERNEL | __GFP_ZERO);KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr); +OPTIMIZER_HIDE_VAR (ptr);OPTIMIZER_HIDE_VAR (size);KUNIT_EXPECT_KASAN_FAIL (test, kasan_ptr_result =memchr (ptr,'1' , size +1 ));@@ -919,6 +923,7 @@ static void kasan_memcmp(struct kunit *test)KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr);memset (arr,0 ,sizeof (arr)); +OPTIMIZER_HIDE_VAR (ptr);OPTIMIZER_HIDE_VAR (size);KUNIT_EXPECT_KASAN_FAIL (test, kasan_int_result =memcmp (ptr, arr, size+1 )); --
Quoted 2 lines
2.35.0.rc0.227.g00780c9af4-goog
Quoted 11 lines · Andrey Konovalov
Quoted 7 lines · Marco Elver
With
CONFIG_FORTIFY_SOURCEenabled, string functions will also perform dynamic checks using__builtin_object_size(ptr), which when failed will panic the kernel.Because the KASAN test deliberately performs out-of-bounds operations, the kernel panics with
FORITY_SOURCE, for example:Nit:
FORITY_SOURCE->FORTIFY_SOURCE
How did that happen?! My hands need some better synchronization...
I'll refrain sending a v2, assuming Andrew can fix up this spelling mistake upon applying.
[...]
Quoted 2 lines
Reviewed-by Andrey Konovalov <[email protected]>
Thanks!
Quoted 18 lines · Marco Elver
With
CONFIG_FORTIFY_SOURCEenabled, string functions will also perform dynamic checks using__builtin_object_size(ptr), which when failed will panic the kernel.Because the KASAN test deliberately performs out-of-bounds operations, the kernel panics with
FORITY_SOURCE, for example:| kernel BUG at lib/string_helpers.c:910! | invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI | CPU: 1 PID: 137 Comm: kunit_try_catch Tainted: G B 5.16.0-rc3+ #3 | Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 | RIP: 0010:fortify_panic+0x19/0x1b | ... | Call Trace: | <TASK> | kmalloc_oob_in_memset.cold+0x16/0x16 | ...
Quoted 6 lines
Fix it by also hiding
ptrfrom the optimizer, which will ensure that__builtin_object_size()does not return a valid size, preventing fortified string functions from panicking.Reported-by Nico Pache <[email protected]>Signed-off-by Marco Elver <[email protected]>
Yup, more good fixes. Thanks!
Signature · 1 line
Kees Cook
Quoted 18 lines · Marco Elver
With
CONFIG_FORTIFY_SOURCEenabled, string functions will also perform dynamic checks using__builtin_object_size(ptr), which when failed will panic the kernel.Because the KASAN test deliberately performs out-of-bounds operations, the kernel panics with
FORITY_SOURCE, for example:| kernel BUG at lib/string_helpers.c:910! | invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI | CPU: 1 PID: 137 Comm: kunit_try_catch Tainted: G B 5.16.0-rc3+ #3 | Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 | RIP: 0010:fortify_panic+0x19/0x1b | ... | Call Trace: | <TASK> | kmalloc_oob_in_memset.cold+0x16/0x16 | ...
Quoted 6 lines
Fix it by also hiding
ptrfrom the optimizer, which will ensure that__builtin_object_size()does not return a valid size, preventing fortified string functions from panicking.Reported-by Nico Pache <[email protected]>Signed-off-by Marco Elver <[email protected]>
Looks good! Thanks for posting this Marco :)
Quoted 49 lines
--- lib/test_kasan.c | 5 +++++ 1 file changed, 5 insertions(+)lib/test_kasan.c +5
-0@@ -492,6 +492,7 @@ static void kmalloc_oob_in_memset(struct kunit *test) ptr =kmalloc (size,GFP_KERNEL );KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr); +OPTIMIZER_HIDE_VAR (ptr);OPTIMIZER_HIDE_VAR (size);KUNIT_EXPECT_KASAN_FAIL (test,memset (ptr,0 , size +KASAN_GRANULE_SIZE ));@@ -515,6 +516,7 @@ static void kmalloc_memmove_negative_size(struct kunit *test)KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr);memset ((char *)ptr,0 ,64 ); +OPTIMIZER_HIDE_VAR (ptr);OPTIMIZER_HIDE_VAR (invalid_size);KUNIT_EXPECT_KASAN_FAIL (test,memmove ((char *)ptr, (char *)ptr +4 , invalid_size));@@ -531,6 +533,7 @@ static void kmalloc_memmove_invalid_size(struct kunit *test)KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr);memset ((char *)ptr,0 ,64 ); +OPTIMIZER_HIDE_VAR (ptr);KUNIT_EXPECT_KASAN_FAIL (test,memmove ((char *)ptr, (char *)ptr +4 , invalid_size));kfree (ptr);@@ -893,6 +896,7 @@ static void kasan_memchr(struct kunit *test) ptr =kmalloc (size,GFP_KERNEL | __GFP_ZERO);KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr); +OPTIMIZER_HIDE_VAR (ptr);OPTIMIZER_HIDE_VAR (size);KUNIT_EXPECT_KASAN_FAIL (test, kasan_ptr_result =memchr (ptr,'1' , size +1 ));@@ -919,6 +923,7 @@ static void kasan_memcmp(struct kunit *test)KUNIT_ASSERT_NOT_ERR_OR_NULL (test, ptr);memset (arr,0 ,sizeof (arr)); +OPTIMIZER_HIDE_VAR (ptr);OPTIMIZER_HIDE_VAR (size);KUNIT_EXPECT_KASAN_FAIL (test, kasan_int_result =memcmp (ptr, arr, size+1 ));