0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0013
0014 #include <kunit/test.h>
0015 #include <linux/init.h>
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/string.h>
0019
0020
0021 #define MAX_VAR_SIZE 128
0022 static u8 check_buf[MAX_VAR_SIZE];
0023
0024
0025 #define VAR_BUFFER 32
0026
0027
0028 static volatile u8 forced_mask = 0xff;
0029
0030
0031 static void *fill_start, *target_start;
0032 static size_t fill_size, target_size;
0033
0034 static bool range_contains(char *haystack_start, size_t haystack_size,
0035 char *needle_start, size_t needle_size)
0036 {
0037 if (needle_start >= haystack_start &&
0038 needle_start + needle_size <= haystack_start + haystack_size)
0039 return true;
0040 return false;
0041 }
0042
0043
0044 #define WANT_SUCCESS 0
0045 #define XFAIL 1
0046
0047 #define DO_NOTHING_TYPE_SCALAR(var_type) var_type
0048 #define DO_NOTHING_TYPE_STRING(var_type) void
0049 #define DO_NOTHING_TYPE_STRUCT(var_type) void
0050
0051 #define DO_NOTHING_RETURN_SCALAR(ptr) *(ptr)
0052 #define DO_NOTHING_RETURN_STRING(ptr)
0053 #define DO_NOTHING_RETURN_STRUCT(ptr)
0054
0055 #define DO_NOTHING_CALL_SCALAR(var, name) \
0056 (var) = do_nothing_ ## name(&(var))
0057 #define DO_NOTHING_CALL_STRING(var, name) \
0058 do_nothing_ ## name(var)
0059 #define DO_NOTHING_CALL_STRUCT(var, name) \
0060 do_nothing_ ## name(&(var))
0061
0062 #define FETCH_ARG_SCALAR(var) &var
0063 #define FETCH_ARG_STRING(var) var
0064 #define FETCH_ARG_STRUCT(var) &var
0065
0066 #define FILL_SIZE_STRING 16
0067
0068 #define INIT_CLONE_SCALAR
0069 #define INIT_CLONE_STRING [FILL_SIZE_STRING]
0070 #define INIT_CLONE_STRUCT
0071
0072 #define ZERO_CLONE_SCALAR(zero) memset(&(zero), 0x00, sizeof(zero))
0073 #define ZERO_CLONE_STRING(zero) memset(&(zero), 0x00, sizeof(zero))
0074
0075
0076
0077
0078 #define ZERO_CLONE_STRUCT(zero) \
0079 do { \
0080 memset(&(zero), 0xFF, sizeof(zero)); \
0081 zero.one = 0; \
0082 zero.two = 0; \
0083 zero.three = 0; \
0084 zero.four = 0; \
0085 } while (0)
0086
0087 #define INIT_SCALAR_none(var_type)
0088 #define INIT_SCALAR_zero(var_type) = 0
0089
0090 #define INIT_STRING_none(var_type) [FILL_SIZE_STRING]
0091 #define INIT_STRING_zero(var_type) [FILL_SIZE_STRING] = { }
0092
0093 #define INIT_STRUCT_none(var_type)
0094 #define INIT_STRUCT_zero(var_type) = { }
0095
0096
0097 #define __static_partial { .two = 0, }
0098 #define __static_all { .one = 0, \
0099 .two = 0, \
0100 .three = 0, \
0101 .four = 0, \
0102 }
0103 #define __dynamic_partial { .two = arg->two, }
0104 #define __dynamic_all { .one = arg->one, \
0105 .two = arg->two, \
0106 .three = arg->three, \
0107 .four = arg->four, \
0108 }
0109 #define __runtime_partial var.two = 0
0110 #define __runtime_all var.one = 0; \
0111 var.two = 0; \
0112 var.three = 0; \
0113 var.four = 0
0114
0115 #define INIT_STRUCT_static_partial(var_type) \
0116 = __static_partial
0117 #define INIT_STRUCT_static_all(var_type) \
0118 = __static_all
0119 #define INIT_STRUCT_dynamic_partial(var_type) \
0120 = __dynamic_partial
0121 #define INIT_STRUCT_dynamic_all(var_type) \
0122 = __dynamic_all
0123 #define INIT_STRUCT_runtime_partial(var_type) \
0124 ; __runtime_partial
0125 #define INIT_STRUCT_runtime_all(var_type) \
0126 ; __runtime_all
0127
0128 #define INIT_STRUCT_assigned_static_partial(var_type) \
0129 ; var = (var_type)__static_partial
0130 #define INIT_STRUCT_assigned_static_all(var_type) \
0131 ; var = (var_type)__static_all
0132 #define INIT_STRUCT_assigned_dynamic_partial(var_type) \
0133 ; var = (var_type)__dynamic_partial
0134 #define INIT_STRUCT_assigned_dynamic_all(var_type) \
0135 ; var = (var_type)__dynamic_all
0136
0137 #define INIT_STRUCT_assigned_copy(var_type) \
0138 ; var = *(arg)
0139
0140
0141
0142
0143
0144
0145
0146
0147 #define DEFINE_TEST_DRIVER(name, var_type, which, xfail) \
0148 \
0149 static noinline void test_ ## name (struct kunit *test) \
0150 { \
0151 var_type zero INIT_CLONE_ ## which; \
0152 int ignored; \
0153 u8 sum = 0, i; \
0154 \
0155 \
0156 BUILD_BUG_ON(sizeof(zero) > MAX_VAR_SIZE); \
0157 \
0158 \
0159 ZERO_CLONE_ ## which(zero); \
0160 \
0161 memset(check_buf, 0x00, sizeof(check_buf)); \
0162 \
0163 ignored = leaf_ ##name((unsigned long)&ignored, 1, \
0164 FETCH_ARG_ ## which(zero)); \
0165 \
0166 for (sum = 0, i = 0; i < target_size; i++) \
0167 sum += (check_buf[i] != 0xFF); \
0168 KUNIT_ASSERT_EQ_MSG(test, sum, 0, \
0169 "leaf fill was not 0xFF!?\n"); \
0170 \
0171 memset(check_buf, 0x00, sizeof(check_buf)); \
0172 \
0173 ignored = leaf_ ##name((unsigned long)&ignored, 0, \
0174 FETCH_ARG_ ## which(zero)); \
0175 \
0176 \
0177 KUNIT_ASSERT_TRUE_MSG(test, \
0178 range_contains(fill_start, fill_size, \
0179 target_start, target_size), \
0180 "stack fill missed target!? " \
0181 "(fill %zu wide, target offset by %d)\n", \
0182 fill_size, \
0183 (int)((ssize_t)(uintptr_t)fill_start - \
0184 (ssize_t)(uintptr_t)target_start)); \
0185 \
0186 \
0187 for (sum = 0, i = 0; i < target_size; i++) \
0188 sum += (check_buf[i] == 0xFF); \
0189 \
0190 if (sum != 0 && xfail) \
0191 kunit_skip(test, \
0192 "XFAIL uninit bytes: %d\n", \
0193 sum); \
0194 KUNIT_ASSERT_EQ_MSG(test, sum, 0, \
0195 "uninit bytes: %d\n", sum); \
0196 }
0197 #define DEFINE_TEST(name, var_type, which, init_level, xfail) \
0198 \
0199 static noinline DO_NOTHING_TYPE_ ## which(var_type) \
0200 do_nothing_ ## name(var_type *ptr) \
0201 { \
0202 \
0203 if ((unsigned long)ptr > 0x2) \
0204 return DO_NOTHING_RETURN_ ## which(ptr); \
0205 else \
0206 return DO_NOTHING_RETURN_ ## which(ptr + 1); \
0207 } \
0208 static noinline int leaf_ ## name(unsigned long sp, bool fill, \
0209 var_type *arg) \
0210 { \
0211 char buf[VAR_BUFFER]; \
0212 var_type var \
0213 INIT_ ## which ## _ ## init_level(var_type); \
0214 \
0215 target_start = &var; \
0216 target_size = sizeof(var); \
0217
0218
0219
0220 \
0221 memset(buf, (char)(sp & 0xff), sizeof(buf)); \
0222 \
0223 if (fill) { \
0224 fill_start = &var; \
0225 fill_size = sizeof(var); \
0226 memset(fill_start, \
0227 (char)((sp & 0xff) | forced_mask), \
0228 fill_size); \
0229 } \
0230 \
0231 \
0232 DO_NOTHING_CALL_ ## which(var, name); \
0233 \
0234 \
0235 memcpy(check_buf, target_start, target_size); \
0236 \
0237 return (int)buf[0] | (int)buf[sizeof(buf) - 1]; \
0238 } \
0239 DEFINE_TEST_DRIVER(name, var_type, which, xfail)
0240
0241
0242 struct test_packed {
0243 unsigned long one;
0244 unsigned long two;
0245 unsigned long three;
0246 unsigned long four;
0247 };
0248
0249
0250 struct test_small_hole {
0251 size_t one;
0252 char two;
0253
0254 int three;
0255 unsigned long four;
0256 };
0257
0258
0259 struct test_big_hole {
0260 u8 one;
0261 u8 two;
0262 u8 three;
0263
0264 u8 four __aligned(64);
0265 } __aligned(64);
0266
0267 struct test_trailing_hole {
0268 char *one;
0269 char *two;
0270 char *three;
0271 char four;
0272
0273 };
0274
0275
0276 struct test_user {
0277 u8 one;
0278 unsigned long two;
0279 char __user *three;
0280 unsigned long four;
0281 };
0282
0283 #define ALWAYS_PASS WANT_SUCCESS
0284 #define ALWAYS_FAIL XFAIL
0285
0286 #ifdef CONFIG_INIT_STACK_NONE
0287 # define USER_PASS XFAIL
0288 # define BYREF_PASS XFAIL
0289 # define STRONG_PASS XFAIL
0290 #elif defined(CONFIG_GCC_PLUGIN_STRUCTLEAK_USER)
0291 # define USER_PASS WANT_SUCCESS
0292 # define BYREF_PASS XFAIL
0293 # define STRONG_PASS XFAIL
0294 #elif defined(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF)
0295 # define USER_PASS WANT_SUCCESS
0296 # define BYREF_PASS WANT_SUCCESS
0297 # define STRONG_PASS XFAIL
0298 #else
0299 # define USER_PASS WANT_SUCCESS
0300 # define BYREF_PASS WANT_SUCCESS
0301 # define STRONG_PASS WANT_SUCCESS
0302 #endif
0303
0304 #define DEFINE_SCALAR_TEST(name, init, xfail) \
0305 DEFINE_TEST(name ## _ ## init, name, SCALAR, \
0306 init, xfail)
0307
0308 #define DEFINE_SCALAR_TESTS(init, xfail) \
0309 DEFINE_SCALAR_TEST(u8, init, xfail); \
0310 DEFINE_SCALAR_TEST(u16, init, xfail); \
0311 DEFINE_SCALAR_TEST(u32, init, xfail); \
0312 DEFINE_SCALAR_TEST(u64, init, xfail); \
0313 DEFINE_TEST(char_array_ ## init, unsigned char, \
0314 STRING, init, xfail)
0315
0316 #define DEFINE_STRUCT_TEST(name, init, xfail) \
0317 DEFINE_TEST(name ## _ ## init, \
0318 struct test_ ## name, STRUCT, init, \
0319 xfail)
0320
0321 #define DEFINE_STRUCT_TESTS(init, xfail) \
0322 DEFINE_STRUCT_TEST(small_hole, init, xfail); \
0323 DEFINE_STRUCT_TEST(big_hole, init, xfail); \
0324 DEFINE_STRUCT_TEST(trailing_hole, init, xfail); \
0325 DEFINE_STRUCT_TEST(packed, init, xfail)
0326
0327 #define DEFINE_STRUCT_INITIALIZER_TESTS(base, xfail) \
0328 DEFINE_STRUCT_TESTS(base ## _ ## partial, \
0329 xfail); \
0330 DEFINE_STRUCT_TESTS(base ## _ ## all, xfail)
0331
0332
0333 DEFINE_SCALAR_TESTS(zero, ALWAYS_PASS);
0334 DEFINE_STRUCT_TESTS(zero, ALWAYS_PASS);
0335
0336 DEFINE_STRUCT_INITIALIZER_TESTS(static, STRONG_PASS);
0337 DEFINE_STRUCT_INITIALIZER_TESTS(dynamic, STRONG_PASS);
0338 DEFINE_STRUCT_INITIALIZER_TESTS(runtime, STRONG_PASS);
0339 DEFINE_STRUCT_INITIALIZER_TESTS(assigned_static, STRONG_PASS);
0340 DEFINE_STRUCT_INITIALIZER_TESTS(assigned_dynamic, STRONG_PASS);
0341 DEFINE_STRUCT_TESTS(assigned_copy, ALWAYS_FAIL);
0342
0343 DEFINE_SCALAR_TESTS(none, STRONG_PASS);
0344 DEFINE_STRUCT_TESTS(none, BYREF_PASS);
0345
0346 DEFINE_TEST(user, struct test_user, STRUCT, none, USER_PASS);
0347
0348
0349
0350
0351
0352
0353 static int noinline __leaf_switch_none(int path, bool fill)
0354 {
0355 switch (path) {
0356
0357
0358
0359
0360 uint64_t var[10];
0361
0362 case 1:
0363 target_start = &var;
0364 target_size = sizeof(var);
0365 if (fill) {
0366 fill_start = &var;
0367 fill_size = sizeof(var);
0368
0369 memset(fill_start, forced_mask | 0x55, fill_size);
0370 }
0371 memcpy(check_buf, target_start, target_size);
0372 break;
0373 case 2:
0374 target_start = &var;
0375 target_size = sizeof(var);
0376 if (fill) {
0377 fill_start = &var;
0378 fill_size = sizeof(var);
0379
0380 memset(fill_start, forced_mask | 0xaa, fill_size);
0381 }
0382 memcpy(check_buf, target_start, target_size);
0383 break;
0384 default:
0385 var[1] = 5;
0386 return var[1] & forced_mask;
0387 }
0388 return 0;
0389 }
0390
0391 static noinline int leaf_switch_1_none(unsigned long sp, bool fill,
0392 uint64_t *arg)
0393 {
0394 return __leaf_switch_none(1, fill);
0395 }
0396
0397 static noinline int leaf_switch_2_none(unsigned long sp, bool fill,
0398 uint64_t *arg)
0399 {
0400 return __leaf_switch_none(2, fill);
0401 }
0402
0403
0404
0405
0406
0407
0408
0409 DEFINE_TEST_DRIVER(switch_1_none, uint64_t, SCALAR, ALWAYS_FAIL);
0410 DEFINE_TEST_DRIVER(switch_2_none, uint64_t, SCALAR, ALWAYS_FAIL);
0411
0412 #define KUNIT_test_scalars(init) \
0413 KUNIT_CASE(test_u8_ ## init), \
0414 KUNIT_CASE(test_u16_ ## init), \
0415 KUNIT_CASE(test_u32_ ## init), \
0416 KUNIT_CASE(test_u64_ ## init), \
0417 KUNIT_CASE(test_char_array_ ## init)
0418
0419 #define KUNIT_test_structs(init) \
0420 KUNIT_CASE(test_small_hole_ ## init), \
0421 KUNIT_CASE(test_big_hole_ ## init), \
0422 KUNIT_CASE(test_trailing_hole_ ## init),\
0423 KUNIT_CASE(test_packed_ ## init) \
0424
0425 static struct kunit_case stackinit_test_cases[] = {
0426
0427 KUNIT_test_scalars(zero),
0428 KUNIT_test_structs(zero),
0429
0430 KUNIT_test_structs(dynamic_partial),
0431 KUNIT_test_structs(assigned_dynamic_partial),
0432
0433 KUNIT_test_structs(static_partial),
0434 KUNIT_test_structs(static_all),
0435 KUNIT_test_structs(dynamic_all),
0436 KUNIT_test_structs(runtime_partial),
0437 KUNIT_test_structs(runtime_all),
0438 KUNIT_test_structs(assigned_static_partial),
0439 KUNIT_test_structs(assigned_static_all),
0440 KUNIT_test_structs(assigned_dynamic_all),
0441
0442 KUNIT_test_structs(assigned_copy),
0443
0444 KUNIT_test_scalars(none),
0445 KUNIT_CASE(test_switch_1_none),
0446 KUNIT_CASE(test_switch_2_none),
0447
0448 KUNIT_test_structs(none),
0449
0450 KUNIT_CASE(test_user),
0451 {}
0452 };
0453
0454 static struct kunit_suite stackinit_test_suite = {
0455 .name = "stackinit",
0456 .test_cases = stackinit_test_cases,
0457 };
0458
0459 kunit_test_suites(&stackinit_test_suite);
0460
0461 MODULE_LICENSE("GPL");