From 2003e483a81cc235e29f77da3f6b256cb4b348e7 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 19 Jun 2024 13:31:05 -0700 Subject: [PATCH] fortify: Do not special-case 0-sized destinations All fake flexible arrays should have been removed now, so remove the special casing that was avoiding checking them. If a destination claims to be 0 sized, believe it. This is especially important for cases where __counted_by is in use and may have a 0 element count. Link: https://lore.kernel.org/r/20240619203105.work.747-kees@kernel.org Signed-off-by: Kees Cook --- include/linux/fortify-string.h | 8 ++------ lib/fortify_kunit.c | 3 +-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 7e0f340bf36349..0d99bf11d260a3 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -601,11 +601,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, /* * Warn when writing beyond destination field size. * - * We must ignore p_size_field == 0 for existing 0-element - * fake flexible arrays, until they are all converted to - * proper flexible arrays. - * - * The implementation of __builtin_*object_size() behaves + * Note the implementation of __builtin_*object_size() behaves * like sizeof() when not directly referencing a flexible * array member, which means there will be many bounds checks * that will appear at run-time, without a way for them to be @@ -613,7 +609,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size, * is specifically the flexible array member). * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101832 */ - if (p_size_field != 0 && p_size_field != SIZE_MAX && + if (p_size_field != SIZE_MAX && p_size != p_size_field && p_size_field < size) return true; diff --git a/lib/fortify_kunit.c b/lib/fortify_kunit.c index f9cc467334ce3d..f0c64b9e9b469f 100644 --- a/lib/fortify_kunit.c +++ b/lib/fortify_kunit.c @@ -910,10 +910,9 @@ static void fortify_test_##memfunc(struct kunit *test) \ memfunc(zero.buf, srcB, 0 + unconst); \ KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ - /* We currently explicitly ignore zero-sized dests. */ \ memfunc(zero.buf, srcB, 1 + unconst); \ KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ - KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ + KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1); \ } __fortify_test(memcpy) __fortify_test(memmove)