1db6fe4d6SKees Cook // SPDX-License-Identifier: GPL-2.0 2db6fe4d6SKees Cook /* 3db6fe4d6SKees Cook * Runtime test cases for CONFIG_FORTIFY_SOURCE. For additional memcpy() 4db6fe4d6SKees Cook * testing see FORTIFY_MEM_* tests in LKDTM (drivers/misc/lkdtm/fortify.c). 5db6fe4d6SKees Cook * 6db6fe4d6SKees Cook * For corner cases with UBSAN, try testing with: 7db6fe4d6SKees Cook * 8db6fe4d6SKees Cook * ./tools/testing/kunit/kunit.py run --arch=x86_64 \ 9db6fe4d6SKees Cook * --kconfig_add CONFIG_FORTIFY_SOURCE=y \ 10db6fe4d6SKees Cook * --kconfig_add CONFIG_UBSAN=y \ 11db6fe4d6SKees Cook * --kconfig_add CONFIG_UBSAN_TRAP=y \ 12db6fe4d6SKees Cook * --kconfig_add CONFIG_UBSAN_BOUNDS=y \ 13db6fe4d6SKees Cook * --kconfig_add CONFIG_UBSAN_LOCAL_BOUNDS=y \ 14db6fe4d6SKees Cook * --make_options LLVM=1 fortify 15db6fe4d6SKees Cook */ 16db6fe4d6SKees Cook #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17db6fe4d6SKees Cook 18db6fe4d6SKees Cook /* We don't need to fill dmesg with the fortify WARNs during testing. */ 19db6fe4d6SKees Cook #ifdef DEBUG 20db6fe4d6SKees Cook # define FORTIFY_REPORT_KUNIT(x...) __fortify_report(x) 21db6fe4d6SKees Cook # define FORTIFY_WARN_KUNIT(x...) WARN_ONCE(x) 22db6fe4d6SKees Cook #else 23db6fe4d6SKees Cook # define FORTIFY_REPORT_KUNIT(x...) do { } while (0) 24db6fe4d6SKees Cook # define FORTIFY_WARN_KUNIT(x...) do { } while (0) 25db6fe4d6SKees Cook #endif 26db6fe4d6SKees Cook 27db6fe4d6SKees Cook /* Redefine fortify_panic() to track failures. */ 28db6fe4d6SKees Cook void fortify_add_kunit_error(int write); 29db6fe4d6SKees Cook #define fortify_panic(func, write, avail, size, retfail) do { \ 30db6fe4d6SKees Cook FORTIFY_REPORT_KUNIT(FORTIFY_REASON(func, write), avail, size); \ 31db6fe4d6SKees Cook fortify_add_kunit_error(write); \ 32db6fe4d6SKees Cook return (retfail); \ 33db6fe4d6SKees Cook } while (0) 34db6fe4d6SKees Cook 35db6fe4d6SKees Cook /* Redefine fortify_warn_once() to track memcpy() failures. */ 36db6fe4d6SKees Cook #define fortify_warn_once(chk_func, x...) do { \ 37db6fe4d6SKees Cook bool __result = chk_func; \ 38db6fe4d6SKees Cook FORTIFY_WARN_KUNIT(__result, x); \ 39db6fe4d6SKees Cook if (__result) \ 40db6fe4d6SKees Cook fortify_add_kunit_error(1); \ 41db6fe4d6SKees Cook } while (0) 42db6fe4d6SKees Cook 43db6fe4d6SKees Cook #include <kunit/device.h> 44db6fe4d6SKees Cook #include <kunit/test.h> 45db6fe4d6SKees Cook #include <kunit/test-bug.h> 46db6fe4d6SKees Cook #include <linux/device.h> 47db6fe4d6SKees Cook #include <linux/slab.h> 48db6fe4d6SKees Cook #include <linux/string.h> 49db6fe4d6SKees Cook #include <linux/vmalloc.h> 50db6fe4d6SKees Cook 51db6fe4d6SKees Cook /* Handle being built without CONFIG_FORTIFY_SOURCE */ 52db6fe4d6SKees Cook #ifndef __compiletime_strlen 53db6fe4d6SKees Cook # define __compiletime_strlen __builtin_strlen 54db6fe4d6SKees Cook #endif 55db6fe4d6SKees Cook 56db6fe4d6SKees Cook static struct kunit_resource read_resource; 57db6fe4d6SKees Cook static struct kunit_resource write_resource; 58db6fe4d6SKees Cook static int fortify_read_overflows; 59db6fe4d6SKees Cook static int fortify_write_overflows; 60db6fe4d6SKees Cook 61db6fe4d6SKees Cook static const char array_of_10[] = "this is 10"; 62db6fe4d6SKees Cook static const char *ptr_of_11 = "this is 11!"; 63416cf1f4SKees Cook static const char * const unchanging_12 = "this is 12!!"; 64db6fe4d6SKees Cook static char array_unknown[] = "compiler thinks I might change"; 65db6fe4d6SKees Cook 66db6fe4d6SKees Cook void fortify_add_kunit_error(int write) 67db6fe4d6SKees Cook { 68db6fe4d6SKees Cook struct kunit_resource *resource; 69db6fe4d6SKees Cook struct kunit *current_test; 70db6fe4d6SKees Cook 71db6fe4d6SKees Cook current_test = kunit_get_current_test(); 72db6fe4d6SKees Cook if (!current_test) 73db6fe4d6SKees Cook return; 74db6fe4d6SKees Cook 75db6fe4d6SKees Cook resource = kunit_find_named_resource(current_test, 76db6fe4d6SKees Cook write ? "fortify_write_overflows" 77db6fe4d6SKees Cook : "fortify_read_overflows"); 78db6fe4d6SKees Cook if (!resource) 79db6fe4d6SKees Cook return; 80db6fe4d6SKees Cook 81db6fe4d6SKees Cook (*(int *)resource->data)++; 82db6fe4d6SKees Cook kunit_put_resource(resource); 83db6fe4d6SKees Cook } 84db6fe4d6SKees Cook 85db6fe4d6SKees Cook static void fortify_test_known_sizes(struct kunit *test) 86db6fe4d6SKees Cook { 87416cf1f4SKees Cook char stack[80] = "Test!"; 88416cf1f4SKees Cook 89416cf1f4SKees Cook KUNIT_EXPECT_FALSE(test, __is_constexpr(__builtin_strlen(stack))); 90416cf1f4SKees Cook KUNIT_EXPECT_EQ(test, __compiletime_strlen(stack), 5); 91416cf1f4SKees Cook 92416cf1f4SKees Cook KUNIT_EXPECT_TRUE(test, __is_constexpr(__builtin_strlen("88888888"))); 93db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, __compiletime_strlen("88888888"), 8); 94416cf1f4SKees Cook 95416cf1f4SKees Cook KUNIT_EXPECT_TRUE(test, __is_constexpr(__builtin_strlen(array_of_10))); 96db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, __compiletime_strlen(array_of_10), 10); 97416cf1f4SKees Cook 98416cf1f4SKees Cook KUNIT_EXPECT_FALSE(test, __is_constexpr(__builtin_strlen(ptr_of_11))); 99db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, __compiletime_strlen(ptr_of_11), 11); 100db6fe4d6SKees Cook 101416cf1f4SKees Cook KUNIT_EXPECT_TRUE(test, __is_constexpr(__builtin_strlen(unchanging_12))); 102416cf1f4SKees Cook KUNIT_EXPECT_EQ(test, __compiletime_strlen(unchanging_12), 12); 103416cf1f4SKees Cook 104416cf1f4SKees Cook KUNIT_EXPECT_FALSE(test, __is_constexpr(__builtin_strlen(array_unknown))); 105db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, __compiletime_strlen(array_unknown), SIZE_MAX); 106416cf1f4SKees Cook 107db6fe4d6SKees Cook /* Externally defined and dynamically sized string pointer: */ 108416cf1f4SKees Cook KUNIT_EXPECT_FALSE(test, __is_constexpr(__builtin_strlen(test->name))); 109db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, __compiletime_strlen(test->name), SIZE_MAX); 110db6fe4d6SKees Cook } 111db6fe4d6SKees Cook 112db6fe4d6SKees Cook /* This is volatile so the optimizer can't perform DCE below. */ 113db6fe4d6SKees Cook static volatile int pick; 114db6fe4d6SKees Cook 115db6fe4d6SKees Cook /* Not inline to keep optimizer from figuring out which string we want. */ 116db6fe4d6SKees Cook static noinline size_t want_minus_one(int pick) 117db6fe4d6SKees Cook { 118db6fe4d6SKees Cook const char *str; 119db6fe4d6SKees Cook 120db6fe4d6SKees Cook switch (pick) { 121db6fe4d6SKees Cook case 1: 122db6fe4d6SKees Cook str = "4444"; 123db6fe4d6SKees Cook break; 124db6fe4d6SKees Cook case 2: 125db6fe4d6SKees Cook str = "333"; 126db6fe4d6SKees Cook break; 127db6fe4d6SKees Cook default: 128db6fe4d6SKees Cook str = "1"; 129db6fe4d6SKees Cook break; 130db6fe4d6SKees Cook } 131db6fe4d6SKees Cook return __compiletime_strlen(str); 132db6fe4d6SKees Cook } 133db6fe4d6SKees Cook 134db6fe4d6SKees Cook static void fortify_test_control_flow_split(struct kunit *test) 135db6fe4d6SKees Cook { 136db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, want_minus_one(pick), SIZE_MAX); 137db6fe4d6SKees Cook } 138db6fe4d6SKees Cook 139db6fe4d6SKees Cook #define KUNIT_EXPECT_BOS(test, p, expected, name) \ 140db6fe4d6SKees Cook KUNIT_EXPECT_EQ_MSG(test, __builtin_object_size(p, 1), \ 141db6fe4d6SKees Cook expected, \ 142db6fe4d6SKees Cook "__alloc_size() not working with __bos on " name "\n") 143db6fe4d6SKees Cook 144db6fe4d6SKees Cook #if !__has_builtin(__builtin_dynamic_object_size) 145db6fe4d6SKees Cook #define KUNIT_EXPECT_BDOS(test, p, expected, name) \ 146db6fe4d6SKees Cook /* Silence "unused variable 'expected'" warning. */ \ 147db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, expected, expected) 148db6fe4d6SKees Cook #else 149db6fe4d6SKees Cook #define KUNIT_EXPECT_BDOS(test, p, expected, name) \ 150db6fe4d6SKees Cook KUNIT_EXPECT_EQ_MSG(test, __builtin_dynamic_object_size(p, 1), \ 151db6fe4d6SKees Cook expected, \ 152db6fe4d6SKees Cook "__alloc_size() not working with __bdos on " name "\n") 153db6fe4d6SKees Cook #endif 154db6fe4d6SKees Cook 155db6fe4d6SKees Cook /* If the execpted size is a constant value, __bos can see it. */ 156db6fe4d6SKees Cook #define check_const(_expected, alloc, free) do { \ 157db6fe4d6SKees Cook size_t expected = (_expected); \ 158db6fe4d6SKees Cook void *p = alloc; \ 159db6fe4d6SKees Cook KUNIT_EXPECT_TRUE_MSG(test, p != NULL, #alloc " failed?!\n"); \ 160db6fe4d6SKees Cook KUNIT_EXPECT_BOS(test, p, expected, #alloc); \ 161db6fe4d6SKees Cook KUNIT_EXPECT_BDOS(test, p, expected, #alloc); \ 162db6fe4d6SKees Cook free; \ 163db6fe4d6SKees Cook } while (0) 164db6fe4d6SKees Cook 165db6fe4d6SKees Cook /* If the execpted size is NOT a constant value, __bos CANNOT see it. */ 166db6fe4d6SKees Cook #define check_dynamic(_expected, alloc, free) do { \ 167db6fe4d6SKees Cook size_t expected = (_expected); \ 168db6fe4d6SKees Cook void *p = alloc; \ 169db6fe4d6SKees Cook KUNIT_EXPECT_TRUE_MSG(test, p != NULL, #alloc " failed?!\n"); \ 170db6fe4d6SKees Cook KUNIT_EXPECT_BOS(test, p, SIZE_MAX, #alloc); \ 171db6fe4d6SKees Cook KUNIT_EXPECT_BDOS(test, p, expected, #alloc); \ 172db6fe4d6SKees Cook free; \ 173db6fe4d6SKees Cook } while (0) 174db6fe4d6SKees Cook 175db6fe4d6SKees Cook /* Assortment of constant-value kinda-edge cases. */ 176db6fe4d6SKees Cook #define CONST_TEST_BODY(TEST_alloc) do { \ 177db6fe4d6SKees Cook /* Special-case vmalloc()-family to skip 0-sized allocs. */ \ 178db6fe4d6SKees Cook if (strcmp(#TEST_alloc, "TEST_vmalloc") != 0) \ 179db6fe4d6SKees Cook TEST_alloc(check_const, 0, 0); \ 180db6fe4d6SKees Cook TEST_alloc(check_const, 1, 1); \ 181db6fe4d6SKees Cook TEST_alloc(check_const, 128, 128); \ 182db6fe4d6SKees Cook TEST_alloc(check_const, 1023, 1023); \ 183db6fe4d6SKees Cook TEST_alloc(check_const, 1025, 1025); \ 184db6fe4d6SKees Cook TEST_alloc(check_const, 4096, 4096); \ 185db6fe4d6SKees Cook TEST_alloc(check_const, 4097, 4097); \ 186db6fe4d6SKees Cook } while (0) 187db6fe4d6SKees Cook 188db6fe4d6SKees Cook static volatile size_t zero_size; 189db6fe4d6SKees Cook static volatile size_t unknown_size = 50; 190db6fe4d6SKees Cook 191db6fe4d6SKees Cook #if !__has_builtin(__builtin_dynamic_object_size) 192db6fe4d6SKees Cook #define DYNAMIC_TEST_BODY(TEST_alloc) \ 193db6fe4d6SKees Cook kunit_skip(test, "Compiler is missing __builtin_dynamic_object_size() support\n") 194db6fe4d6SKees Cook #else 195db6fe4d6SKees Cook #define DYNAMIC_TEST_BODY(TEST_alloc) do { \ 196db6fe4d6SKees Cook size_t size = unknown_size; \ 197db6fe4d6SKees Cook \ 198db6fe4d6SKees Cook /* \ 199db6fe4d6SKees Cook * Expected size is "size" in each test, before it is then \ 200db6fe4d6SKees Cook * internally incremented in each test. Requires we disable \ 201db6fe4d6SKees Cook * -Wunsequenced. \ 202db6fe4d6SKees Cook */ \ 203db6fe4d6SKees Cook TEST_alloc(check_dynamic, size, size++); \ 204db6fe4d6SKees Cook /* Make sure incrementing actually happened. */ \ 205db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, size, unknown_size); \ 206db6fe4d6SKees Cook } while (0) 207db6fe4d6SKees Cook #endif 208db6fe4d6SKees Cook 209db6fe4d6SKees Cook #define DEFINE_ALLOC_SIZE_TEST_PAIR(allocator) \ 210db6fe4d6SKees Cook static void fortify_test_alloc_size_##allocator##_const(struct kunit *test) \ 211db6fe4d6SKees Cook { \ 212db6fe4d6SKees Cook CONST_TEST_BODY(TEST_##allocator); \ 213db6fe4d6SKees Cook } \ 214db6fe4d6SKees Cook static void fortify_test_alloc_size_##allocator##_dynamic(struct kunit *test) \ 215db6fe4d6SKees Cook { \ 216db6fe4d6SKees Cook DYNAMIC_TEST_BODY(TEST_##allocator); \ 217db6fe4d6SKees Cook } 218db6fe4d6SKees Cook 219db6fe4d6SKees Cook #define TEST_kmalloc(checker, expected_size, alloc_size) do { \ 220db6fe4d6SKees Cook gfp_t gfp = GFP_KERNEL | __GFP_NOWARN; \ 221db6fe4d6SKees Cook void *orig; \ 222db6fe4d6SKees Cook size_t len; \ 223db6fe4d6SKees Cook \ 224db6fe4d6SKees Cook checker(expected_size, kmalloc(alloc_size, gfp), \ 225db6fe4d6SKees Cook kfree(p)); \ 226db6fe4d6SKees Cook checker(expected_size, \ 227db6fe4d6SKees Cook kmalloc_node(alloc_size, gfp, NUMA_NO_NODE), \ 228db6fe4d6SKees Cook kfree(p)); \ 229db6fe4d6SKees Cook checker(expected_size, kzalloc(alloc_size, gfp), \ 230db6fe4d6SKees Cook kfree(p)); \ 231db6fe4d6SKees Cook checker(expected_size, \ 232db6fe4d6SKees Cook kzalloc_node(alloc_size, gfp, NUMA_NO_NODE), \ 233db6fe4d6SKees Cook kfree(p)); \ 234db6fe4d6SKees Cook checker(expected_size, kcalloc(1, alloc_size, gfp), \ 235db6fe4d6SKees Cook kfree(p)); \ 236db6fe4d6SKees Cook checker(expected_size, kcalloc(alloc_size, 1, gfp), \ 237db6fe4d6SKees Cook kfree(p)); \ 238db6fe4d6SKees Cook checker(expected_size, \ 239db6fe4d6SKees Cook kcalloc_node(1, alloc_size, gfp, NUMA_NO_NODE), \ 240db6fe4d6SKees Cook kfree(p)); \ 241db6fe4d6SKees Cook checker(expected_size, \ 242db6fe4d6SKees Cook kcalloc_node(alloc_size, 1, gfp, NUMA_NO_NODE), \ 243db6fe4d6SKees Cook kfree(p)); \ 244db6fe4d6SKees Cook checker(expected_size, kmalloc_array(1, alloc_size, gfp), \ 245db6fe4d6SKees Cook kfree(p)); \ 246db6fe4d6SKees Cook checker(expected_size, kmalloc_array(alloc_size, 1, gfp), \ 247db6fe4d6SKees Cook kfree(p)); \ 248db6fe4d6SKees Cook checker(expected_size, \ 249db6fe4d6SKees Cook kmalloc_array_node(1, alloc_size, gfp, NUMA_NO_NODE), \ 250db6fe4d6SKees Cook kfree(p)); \ 251db6fe4d6SKees Cook checker(expected_size, \ 252db6fe4d6SKees Cook kmalloc_array_node(alloc_size, 1, gfp, NUMA_NO_NODE), \ 253db6fe4d6SKees Cook kfree(p)); \ 254db6fe4d6SKees Cook \ 255db6fe4d6SKees Cook orig = kmalloc(alloc_size, gfp); \ 256db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, orig != NULL); \ 257db6fe4d6SKees Cook checker((expected_size) * 2, \ 258db6fe4d6SKees Cook krealloc(orig, (alloc_size) * 2, gfp), \ 259db6fe4d6SKees Cook kfree(p)); \ 260db6fe4d6SKees Cook orig = kmalloc(alloc_size, gfp); \ 261db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, orig != NULL); \ 262db6fe4d6SKees Cook checker((expected_size) * 2, \ 263db6fe4d6SKees Cook krealloc_array(orig, 1, (alloc_size) * 2, gfp), \ 264db6fe4d6SKees Cook kfree(p)); \ 265db6fe4d6SKees Cook orig = kmalloc(alloc_size, gfp); \ 266db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, orig != NULL); \ 267db6fe4d6SKees Cook checker((expected_size) * 2, \ 268db6fe4d6SKees Cook krealloc_array(orig, (alloc_size) * 2, 1, gfp), \ 269db6fe4d6SKees Cook kfree(p)); \ 270db6fe4d6SKees Cook \ 271db6fe4d6SKees Cook len = 11; \ 272db6fe4d6SKees Cook /* Using memdup() with fixed size, so force unknown length. */ \ 273db6fe4d6SKees Cook if (!__builtin_constant_p(expected_size)) \ 274db6fe4d6SKees Cook len += zero_size; \ 275db6fe4d6SKees Cook checker(len, kmemdup("hello there", len, gfp), kfree(p)); \ 276db6fe4d6SKees Cook } while (0) 277db6fe4d6SKees Cook DEFINE_ALLOC_SIZE_TEST_PAIR(kmalloc) 278db6fe4d6SKees Cook 279db6fe4d6SKees Cook /* Sizes are in pages, not bytes. */ 280db6fe4d6SKees Cook #define TEST_vmalloc(checker, expected_pages, alloc_pages) do { \ 281db6fe4d6SKees Cook gfp_t gfp = GFP_KERNEL | __GFP_NOWARN; \ 282db6fe4d6SKees Cook checker((expected_pages) * PAGE_SIZE, \ 283db6fe4d6SKees Cook vmalloc((alloc_pages) * PAGE_SIZE), vfree(p)); \ 284db6fe4d6SKees Cook checker((expected_pages) * PAGE_SIZE, \ 285db6fe4d6SKees Cook vzalloc((alloc_pages) * PAGE_SIZE), vfree(p)); \ 286db6fe4d6SKees Cook checker((expected_pages) * PAGE_SIZE, \ 287db6fe4d6SKees Cook __vmalloc((alloc_pages) * PAGE_SIZE, gfp), vfree(p)); \ 288db6fe4d6SKees Cook } while (0) 289db6fe4d6SKees Cook DEFINE_ALLOC_SIZE_TEST_PAIR(vmalloc) 290db6fe4d6SKees Cook 291db6fe4d6SKees Cook /* Sizes are in pages (and open-coded for side-effects), not bytes. */ 292db6fe4d6SKees Cook #define TEST_kvmalloc(checker, expected_pages, alloc_pages) do { \ 293db6fe4d6SKees Cook gfp_t gfp = GFP_KERNEL | __GFP_NOWARN; \ 294db6fe4d6SKees Cook size_t prev_size; \ 295db6fe4d6SKees Cook void *orig; \ 296db6fe4d6SKees Cook \ 297db6fe4d6SKees Cook checker((expected_pages) * PAGE_SIZE, \ 298db6fe4d6SKees Cook kvmalloc((alloc_pages) * PAGE_SIZE, gfp), \ 299db6fe4d6SKees Cook kvfree(p)); \ 300db6fe4d6SKees Cook checker((expected_pages) * PAGE_SIZE, \ 301db6fe4d6SKees Cook kvmalloc_node((alloc_pages) * PAGE_SIZE, gfp, NUMA_NO_NODE), \ 302db6fe4d6SKees Cook kvfree(p)); \ 303db6fe4d6SKees Cook checker((expected_pages) * PAGE_SIZE, \ 304db6fe4d6SKees Cook kvzalloc((alloc_pages) * PAGE_SIZE, gfp), \ 305db6fe4d6SKees Cook kvfree(p)); \ 306db6fe4d6SKees Cook checker((expected_pages) * PAGE_SIZE, \ 307db6fe4d6SKees Cook kvzalloc_node((alloc_pages) * PAGE_SIZE, gfp, NUMA_NO_NODE), \ 308db6fe4d6SKees Cook kvfree(p)); \ 309db6fe4d6SKees Cook checker((expected_pages) * PAGE_SIZE, \ 310db6fe4d6SKees Cook kvcalloc(1, (alloc_pages) * PAGE_SIZE, gfp), \ 311db6fe4d6SKees Cook kvfree(p)); \ 312db6fe4d6SKees Cook checker((expected_pages) * PAGE_SIZE, \ 313db6fe4d6SKees Cook kvcalloc((alloc_pages) * PAGE_SIZE, 1, gfp), \ 314db6fe4d6SKees Cook kvfree(p)); \ 315db6fe4d6SKees Cook checker((expected_pages) * PAGE_SIZE, \ 316db6fe4d6SKees Cook kvmalloc_array(1, (alloc_pages) * PAGE_SIZE, gfp), \ 317db6fe4d6SKees Cook kvfree(p)); \ 318db6fe4d6SKees Cook checker((expected_pages) * PAGE_SIZE, \ 319db6fe4d6SKees Cook kvmalloc_array((alloc_pages) * PAGE_SIZE, 1, gfp), \ 320db6fe4d6SKees Cook kvfree(p)); \ 321db6fe4d6SKees Cook \ 322db6fe4d6SKees Cook prev_size = (expected_pages) * PAGE_SIZE; \ 323db6fe4d6SKees Cook orig = kvmalloc(prev_size, gfp); \ 324db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, orig != NULL); \ 325db6fe4d6SKees Cook checker(((expected_pages) * PAGE_SIZE) * 2, \ 326db6fe4d6SKees Cook kvrealloc(orig, ((alloc_pages) * PAGE_SIZE) * 2, gfp), \ 327db6fe4d6SKees Cook kvfree(p)); \ 328db6fe4d6SKees Cook } while (0) 329db6fe4d6SKees Cook DEFINE_ALLOC_SIZE_TEST_PAIR(kvmalloc) 330db6fe4d6SKees Cook 331db6fe4d6SKees Cook #define TEST_devm_kmalloc(checker, expected_size, alloc_size) do { \ 332db6fe4d6SKees Cook gfp_t gfp = GFP_KERNEL | __GFP_NOWARN; \ 333db6fe4d6SKees Cook const char dev_name[] = "fortify-test"; \ 334db6fe4d6SKees Cook struct device *dev; \ 335db6fe4d6SKees Cook void *orig; \ 336db6fe4d6SKees Cook size_t len; \ 337db6fe4d6SKees Cook \ 338db6fe4d6SKees Cook /* Create dummy device for devm_kmalloc()-family tests. */ \ 339db6fe4d6SKees Cook dev = kunit_device_register(test, dev_name); \ 340db6fe4d6SKees Cook KUNIT_ASSERT_FALSE_MSG(test, IS_ERR(dev), \ 341db6fe4d6SKees Cook "Cannot register test device\n"); \ 342db6fe4d6SKees Cook \ 343db6fe4d6SKees Cook checker(expected_size, devm_kmalloc(dev, alloc_size, gfp), \ 344db6fe4d6SKees Cook devm_kfree(dev, p)); \ 345db6fe4d6SKees Cook checker(expected_size, devm_kzalloc(dev, alloc_size, gfp), \ 346db6fe4d6SKees Cook devm_kfree(dev, p)); \ 347db6fe4d6SKees Cook checker(expected_size, \ 348db6fe4d6SKees Cook devm_kmalloc_array(dev, 1, alloc_size, gfp), \ 349db6fe4d6SKees Cook devm_kfree(dev, p)); \ 350db6fe4d6SKees Cook checker(expected_size, \ 351db6fe4d6SKees Cook devm_kmalloc_array(dev, alloc_size, 1, gfp), \ 352db6fe4d6SKees Cook devm_kfree(dev, p)); \ 353db6fe4d6SKees Cook checker(expected_size, \ 354db6fe4d6SKees Cook devm_kcalloc(dev, 1, alloc_size, gfp), \ 355db6fe4d6SKees Cook devm_kfree(dev, p)); \ 356db6fe4d6SKees Cook checker(expected_size, \ 357db6fe4d6SKees Cook devm_kcalloc(dev, alloc_size, 1, gfp), \ 358db6fe4d6SKees Cook devm_kfree(dev, p)); \ 359db6fe4d6SKees Cook \ 360db6fe4d6SKees Cook orig = devm_kmalloc(dev, alloc_size, gfp); \ 361db6fe4d6SKees Cook KUNIT_EXPECT_TRUE(test, orig != NULL); \ 362db6fe4d6SKees Cook checker((expected_size) * 2, \ 363db6fe4d6SKees Cook devm_krealloc(dev, orig, (alloc_size) * 2, gfp), \ 364db6fe4d6SKees Cook devm_kfree(dev, p)); \ 365db6fe4d6SKees Cook \ 366db6fe4d6SKees Cook len = 4; \ 367db6fe4d6SKees Cook /* Using memdup() with fixed size, so force unknown length. */ \ 368db6fe4d6SKees Cook if (!__builtin_constant_p(expected_size)) \ 369db6fe4d6SKees Cook len += zero_size; \ 370db6fe4d6SKees Cook checker(len, devm_kmemdup(dev, "Ohai", len, gfp), \ 371db6fe4d6SKees Cook devm_kfree(dev, p)); \ 372db6fe4d6SKees Cook \ 373db6fe4d6SKees Cook kunit_device_unregister(test, dev); \ 374db6fe4d6SKees Cook } while (0) 375db6fe4d6SKees Cook DEFINE_ALLOC_SIZE_TEST_PAIR(devm_kmalloc) 376db6fe4d6SKees Cook 377db6fe4d6SKees Cook static const char * const test_strs[] = { 378db6fe4d6SKees Cook "", 379db6fe4d6SKees Cook "Hello there", 380db6fe4d6SKees Cook "A longer string, just for variety", 381db6fe4d6SKees Cook }; 382db6fe4d6SKees Cook 383db6fe4d6SKees Cook #define TEST_realloc(checker) do { \ 384db6fe4d6SKees Cook gfp_t gfp = GFP_KERNEL; \ 385db6fe4d6SKees Cook size_t len; \ 386db6fe4d6SKees Cook int i; \ 387db6fe4d6SKees Cook \ 388db6fe4d6SKees Cook for (i = 0; i < ARRAY_SIZE(test_strs); i++) { \ 389db6fe4d6SKees Cook len = strlen(test_strs[i]); \ 390db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, __builtin_constant_p(len), 0); \ 391db6fe4d6SKees Cook checker(len, kmemdup_array(test_strs[i], 1, len, gfp), \ 392db6fe4d6SKees Cook kfree(p)); \ 393db6fe4d6SKees Cook checker(len, kmemdup(test_strs[i], len, gfp), \ 394db6fe4d6SKees Cook kfree(p)); \ 395db6fe4d6SKees Cook } \ 396db6fe4d6SKees Cook } while (0) 397db6fe4d6SKees Cook static void fortify_test_realloc_size(struct kunit *test) 398db6fe4d6SKees Cook { 399db6fe4d6SKees Cook TEST_realloc(check_dynamic); 400db6fe4d6SKees Cook } 401db6fe4d6SKees Cook 402db6fe4d6SKees Cook /* 403db6fe4d6SKees Cook * We can't have an array at the end of a structure or else 404db6fe4d6SKees Cook * builds without -fstrict-flex-arrays=3 will report them as 405db6fe4d6SKees Cook * being an unknown length. Additionally, add bytes before 406db6fe4d6SKees Cook * and after the string to catch over/underflows if tests 407db6fe4d6SKees Cook * fail. 408db6fe4d6SKees Cook */ 409db6fe4d6SKees Cook struct fortify_padding { 410db6fe4d6SKees Cook unsigned long bytes_before; 411db6fe4d6SKees Cook char buf[32]; 412db6fe4d6SKees Cook unsigned long bytes_after; 413db6fe4d6SKees Cook }; 414db6fe4d6SKees Cook 415db6fe4d6SKees Cook static void fortify_test_strlen(struct kunit *test) 416db6fe4d6SKees Cook { 417db6fe4d6SKees Cook struct fortify_padding pad = { }; 418db6fe4d6SKees Cook int i, end = sizeof(pad.buf) - 1; 419db6fe4d6SKees Cook 420db6fe4d6SKees Cook /* Fill 31 bytes with valid characters. */ 421db6fe4d6SKees Cook for (i = 0; i < sizeof(pad.buf) - 1; i++) 422db6fe4d6SKees Cook pad.buf[i] = i + '0'; 423db6fe4d6SKees Cook /* Trailing bytes are still %NUL. */ 424db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[end], '\0'); 425db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 426db6fe4d6SKees Cook 427db6fe4d6SKees Cook /* String is terminated, so strlen() is valid. */ 428db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlen(pad.buf), end); 429db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 430db6fe4d6SKees Cook 431db6fe4d6SKees Cook /* Make string unterminated, and recount. */ 432db6fe4d6SKees Cook pad.buf[end] = 'A'; 433db6fe4d6SKees Cook end = sizeof(pad.buf); 434db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strlen(pad.buf), end); 435db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1); 436db6fe4d6SKees Cook } 437db6fe4d6SKees Cook 438db6fe4d6SKees Cook static void fortify_test_strnlen(struct kunit *test) 439db6fe4d6SKees Cook { 440db6fe4d6SKees Cook struct fortify_padding pad = { }; 441db6fe4d6SKees Cook int i, end = sizeof(pad.buf) - 1; 442db6fe4d6SKees Cook 443db6fe4d6SKees Cook /* Fill 31 bytes with valid characters. */ 444db6fe4d6SKees Cook for (i = 0; i < sizeof(pad.buf) - 1; i++) 445db6fe4d6SKees Cook pad.buf[i] = i + '0'; 446db6fe4d6SKees Cook /* Trailing bytes are still %NUL. */ 447db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[end], '\0'); 448db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 449db6fe4d6SKees Cook 450db6fe4d6SKees Cook /* String is terminated, so strnlen() is valid. */ 451db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strnlen(pad.buf, sizeof(pad.buf)), end); 452db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 453db6fe4d6SKees Cook /* A truncated strnlen() will be safe, too. */ 454db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strnlen(pad.buf, sizeof(pad.buf) / 2), 455db6fe4d6SKees Cook sizeof(pad.buf) / 2); 456db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 457db6fe4d6SKees Cook 458db6fe4d6SKees Cook /* Make string unterminated, and recount. */ 459db6fe4d6SKees Cook pad.buf[end] = 'A'; 460db6fe4d6SKees Cook end = sizeof(pad.buf); 461db6fe4d6SKees Cook /* Reading beyond with strncpy() will fail. */ 462db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end + 1), end); 463db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1); 464db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end + 2), end); 465db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 466db6fe4d6SKees Cook 467db6fe4d6SKees Cook /* Early-truncated is safe still, though. */ 468db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end), end); 469db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 470db6fe4d6SKees Cook 471db6fe4d6SKees Cook end = sizeof(pad.buf) / 2; 472db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end), end); 473db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 474db6fe4d6SKees Cook } 475db6fe4d6SKees Cook 476db6fe4d6SKees Cook static void fortify_test_strcpy(struct kunit *test) 477db6fe4d6SKees Cook { 478db6fe4d6SKees Cook struct fortify_padding pad = { }; 479db6fe4d6SKees Cook char src[sizeof(pad.buf) + 1] = { }; 480db6fe4d6SKees Cook int i; 481db6fe4d6SKees Cook 482db6fe4d6SKees Cook /* Fill 31 bytes with valid characters. */ 483db6fe4d6SKees Cook for (i = 0; i < sizeof(src) - 2; i++) 484db6fe4d6SKees Cook src[i] = i + '0'; 485db6fe4d6SKees Cook 486db6fe4d6SKees Cook /* Destination is %NUL-filled to start with. */ 487db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_before, 0); 488db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 489db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 490db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 491db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 492db6fe4d6SKees Cook 493db6fe4d6SKees Cook /* Legitimate strcpy() 1 less than of max size. */ 494db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strcpy(pad.buf, src) 495db6fe4d6SKees Cook == pad.buf); 496db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 497db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 498db6fe4d6SKees Cook /* Only last byte should be %NUL */ 499db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 500db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 501db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 502db6fe4d6SKees Cook 503db6fe4d6SKees Cook src[sizeof(src) - 2] = 'A'; 504db6fe4d6SKees Cook /* But now we trip the overflow checking. */ 505db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strcpy(pad.buf, src) 506db6fe4d6SKees Cook == pad.buf); 507db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 508db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1); 509db6fe4d6SKees Cook /* Trailing %NUL -- thanks to FORTIFY. */ 510db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 511db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 512db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 513db6fe4d6SKees Cook /* And we will not have gone beyond. */ 514db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 515db6fe4d6SKees Cook 516db6fe4d6SKees Cook src[sizeof(src) - 1] = 'A'; 517db6fe4d6SKees Cook /* And for sure now, two bytes past. */ 518db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strcpy(pad.buf, src) 519db6fe4d6SKees Cook == pad.buf); 520db6fe4d6SKees Cook /* 521db6fe4d6SKees Cook * Which trips both the strlen() on the unterminated src, 522db6fe4d6SKees Cook * and the resulting copy attempt. 523db6fe4d6SKees Cook */ 524db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1); 525db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2); 526db6fe4d6SKees Cook /* Trailing %NUL -- thanks to FORTIFY. */ 527db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 528db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 529db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 530db6fe4d6SKees Cook /* And we will not have gone beyond. */ 531db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 532db6fe4d6SKees Cook } 533db6fe4d6SKees Cook 534db6fe4d6SKees Cook static void fortify_test_strncpy(struct kunit *test) 535db6fe4d6SKees Cook { 536db6fe4d6SKees Cook struct fortify_padding pad = { }; 537db6fe4d6SKees Cook char src[] = "Copy me fully into a small buffer and I will overflow!"; 538*6ee149f6SKees Cook size_t sizeof_buf = sizeof(pad.buf); 539*6ee149f6SKees Cook 540*6ee149f6SKees Cook OPTIMIZER_HIDE_VAR(sizeof_buf); 541db6fe4d6SKees Cook 542db6fe4d6SKees Cook /* Destination is %NUL-filled to start with. */ 543db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_before, 0); 544*6ee149f6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof_buf - 1], '\0'); 545*6ee149f6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof_buf - 2], '\0'); 546*6ee149f6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof_buf - 3], '\0'); 547db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 548db6fe4d6SKees Cook 549db6fe4d6SKees Cook /* Legitimate strncpy() 1 less than of max size. */ 550*6ee149f6SKees Cook KUNIT_ASSERT_TRUE(test, strncpy(pad.buf, src, sizeof_buf - 1) 551db6fe4d6SKees Cook == pad.buf); 552db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 553db6fe4d6SKees Cook /* Only last byte should be %NUL */ 554*6ee149f6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof_buf - 1], '\0'); 555*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 556*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 3], '\0'); 557db6fe4d6SKees Cook 558db6fe4d6SKees Cook /* Legitimate (though unterminated) max-size strncpy. */ 559*6ee149f6SKees Cook KUNIT_ASSERT_TRUE(test, strncpy(pad.buf, src, sizeof_buf) 560db6fe4d6SKees Cook == pad.buf); 561db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 562db6fe4d6SKees Cook /* No trailing %NUL -- thanks strncpy API. */ 563*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 1], '\0'); 564*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 565*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 566db6fe4d6SKees Cook /* But we will not have gone beyond. */ 567db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 568db6fe4d6SKees Cook 569db6fe4d6SKees Cook /* Now verify that FORTIFY is working... */ 570*6ee149f6SKees Cook KUNIT_ASSERT_TRUE(test, strncpy(pad.buf, src, sizeof_buf + 1) 571db6fe4d6SKees Cook == pad.buf); 572db6fe4d6SKees Cook /* Should catch the overflow. */ 573db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1); 574*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 1], '\0'); 575*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 576*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 577db6fe4d6SKees Cook /* And we will not have gone beyond. */ 578db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 579db6fe4d6SKees Cook 580db6fe4d6SKees Cook /* And further... */ 581*6ee149f6SKees Cook KUNIT_ASSERT_TRUE(test, strncpy(pad.buf, src, sizeof_buf + 2) 582db6fe4d6SKees Cook == pad.buf); 583db6fe4d6SKees Cook /* Should catch the overflow. */ 584db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2); 585*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 1], '\0'); 586*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 587*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 588db6fe4d6SKees Cook /* And we will not have gone beyond. */ 589db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 590db6fe4d6SKees Cook } 591db6fe4d6SKees Cook 592db6fe4d6SKees Cook static void fortify_test_strscpy(struct kunit *test) 593db6fe4d6SKees Cook { 594db6fe4d6SKees Cook struct fortify_padding pad = { }; 595db6fe4d6SKees Cook char src[] = "Copy me fully into a small buffer and I will overflow!"; 596*6ee149f6SKees Cook size_t sizeof_buf = sizeof(pad.buf); 597*6ee149f6SKees Cook size_t sizeof_src = sizeof(src); 598*6ee149f6SKees Cook 599*6ee149f6SKees Cook OPTIMIZER_HIDE_VAR(sizeof_buf); 600*6ee149f6SKees Cook OPTIMIZER_HIDE_VAR(sizeof_src); 601db6fe4d6SKees Cook 602db6fe4d6SKees Cook /* Destination is %NUL-filled to start with. */ 603db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_before, 0); 604*6ee149f6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof_buf - 1], '\0'); 605*6ee149f6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof_buf - 2], '\0'); 606*6ee149f6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof_buf - 3], '\0'); 607db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 608db6fe4d6SKees Cook 609db6fe4d6SKees Cook /* Legitimate strscpy() 1 less than of max size. */ 610*6ee149f6SKees Cook KUNIT_ASSERT_EQ(test, strscpy(pad.buf, src, sizeof_buf - 1), 611db6fe4d6SKees Cook -E2BIG); 612db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 613db6fe4d6SKees Cook /* Keeping space for %NUL, last two bytes should be %NUL */ 614*6ee149f6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof_buf - 1], '\0'); 615*6ee149f6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof_buf - 2], '\0'); 616*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 3], '\0'); 617db6fe4d6SKees Cook 618db6fe4d6SKees Cook /* Legitimate max-size strscpy. */ 619*6ee149f6SKees Cook KUNIT_ASSERT_EQ(test, strscpy(pad.buf, src, sizeof_buf), 620db6fe4d6SKees Cook -E2BIG); 621db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 622db6fe4d6SKees Cook /* A trailing %NUL will exist. */ 623*6ee149f6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof_buf - 1], '\0'); 624*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 625*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 626db6fe4d6SKees Cook 627db6fe4d6SKees Cook /* Now verify that FORTIFY is working... */ 628*6ee149f6SKees Cook KUNIT_ASSERT_EQ(test, strscpy(pad.buf, src, sizeof_buf + 1), 629db6fe4d6SKees Cook -E2BIG); 630db6fe4d6SKees Cook /* Should catch the overflow. */ 631db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1); 632*6ee149f6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof_buf - 1], '\0'); 633*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 634*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 635db6fe4d6SKees Cook /* And we will not have gone beyond. */ 636db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 637db6fe4d6SKees Cook 638db6fe4d6SKees Cook /* And much further... */ 639*6ee149f6SKees Cook KUNIT_ASSERT_EQ(test, strscpy(pad.buf, src, sizeof_src * 2), 640db6fe4d6SKees Cook -E2BIG); 641db6fe4d6SKees Cook /* Should catch the overflow. */ 642db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2); 643*6ee149f6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof_buf - 1], '\0'); 644*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 645*6ee149f6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof_buf - 2], '\0'); 646db6fe4d6SKees Cook /* And we will not have gone beyond. */ 647db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 648db6fe4d6SKees Cook } 649db6fe4d6SKees Cook 650db6fe4d6SKees Cook static void fortify_test_strcat(struct kunit *test) 651db6fe4d6SKees Cook { 652db6fe4d6SKees Cook struct fortify_padding pad = { }; 653db6fe4d6SKees Cook char src[sizeof(pad.buf) / 2] = { }; 654db6fe4d6SKees Cook char one[] = "A"; 655db6fe4d6SKees Cook char two[] = "BC"; 656db6fe4d6SKees Cook int i; 657db6fe4d6SKees Cook 658db6fe4d6SKees Cook /* Fill 15 bytes with valid characters. */ 659db6fe4d6SKees Cook for (i = 0; i < sizeof(src) - 1; i++) 660db6fe4d6SKees Cook src[i] = i + 'A'; 661db6fe4d6SKees Cook 662db6fe4d6SKees Cook /* Destination is %NUL-filled to start with. */ 663db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_before, 0); 664db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 665db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 666db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 667db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 668db6fe4d6SKees Cook 669db6fe4d6SKees Cook /* Legitimate strcat() using less than half max size. */ 670db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strcat(pad.buf, src) == pad.buf); 671db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 672db6fe4d6SKees Cook /* Legitimate strcat() now 2 bytes shy of end. */ 673db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strcat(pad.buf, src) == pad.buf); 674db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 675db6fe4d6SKees Cook /* Last two bytes should be %NUL */ 676db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 677db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 678db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 679db6fe4d6SKees Cook 680db6fe4d6SKees Cook /* Add one more character to the end. */ 681db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strcat(pad.buf, one) == pad.buf); 682db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 683db6fe4d6SKees Cook /* Last byte should be %NUL */ 684db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 685db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 686db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 687db6fe4d6SKees Cook 688db6fe4d6SKees Cook /* And this one char will overflow. */ 689db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strcat(pad.buf, one) == pad.buf); 690db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1); 691db6fe4d6SKees Cook /* Last byte should be %NUL thanks to FORTIFY. */ 692db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 693db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 694db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 695db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 696db6fe4d6SKees Cook 697db6fe4d6SKees Cook /* And adding two will overflow more. */ 698db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strcat(pad.buf, two) == pad.buf); 699db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2); 700db6fe4d6SKees Cook /* Last byte should be %NUL thanks to FORTIFY. */ 701db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 702db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 703db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 704db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 705db6fe4d6SKees Cook } 706db6fe4d6SKees Cook 707db6fe4d6SKees Cook static void fortify_test_strncat(struct kunit *test) 708db6fe4d6SKees Cook { 709db6fe4d6SKees Cook struct fortify_padding pad = { }; 710db6fe4d6SKees Cook char src[sizeof(pad.buf)] = { }; 711db6fe4d6SKees Cook int i, partial; 712db6fe4d6SKees Cook 713db6fe4d6SKees Cook /* Fill 31 bytes with valid characters. */ 714db6fe4d6SKees Cook partial = sizeof(src) / 2 - 1; 715db6fe4d6SKees Cook for (i = 0; i < partial; i++) 716db6fe4d6SKees Cook src[i] = i + 'A'; 717db6fe4d6SKees Cook 718db6fe4d6SKees Cook /* Destination is %NUL-filled to start with. */ 719db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_before, 0); 720db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 721db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 722db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 723db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 724db6fe4d6SKees Cook 725db6fe4d6SKees Cook /* Legitimate strncat() using less than half max size. */ 726db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, partial) == pad.buf); 727db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 728db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 729db6fe4d6SKees Cook /* Legitimate strncat() now 2 bytes shy of end. */ 730db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, partial) == pad.buf); 731db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 732db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 733db6fe4d6SKees Cook /* Last two bytes should be %NUL */ 734db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 735db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 736db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 737db6fe4d6SKees Cook 738db6fe4d6SKees Cook /* Add one more character to the end. */ 739db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, 1) == pad.buf); 740db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 741db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 742db6fe4d6SKees Cook /* Last byte should be %NUL */ 743db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 744db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 745db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 746db6fe4d6SKees Cook 747db6fe4d6SKees Cook /* And this one char will overflow. */ 748db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, 1) == pad.buf); 749db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 750db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1); 751db6fe4d6SKees Cook /* Last byte should be %NUL thanks to FORTIFY. */ 752db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 753db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 754db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 755db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 756db6fe4d6SKees Cook 757db6fe4d6SKees Cook /* And adding two will overflow more. */ 758db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, 2) == pad.buf); 759db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 760db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2); 761db6fe4d6SKees Cook /* Last byte should be %NUL thanks to FORTIFY. */ 762db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 763db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 764db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 765db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 766db6fe4d6SKees Cook 767db6fe4d6SKees Cook /* Force an unterminated destination, and overflow. */ 768db6fe4d6SKees Cook pad.buf[sizeof(pad.buf) - 1] = 'A'; 769db6fe4d6SKees Cook KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, 1) == pad.buf); 770db6fe4d6SKees Cook /* This will have tripped both strlen() and strcat(). */ 771db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1); 772db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 3); 773db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 774db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 775db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 776db6fe4d6SKees Cook /* But we should not go beyond the end. */ 777db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 778db6fe4d6SKees Cook } 779db6fe4d6SKees Cook 780db6fe4d6SKees Cook static void fortify_test_strlcat(struct kunit *test) 781db6fe4d6SKees Cook { 782db6fe4d6SKees Cook struct fortify_padding pad = { }; 783db6fe4d6SKees Cook char src[sizeof(pad.buf)] = { }; 784db6fe4d6SKees Cook int i, partial; 785*6ee149f6SKees Cook int len = sizeof(pad.buf); 786*6ee149f6SKees Cook 787*6ee149f6SKees Cook OPTIMIZER_HIDE_VAR(len); 788db6fe4d6SKees Cook 789db6fe4d6SKees Cook /* Fill 15 bytes with valid characters. */ 790db6fe4d6SKees Cook partial = sizeof(src) / 2 - 1; 791db6fe4d6SKees Cook for (i = 0; i < partial; i++) 792db6fe4d6SKees Cook src[i] = i + 'A'; 793db6fe4d6SKees Cook 794db6fe4d6SKees Cook /* Destination is %NUL-filled to start with. */ 795db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_before, 0); 796db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 797db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 798db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 799db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 800db6fe4d6SKees Cook 801db6fe4d6SKees Cook /* Legitimate strlcat() using less than half max size. */ 802db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, strlcat(pad.buf, src, len), partial); 803db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 804db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 805db6fe4d6SKees Cook /* Legitimate strlcat() now 2 bytes shy of end. */ 806db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, strlcat(pad.buf, src, len), partial * 2); 807db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 808db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 809db6fe4d6SKees Cook /* Last two bytes should be %NUL */ 810db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 811db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 812db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 813db6fe4d6SKees Cook 814db6fe4d6SKees Cook /* Add one more character to the end. */ 815db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, strlcat(pad.buf, "Q", len), partial * 2 + 1); 816db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 817db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); 818db6fe4d6SKees Cook /* Last byte should be %NUL */ 819db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 820db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 821db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 822db6fe4d6SKees Cook 823db6fe4d6SKees Cook /* And this one char will overflow. */ 824db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, strlcat(pad.buf, "V", len * 2), len); 825db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 826db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1); 827db6fe4d6SKees Cook /* Last byte should be %NUL thanks to FORTIFY. */ 828db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 829db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 830db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 831db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 832db6fe4d6SKees Cook 833db6fe4d6SKees Cook /* And adding two will overflow more. */ 834db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, strlcat(pad.buf, "QQ", len * 2), len + 1); 835db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 836db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2); 837db6fe4d6SKees Cook /* Last byte should be %NUL thanks to FORTIFY. */ 838db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 839db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 840db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 841db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 842db6fe4d6SKees Cook 843db6fe4d6SKees Cook /* Force an unterminated destination, and overflow. */ 844db6fe4d6SKees Cook pad.buf[sizeof(pad.buf) - 1] = 'A'; 845db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, strlcat(pad.buf, "TT", len * 2), len + 2); 846db6fe4d6SKees Cook /* This will have tripped both strlen() and strlcat(). */ 847db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 848db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2); 849db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 850db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0'); 851db6fe4d6SKees Cook KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0'); 852db6fe4d6SKees Cook /* But we should not go beyond the end. */ 853db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 854db6fe4d6SKees Cook 855db6fe4d6SKees Cook /* Force an unterminated source, and overflow. */ 856db6fe4d6SKees Cook memset(src, 'B', sizeof(src)); 857db6fe4d6SKees Cook pad.buf[sizeof(pad.buf) - 1] = '\0'; 858db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, strlcat(pad.buf, src, len * 3), len - 1 + sizeof(src)); 859db6fe4d6SKees Cook /* This will have tripped both strlen() and strlcat(). */ 860db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 3); 861db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 3); 862db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0'); 863db6fe4d6SKees Cook /* But we should not go beyond the end. */ 864db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 865db6fe4d6SKees Cook } 866db6fe4d6SKees Cook 867db6fe4d6SKees Cook /* Check for 0-sized arrays... */ 868db6fe4d6SKees Cook struct fortify_zero_sized { 869db6fe4d6SKees Cook unsigned long bytes_before; 870db6fe4d6SKees Cook char buf[0]; 871db6fe4d6SKees Cook unsigned long bytes_after; 872db6fe4d6SKees Cook }; 873db6fe4d6SKees Cook 874db6fe4d6SKees Cook #define __fortify_test(memfunc) \ 875db6fe4d6SKees Cook static void fortify_test_##memfunc(struct kunit *test) \ 876db6fe4d6SKees Cook { \ 877*6ee149f6SKees Cook struct fortify_zero_sized empty = { }; \ 878db6fe4d6SKees Cook struct fortify_padding pad = { }; \ 879db6fe4d6SKees Cook char srcA[sizeof(pad.buf) + 2]; \ 880db6fe4d6SKees Cook char srcB[sizeof(pad.buf) + 2]; \ 881*6ee149f6SKees Cook size_t len = sizeof(pad.buf); \ 882*6ee149f6SKees Cook size_t zero = 0; \ 883*6ee149f6SKees Cook \ 884*6ee149f6SKees Cook OPTIMIZER_HIDE_VAR(len); \ 885*6ee149f6SKees Cook OPTIMIZER_HIDE_VAR(zero); \ 886db6fe4d6SKees Cook \ 887db6fe4d6SKees Cook memset(srcA, 'A', sizeof(srcA)); \ 888db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, srcA[0], 'A'); \ 889db6fe4d6SKees Cook memset(srcB, 'B', sizeof(srcB)); \ 890db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, srcB[0], 'B'); \ 891db6fe4d6SKees Cook \ 892*6ee149f6SKees Cook memfunc(pad.buf, srcA, zero); \ 893db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[0], '\0'); \ 894db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 895db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 896*6ee149f6SKees Cook memfunc(pad.buf + 1, srcB, zero + 1); \ 897db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[0], '\0'); \ 898db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[1], 'B'); \ 899db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[2], '\0'); \ 900db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 901db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 902*6ee149f6SKees Cook memfunc(pad.buf, srcA, zero + 1); \ 903db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[0], 'A'); \ 904db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[1], 'B'); \ 905db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 906db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 907db6fe4d6SKees Cook memfunc(pad.buf, srcA, len - 1); \ 908db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[1], 'A'); \ 909db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[len - 1], '\0'); \ 910db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 911db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 912db6fe4d6SKees Cook memfunc(pad.buf, srcA, len); \ 913db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[1], 'A'); \ 914db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.buf[len - 1], 'A'); \ 915db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); \ 916db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 917db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 918db6fe4d6SKees Cook memfunc(pad.buf, srcA, len + 1); \ 919db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 920db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1); \ 921db6fe4d6SKees Cook memfunc(pad.buf + 1, srcB, len); \ 922db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 923db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2); \ 924db6fe4d6SKees Cook \ 925db6fe4d6SKees Cook /* Reset error counter. */ \ 926db6fe4d6SKees Cook fortify_write_overflows = 0; \ 927db6fe4d6SKees Cook /* Copy nothing into nothing: no errors. */ \ 928*6ee149f6SKees Cook memfunc(empty.buf, srcB, zero); \ 929db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 930db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 931*6ee149f6SKees Cook memfunc(empty.buf, srcB, zero + 1); \ 932db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 933db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1); \ 934db6fe4d6SKees Cook } 935db6fe4d6SKees Cook __fortify_test(memcpy) 936db6fe4d6SKees Cook __fortify_test(memmove) 937db6fe4d6SKees Cook 938db6fe4d6SKees Cook static void fortify_test_memscan(struct kunit *test) 939db6fe4d6SKees Cook { 940db6fe4d6SKees Cook char haystack[] = "Where oh where is my memory range?"; 941db6fe4d6SKees Cook char *mem = haystack + strlen("Where oh where is "); 942db6fe4d6SKees Cook char needle = 'm'; 943*6ee149f6SKees Cook size_t len = sizeof(haystack); 944*6ee149f6SKees Cook 945*6ee149f6SKees Cook OPTIMIZER_HIDE_VAR(len); 946db6fe4d6SKees Cook 947db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, memscan(haystack, needle, len), 948db6fe4d6SKees Cook mem); 949db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 950db6fe4d6SKees Cook /* Catch too-large range. */ 951db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, memscan(haystack, needle, len + 1), 952db6fe4d6SKees Cook NULL); 953db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1); 954db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, memscan(haystack, needle, len * 2), 955db6fe4d6SKees Cook NULL); 956db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 957db6fe4d6SKees Cook } 958db6fe4d6SKees Cook 959db6fe4d6SKees Cook static void fortify_test_memchr(struct kunit *test) 960db6fe4d6SKees Cook { 961db6fe4d6SKees Cook char haystack[] = "Where oh where is my memory range?"; 962db6fe4d6SKees Cook char *mem = haystack + strlen("Where oh where is "); 963db6fe4d6SKees Cook char needle = 'm'; 964*6ee149f6SKees Cook size_t len = sizeof(haystack); 965*6ee149f6SKees Cook 966*6ee149f6SKees Cook OPTIMIZER_HIDE_VAR(len); 967db6fe4d6SKees Cook 968db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, memchr(haystack, needle, len), 969db6fe4d6SKees Cook mem); 970db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 971db6fe4d6SKees Cook /* Catch too-large range. */ 972db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, memchr(haystack, needle, len + 1), 973db6fe4d6SKees Cook NULL); 974db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1); 975db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, memchr(haystack, needle, len * 2), 976db6fe4d6SKees Cook NULL); 977db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 978db6fe4d6SKees Cook } 979db6fe4d6SKees Cook 980db6fe4d6SKees Cook static void fortify_test_memchr_inv(struct kunit *test) 981db6fe4d6SKees Cook { 982db6fe4d6SKees Cook char haystack[] = "Where oh where is my memory range?"; 983db6fe4d6SKees Cook char *mem = haystack + 1; 984db6fe4d6SKees Cook char needle = 'W'; 985*6ee149f6SKees Cook size_t len = sizeof(haystack); 986*6ee149f6SKees Cook 987*6ee149f6SKees Cook OPTIMIZER_HIDE_VAR(len); 988db6fe4d6SKees Cook 989db6fe4d6SKees Cook /* Normal search is okay. */ 990db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, memchr_inv(haystack, needle, len), 991db6fe4d6SKees Cook mem); 992db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 993db6fe4d6SKees Cook /* Catch too-large range. */ 994db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, memchr_inv(haystack, needle, len + 1), 995db6fe4d6SKees Cook NULL); 996db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1); 997db6fe4d6SKees Cook KUNIT_ASSERT_PTR_EQ(test, memchr_inv(haystack, needle, len * 2), 998db6fe4d6SKees Cook NULL); 999db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 1000db6fe4d6SKees Cook } 1001db6fe4d6SKees Cook 1002db6fe4d6SKees Cook static void fortify_test_memcmp(struct kunit *test) 1003db6fe4d6SKees Cook { 1004db6fe4d6SKees Cook char one[] = "My mind is going ..."; 1005db6fe4d6SKees Cook char two[] = "My mind is going ... I can feel it."; 1006*6ee149f6SKees Cook size_t one_len = sizeof(one) - 1; 1007*6ee149f6SKees Cook size_t two_len = sizeof(two) - 1; 1008*6ee149f6SKees Cook 1009*6ee149f6SKees Cook OPTIMIZER_HIDE_VAR(one_len); 1010*6ee149f6SKees Cook OPTIMIZER_HIDE_VAR(two_len); 1011db6fe4d6SKees Cook 1012db6fe4d6SKees Cook /* We match the first string (ignoring the %NUL). */ 1013db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, memcmp(one, two, one_len), 0); 1014db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 1015db6fe4d6SKees Cook /* Still in bounds, but no longer matching. */ 1016db6fe4d6SKees Cook KUNIT_ASSERT_LT(test, memcmp(one, two, one_len + 1), 0); 1017db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 1018db6fe4d6SKees Cook 1019db6fe4d6SKees Cook /* Catch too-large ranges. */ 1020db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, memcmp(one, two, one_len + 2), INT_MIN); 1021db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1); 1022db6fe4d6SKees Cook 1023db6fe4d6SKees Cook KUNIT_ASSERT_EQ(test, memcmp(two, one, two_len + 2), INT_MIN); 1024db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 1025db6fe4d6SKees Cook } 1026db6fe4d6SKees Cook 1027db6fe4d6SKees Cook static void fortify_test_kmemdup(struct kunit *test) 1028db6fe4d6SKees Cook { 1029db6fe4d6SKees Cook char src[] = "I got Doom running on it!"; 1030db6fe4d6SKees Cook char *copy; 1031*6ee149f6SKees Cook size_t len = sizeof(src); 1032*6ee149f6SKees Cook 1033*6ee149f6SKees Cook OPTIMIZER_HIDE_VAR(len); 1034db6fe4d6SKees Cook 1035db6fe4d6SKees Cook /* Copy is within bounds. */ 1036db6fe4d6SKees Cook copy = kmemdup(src, len, GFP_KERNEL); 1037db6fe4d6SKees Cook KUNIT_EXPECT_NOT_NULL(test, copy); 1038db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 1039db6fe4d6SKees Cook kfree(copy); 1040db6fe4d6SKees Cook 1041db6fe4d6SKees Cook /* Without %NUL. */ 1042db6fe4d6SKees Cook copy = kmemdup(src, len - 1, GFP_KERNEL); 1043db6fe4d6SKees Cook KUNIT_EXPECT_NOT_NULL(test, copy); 1044db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 1045db6fe4d6SKees Cook kfree(copy); 1046db6fe4d6SKees Cook 1047db6fe4d6SKees Cook /* Tiny bounds. */ 1048db6fe4d6SKees Cook copy = kmemdup(src, 1, GFP_KERNEL); 1049db6fe4d6SKees Cook KUNIT_EXPECT_NOT_NULL(test, copy); 1050db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); 1051db6fe4d6SKees Cook kfree(copy); 1052db6fe4d6SKees Cook 1053db6fe4d6SKees Cook /* Out of bounds by 1 byte. */ 1054db6fe4d6SKees Cook copy = kmemdup(src, len + 1, GFP_KERNEL); 1055db6fe4d6SKees Cook KUNIT_EXPECT_PTR_EQ(test, copy, ZERO_SIZE_PTR); 1056db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1); 1057db6fe4d6SKees Cook kfree(copy); 1058db6fe4d6SKees Cook 1059db6fe4d6SKees Cook /* Way out of bounds. */ 1060db6fe4d6SKees Cook copy = kmemdup(src, len * 2, GFP_KERNEL); 1061db6fe4d6SKees Cook KUNIT_EXPECT_PTR_EQ(test, copy, ZERO_SIZE_PTR); 1062db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 1063db6fe4d6SKees Cook kfree(copy); 1064db6fe4d6SKees Cook 1065db6fe4d6SKees Cook /* Starting offset causing out of bounds. */ 1066db6fe4d6SKees Cook copy = kmemdup(src + 1, len, GFP_KERNEL); 1067db6fe4d6SKees Cook KUNIT_EXPECT_PTR_EQ(test, copy, ZERO_SIZE_PTR); 1068db6fe4d6SKees Cook KUNIT_EXPECT_EQ(test, fortify_read_overflows, 3); 1069db6fe4d6SKees Cook kfree(copy); 1070db6fe4d6SKees Cook } 1071db6fe4d6SKees Cook 1072db6fe4d6SKees Cook static int fortify_test_init(struct kunit *test) 1073db6fe4d6SKees Cook { 1074db6fe4d6SKees Cook if (!IS_ENABLED(CONFIG_FORTIFY_SOURCE)) 1075db6fe4d6SKees Cook kunit_skip(test, "Not built with CONFIG_FORTIFY_SOURCE=y"); 1076db6fe4d6SKees Cook 1077db6fe4d6SKees Cook fortify_read_overflows = 0; 1078db6fe4d6SKees Cook kunit_add_named_resource(test, NULL, NULL, &read_resource, 1079db6fe4d6SKees Cook "fortify_read_overflows", 1080db6fe4d6SKees Cook &fortify_read_overflows); 1081db6fe4d6SKees Cook fortify_write_overflows = 0; 1082db6fe4d6SKees Cook kunit_add_named_resource(test, NULL, NULL, &write_resource, 1083db6fe4d6SKees Cook "fortify_write_overflows", 1084db6fe4d6SKees Cook &fortify_write_overflows); 1085db6fe4d6SKees Cook return 0; 1086db6fe4d6SKees Cook } 1087db6fe4d6SKees Cook 1088db6fe4d6SKees Cook static struct kunit_case fortify_test_cases[] = { 1089db6fe4d6SKees Cook KUNIT_CASE(fortify_test_known_sizes), 1090db6fe4d6SKees Cook KUNIT_CASE(fortify_test_control_flow_split), 1091db6fe4d6SKees Cook KUNIT_CASE(fortify_test_alloc_size_kmalloc_const), 1092db6fe4d6SKees Cook KUNIT_CASE(fortify_test_alloc_size_kmalloc_dynamic), 1093db6fe4d6SKees Cook KUNIT_CASE(fortify_test_alloc_size_vmalloc_const), 1094db6fe4d6SKees Cook KUNIT_CASE(fortify_test_alloc_size_vmalloc_dynamic), 1095db6fe4d6SKees Cook KUNIT_CASE(fortify_test_alloc_size_kvmalloc_const), 1096db6fe4d6SKees Cook KUNIT_CASE(fortify_test_alloc_size_kvmalloc_dynamic), 1097db6fe4d6SKees Cook KUNIT_CASE(fortify_test_alloc_size_devm_kmalloc_const), 1098db6fe4d6SKees Cook KUNIT_CASE(fortify_test_alloc_size_devm_kmalloc_dynamic), 1099db6fe4d6SKees Cook KUNIT_CASE(fortify_test_realloc_size), 1100db6fe4d6SKees Cook KUNIT_CASE(fortify_test_strlen), 1101db6fe4d6SKees Cook KUNIT_CASE(fortify_test_strnlen), 1102db6fe4d6SKees Cook KUNIT_CASE(fortify_test_strcpy), 1103db6fe4d6SKees Cook KUNIT_CASE(fortify_test_strncpy), 1104db6fe4d6SKees Cook KUNIT_CASE(fortify_test_strscpy), 1105db6fe4d6SKees Cook KUNIT_CASE(fortify_test_strcat), 1106db6fe4d6SKees Cook KUNIT_CASE(fortify_test_strncat), 1107db6fe4d6SKees Cook KUNIT_CASE(fortify_test_strlcat), 1108db6fe4d6SKees Cook /* skip memset: performs bounds checking on whole structs */ 1109db6fe4d6SKees Cook KUNIT_CASE(fortify_test_memcpy), 1110db6fe4d6SKees Cook KUNIT_CASE(fortify_test_memmove), 1111db6fe4d6SKees Cook KUNIT_CASE(fortify_test_memscan), 1112db6fe4d6SKees Cook KUNIT_CASE(fortify_test_memchr), 1113db6fe4d6SKees Cook KUNIT_CASE(fortify_test_memchr_inv), 1114db6fe4d6SKees Cook KUNIT_CASE(fortify_test_memcmp), 1115db6fe4d6SKees Cook KUNIT_CASE(fortify_test_kmemdup), 1116db6fe4d6SKees Cook {} 1117db6fe4d6SKees Cook }; 1118db6fe4d6SKees Cook 1119db6fe4d6SKees Cook static struct kunit_suite fortify_test_suite = { 1120db6fe4d6SKees Cook .name = "fortify", 1121db6fe4d6SKees Cook .init = fortify_test_init, 1122db6fe4d6SKees Cook .test_cases = fortify_test_cases, 1123db6fe4d6SKees Cook }; 1124db6fe4d6SKees Cook 1125db6fe4d6SKees Cook kunit_test_suite(fortify_test_suite); 1126db6fe4d6SKees Cook 1127db6fe4d6SKees Cook MODULE_DESCRIPTION("Runtime test cases for CONFIG_FORTIFY_SOURCE"); 1128db6fe4d6SKees Cook MODULE_LICENSE("GPL"); 1129