11// SPDX-License-Identifier: GPL-2.0
22/*
3- * Runtime test cases for CONFIG_FORTIFY_SOURCE. For testing memcpy(),
4- * see FORTIFY_MEM_* tests in LKDTM (drivers/misc/lkdtm/fortify.c).
3+ * Runtime test cases for CONFIG_FORTIFY_SOURCE. For additional memcpy()
4+ * testing see FORTIFY_MEM_* tests in LKDTM (drivers/misc/lkdtm/fortify.c).
55 *
66 * For corner cases with UBSAN, try testing with:
77 *
1818/* We don't need to fill dmesg with the fortify WARNs during testing. */
1919#ifdef DEBUG
2020# define FORTIFY_REPORT_KUNIT (x ...) __fortify_report(x)
21+ # define FORTIFY_WARN_KUNIT (x ...) WARN_ONCE(x)
2122#else
2223# define FORTIFY_REPORT_KUNIT (x ...) do { } while (0)
24+ # define FORTIFY_WARN_KUNIT (x ...) do { } while (0)
2325#endif
2426
2527/* Redefine fortify_panic() to track failures. */
@@ -30,6 +32,14 @@ void fortify_add_kunit_error(int write);
3032 return (retfail); \
3133} while (0)
3234
35+ /* Redefine fortify_warn_once() to track memcpy() failures. */
36+ #define fortify_warn_once (chk_func , x ...) do { \
37+ bool __result = chk_func; \
38+ FORTIFY_WARN_KUNIT(__result, x); \
39+ if (__result) \
40+ fortify_add_kunit_error(1); \
41+ } while (0)
42+
3343#include <kunit/device.h>
3444#include <kunit/test.h>
3545#include <kunit/test-bug.h>
@@ -818,6 +828,74 @@ static void fortify_test_strlcat(struct kunit *test)
818828 KUNIT_EXPECT_EQ (test , pad .bytes_after , 0 );
819829}
820830
831+ /* Check for 0-sized arrays... */
832+ struct fortify_zero_sized {
833+ unsigned long bytes_before ;
834+ char buf [0 ];
835+ unsigned long bytes_after ;
836+ };
837+
838+ #define __fortify_test (memfunc ) \
839+ static void fortify_test_##memfunc(struct kunit *test) \
840+ { \
841+ struct fortify_zero_sized zero = { }; \
842+ struct fortify_padding pad = { }; \
843+ char srcA[sizeof(pad.buf) + 2]; \
844+ char srcB[sizeof(pad.buf) + 2]; \
845+ size_t len = sizeof(pad.buf) + unconst; \
846+ \
847+ memset(srcA, 'A', sizeof(srcA)); \
848+ KUNIT_ASSERT_EQ(test, srcA[0], 'A'); \
849+ memset(srcB, 'B', sizeof(srcB)); \
850+ KUNIT_ASSERT_EQ(test, srcB[0], 'B'); \
851+ \
852+ memfunc(pad.buf, srcA, 0 + unconst); \
853+ KUNIT_EXPECT_EQ(test, pad.buf[0], '\0'); \
854+ KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \
855+ KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \
856+ memfunc(pad.buf + 1, srcB, 1 + unconst); \
857+ KUNIT_EXPECT_EQ(test, pad.buf[0], '\0'); \
858+ KUNIT_EXPECT_EQ(test, pad.buf[1], 'B'); \
859+ KUNIT_EXPECT_EQ(test, pad.buf[2], '\0'); \
860+ KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \
861+ KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \
862+ memfunc(pad.buf, srcA, 1 + unconst); \
863+ KUNIT_EXPECT_EQ(test, pad.buf[0], 'A'); \
864+ KUNIT_EXPECT_EQ(test, pad.buf[1], 'B'); \
865+ KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \
866+ KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \
867+ memfunc(pad.buf, srcA, len - 1); \
868+ KUNIT_EXPECT_EQ(test, pad.buf[1], 'A'); \
869+ KUNIT_EXPECT_EQ(test, pad.buf[len - 1], '\0'); \
870+ KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \
871+ KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \
872+ memfunc(pad.buf, srcA, len); \
873+ KUNIT_EXPECT_EQ(test, pad.buf[1], 'A'); \
874+ KUNIT_EXPECT_EQ(test, pad.buf[len - 1], 'A'); \
875+ KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); \
876+ KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \
877+ KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \
878+ memfunc(pad.buf, srcA, len + 1); \
879+ KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \
880+ KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1); \
881+ memfunc(pad.buf + 1, srcB, len); \
882+ KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \
883+ KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2); \
884+ \
885+ /* Reset error counter. */ \
886+ fortify_write_overflows = 0 ; \
887+ /* Copy nothing into nothing: no errors. */ \
888+ memfunc (zero .buf , srcB , 0 + unconst ); \
889+ KUNIT_EXPECT_EQ (test , fortify_read_overflows , 0 ); \
890+ KUNIT_EXPECT_EQ (test , fortify_write_overflows , 0 ); \
891+ /* We currently explicitly ignore zero-sized dests. */ \
892+ memfunc (zero .buf , srcB , 1 + unconst ); \
893+ KUNIT_EXPECT_EQ (test , fortify_read_overflows , 0 ); \
894+ KUNIT_EXPECT_EQ (test , fortify_write_overflows , 0 ); \
895+ }
896+ __fortify_test (memcpy )
897+ __fortify_test (memmove )
898+
821899static void fortify_test_memscan (struct kunit * test )
822900{
823901 char haystack [] = "Where oh where is my memory range?" ;
@@ -977,7 +1055,8 @@ static struct kunit_case fortify_test_cases[] = {
9771055 KUNIT_CASE (fortify_test_strncat ),
9781056 KUNIT_CASE (fortify_test_strlcat ),
9791057 /* skip memset: performs bounds checking on whole structs */
980- /* skip memcpy: still using warn-and-overwrite instead of hard-fail */
1058+ KUNIT_CASE (fortify_test_memcpy ),
1059+ KUNIT_CASE (fortify_test_memmove ),
9811060 KUNIT_CASE (fortify_test_memscan ),
9821061 KUNIT_CASE (fortify_test_memchr ),
9831062 KUNIT_CASE (fortify_test_memchr_inv ),
0 commit comments