1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 */ 5 #include <assert.h> 6 #include <config.h> 7 #include <kernel/dt_driver.h> 8 #include <malloc.h> 9 #include <stdbool.h> 10 #include <trace.h> 11 #include <kernel/panic.h> 12 #include <util.h> 13 14 #include "misc.h" 15 16 /* 17 * Enable expect LOG macro to enable/disable self tests traces. 18 * 19 * #define LOG DMSG_RAW 20 * #define LOG(...) 21 */ 22 #define LOG(...) 23 24 static int self_test_add_overflow(void) 25 { 26 uint32_t r_u32; 27 int32_t r_s32; 28 uintmax_t r_um; 29 intmax_t r_sm; 30 31 if (ADD_OVERFLOW(8U, 0U, &r_s32)) 32 return -1; 33 if (r_s32 != 8) 34 return -1; 35 if (ADD_OVERFLOW(32U, 30U, &r_u32)) 36 return -1; 37 if (r_u32 != 62) 38 return -1; 39 if (!ADD_OVERFLOW(UINT32_MAX, UINT32_MAX, &r_u32)) 40 return -1; 41 if (!ADD_OVERFLOW(UINT32_MAX / 2 + 1, UINT32_MAX / 2 + 1, &r_u32)) 42 return -1; 43 if (ADD_OVERFLOW(UINT32_MAX / 2, UINT32_MAX / 2 + 1, &r_u32)) 44 return -1; 45 if (r_u32 != UINT32_MAX) 46 return -1; 47 48 if (ADD_OVERFLOW((uint32_t)30, (int32_t)-31, &r_s32)) 49 return -1; 50 if (r_s32 != -1) 51 return -1; 52 if (ADD_OVERFLOW((int32_t)30, (int32_t)-31, &r_s32)) 53 return -1; 54 if (r_s32 != -1) 55 return -1; 56 if (ADD_OVERFLOW((int32_t)-31, (uint32_t)30, &r_s32)) 57 return -1; 58 if (r_s32 != -1) 59 return -1; 60 61 if (ADD_OVERFLOW(INT32_MIN + 1, -1, &r_s32)) 62 return -1; 63 if (r_s32 != INT32_MIN) 64 return -1; 65 if (!ADD_OVERFLOW(INT32_MIN, -1, &r_s32)) 66 return -1; 67 if (!ADD_OVERFLOW(INT32_MIN + 1, -2, &r_s32)) 68 return -1; 69 if (!ADD_OVERFLOW(INT32_MAX, INT32_MAX, &r_s32)) 70 return -1; 71 if (ADD_OVERFLOW(INT32_MAX, INT32_MAX, &r_u32)) 72 return -1; 73 if (!ADD_OVERFLOW(INTMAX_MAX, INTMAX_MAX, &r_sm)) 74 return -1; 75 if (ADD_OVERFLOW(INTMAX_MAX, INTMAX_MAX, &r_um)) 76 return -1; 77 if (!ADD_OVERFLOW(INT32_MAX / 2 + 1, INT32_MAX / 2 + 1, &r_s32)) 78 return -1; 79 if (ADD_OVERFLOW(INT32_MAX / 2, INT32_MAX / 2 + 1, &r_s32)) 80 return -1; 81 if (r_s32 != INT32_MAX) 82 return -1; 83 84 return 0; 85 } 86 87 static int self_test_sub_overflow(void) 88 { 89 uint32_t r_u32; 90 int32_t r_s32; 91 intmax_t r_sm; 92 93 if (SUB_OVERFLOW(8U, 1U, &r_s32)) 94 return -1; 95 if (r_s32 != 7) 96 return -1; 97 if (SUB_OVERFLOW(32U, 30U, &r_u32)) 98 return -1; 99 if (r_u32 != 2) 100 return -1; 101 if (!SUB_OVERFLOW(30U, 31U, &r_u32)) 102 return -1; 103 104 if (SUB_OVERFLOW(30, 31, &r_s32)) 105 return -1; 106 if (r_s32 != -1) 107 return -1; 108 if (SUB_OVERFLOW(-1, INT32_MAX, &r_s32)) 109 return -1; 110 if (r_s32 != INT32_MIN) 111 return -1; 112 if (!SUB_OVERFLOW(-2, INT32_MAX, &r_s32)) 113 return -1; 114 115 if (SUB_OVERFLOW((uint32_t)30, (int32_t)-31, &r_s32)) 116 return -1; 117 if (r_s32 != 61) 118 return -1; 119 if (SUB_OVERFLOW((int32_t)30, (int32_t)-31, &r_s32)) 120 return -1; 121 if (r_s32 != 61) 122 return -1; 123 if (SUB_OVERFLOW((int32_t)-31, (uint32_t)30, &r_s32)) 124 return -1; 125 if (r_s32 != -61) 126 return -1; 127 if (SUB_OVERFLOW((int32_t)-31, (int32_t)-30, &r_s32)) 128 return -1; 129 if (r_s32 != -1) 130 return -1; 131 132 if (SUB_OVERFLOW((int32_t)31, -(INTMAX_MIN + 1), &r_sm)) 133 return -1; 134 if (r_sm != (INTMAX_MIN + 32)) 135 return -1; 136 137 return 0; 138 } 139 140 static int self_test_mul_unsigned_overflow(void) 141 { 142 const size_t um_half_shift = sizeof(uintmax_t) * 8 / 2; 143 const uintmax_t um_half_mask = UINTMAX_MAX >> um_half_shift; 144 uint32_t r_u32; 145 uintmax_t r_um; 146 147 if (MUL_OVERFLOW(32, 30, &r_u32)) 148 return -1; 149 if (r_u32 != 960) 150 return -1; 151 if (MUL_OVERFLOW(-32, -30, &r_u32)) 152 return -1; 153 if (r_u32 != 960) 154 return -1; 155 156 if (MUL_OVERFLOW(UINTMAX_MAX, 1, &r_um)) 157 return -1; 158 if (r_um != UINTMAX_MAX) 159 return -1; 160 if (MUL_OVERFLOW(UINTMAX_MAX / 4, 4, &r_um)) 161 return -1; 162 if (r_um != (UINTMAX_MAX - 3)) 163 return -1; 164 if (!MUL_OVERFLOW(UINTMAX_MAX / 4 + 1, 4, &r_um)) 165 return -1; 166 if (!MUL_OVERFLOW(UINTMAX_MAX, UINTMAX_MAX, &r_um)) 167 return -1; 168 if (!MUL_OVERFLOW(um_half_mask << um_half_shift, 169 um_half_mask << um_half_shift, &r_um)) 170 return -1; 171 172 return 0; 173 } 174 175 static int self_test_mul_signed_overflow(void) 176 { 177 intmax_t r; 178 179 if (MUL_OVERFLOW(32, -30, &r)) 180 return -1; 181 if (r != -960) 182 return -1; 183 if (MUL_OVERFLOW(-32, 30, &r)) 184 return -1; 185 if (r != -960) 186 return -1; 187 if (MUL_OVERFLOW(32, 30, &r)) 188 return -1; 189 if (r != 960) 190 return -1; 191 192 if (MUL_OVERFLOW(INTMAX_MAX, 1, &r)) 193 return -1; 194 if (r != INTMAX_MAX) 195 return -1; 196 if (MUL_OVERFLOW(INTMAX_MAX / 4, 4, &r)) 197 return -1; 198 if (r != (INTMAX_MAX - 3)) 199 return -1; 200 if (!MUL_OVERFLOW(INTMAX_MAX / 4 + 1, 4, &r)) 201 return -1; 202 if (!MUL_OVERFLOW(INTMAX_MAX, INTMAX_MAX, &r)) 203 return -1; 204 if (MUL_OVERFLOW(INTMAX_MIN + 1, 1, &r)) 205 return -1; 206 if (r != INTMAX_MIN + 1) 207 return -1; 208 if (MUL_OVERFLOW(1, INTMAX_MIN + 1, &r)) 209 return -1; 210 if (r != INTMAX_MIN + 1) 211 return -1; 212 if (MUL_OVERFLOW(0, INTMAX_MIN, &r)) 213 return -1; 214 if (r != 0) 215 return -1; 216 if (MUL_OVERFLOW(1, INTMAX_MIN, &r)) 217 return -1; 218 if (r != INTMAX_MIN) 219 return -1; 220 221 return 0; 222 } 223 224 /* test division support. resulting trace shall be manually checked */ 225 static int self_test_division(void) 226 { 227 signed a, b, c, d; 228 bool r; 229 int ret = 0; 230 231 LOG(""); 232 LOG("division tests (division and modulo):"); 233 /* get some unpredicted values to prevent compilation optimizations: */ 234 /* => use the stack address */ 235 236 LOG("- test with unsigned small integers:"); 237 a = (signed)((unsigned)(vaddr_t)&a & 0xFFFFF); 238 b = (signed)((unsigned)(vaddr_t)&b & 0x00FFF) + 1; 239 c = a / b; 240 d = a % b; 241 r = ((b * c + d) == a); 242 if (!r) 243 ret = -1; 244 LOG(" 0x%08x / 0x%08x = %u / %u = %u = 0x%x)", 245 (unsigned)a, (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)c, 246 (unsigned)c); 247 LOG(" 0x%08x %% 0x%08x = %u %% %u = %u = 0x%x)", (unsigned)a, 248 (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)d, (unsigned)d); 249 LOG(" check results => %s", r ? "ok" : "FAILED !!!"); 250 LOG(""); 251 252 LOG("- test with signed small integers, negative numerator:"); 253 a = (signed)(vaddr_t)&a; 254 b = (signed)((unsigned)(vaddr_t)&b & 0x00FFF) - 1; 255 c = a / b; 256 d = a % b; 257 r = ((b * c + d) == a); 258 if (!r) 259 ret = -1; 260 LOG(" 0x%08x / 0x%08x = %d / %d = %d = 0x%x)", 261 (unsigned)a, (unsigned)b, (signed)a, (signed)b, (signed)c, 262 (unsigned)c); 263 LOG(" 0x%08x %% 0x%08x = %d %% %d = %d = 0x%x)", (unsigned)a, 264 (unsigned)b, (signed)a, (signed)b, (signed)d, (unsigned)d); 265 LOG(" check results => %s", r ? "ok" : "FAILED !!!"); 266 LOG(""); 267 268 LOG("- test with signed small integers, negative denominator:"); 269 a = (signed)((unsigned)(vaddr_t)&a & 0xFFFFF); 270 b = -(signed)((unsigned)(vaddr_t)&b & 0x00FFF) + 1; 271 c = a / b; 272 d = a % b; 273 274 LOG("- test with unsigned integers, big numerator (> 0x80000000):"); 275 a = (signed)(vaddr_t)&a; 276 b = (signed)((unsigned)(vaddr_t)&b & 0x00FFF) + 1; 277 c = (signed)((unsigned)a / (unsigned)b); 278 d = (signed)((unsigned)a % (unsigned)b); 279 r = (((unsigned)b * (unsigned)c + (unsigned)d) == (unsigned)a); 280 if (!r) 281 ret = -1; 282 LOG(" 0x%08x / 0x%08x = %u / %u = %u = 0x%x)", 283 (unsigned)a, (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)c, 284 (unsigned)c); 285 LOG(" 0x%08x %% 0x%08x = %u %% %u = %u = 0x%x)", (unsigned)a, 286 (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)d, (unsigned)d); 287 LOG(" check results => %s", r ? "ok" : "FAILED !!!"); 288 LOG(""); 289 290 LOG("- test with unsigned integers, big num. & denom. (> 0x80000000):"); 291 a = (signed)(vaddr_t)&a; 292 b = (signed)((unsigned)(vaddr_t)&a - 1); 293 c = (signed)((unsigned)a / (unsigned)b); 294 d = (signed)((unsigned)a % (unsigned)b); 295 r = (((unsigned)b * (unsigned)c + (unsigned)d) == (unsigned)a); 296 if (!r) 297 ret = -1; 298 LOG(" 0x%08x / 0x%08x = %u / %u = %u = 0x%x)", 299 (unsigned)a, (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)c, 300 (unsigned)c); 301 LOG(" 0x%08x %% 0x%08x = %u %% %u = %u = 0x%x)", (unsigned)a, 302 (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)d, (unsigned)d); 303 LOG(" check results => %s", r ? "ok" : "FAILED !!!"); 304 LOG(""); 305 306 return ret; 307 } 308 309 /* test malloc support. resulting trace shall be manually checked */ 310 static int self_test_malloc(void) 311 { 312 char *p1 = NULL, *p2 = NULL; 313 int *p3 = NULL, *p4 = NULL; 314 bool r; 315 int ret = 0; 316 317 LOG("malloc tests:"); 318 LOG(" p1=%p p2=%p p3=%p p4=%p", 319 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 320 /* test malloc */ 321 p1 = malloc(1024); 322 LOG("- p1 = malloc(1024)"); 323 p2 = malloc(1024); 324 LOG("- p2 = malloc(1024)"); 325 LOG(" p1=%p p2=%p p3=%p p4=%p", 326 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 327 r = (p1 && p2 && malloc_buffer_is_within_alloced(p1, 1024) && 328 !malloc_buffer_is_within_alloced(p1 + 25, 1000) && 329 !malloc_buffer_is_within_alloced(p1 - 25, 500) && 330 malloc_buffer_overlaps_heap(p1 - 25, 500)); 331 if (!r) 332 ret = -1; 333 LOG(" => test %s", r ? "ok" : "FAILED"); 334 LOG(""); 335 336 /* test realloc */ 337 p3 = realloc(p1, 3 * 1024); 338 if (p3) 339 p1 = NULL; 340 LOG("- p3 = realloc(p1, 3*1024)"); 341 LOG("- free p2"); 342 free(p2); 343 p2 = malloc(1024); 344 LOG("- p2 = malloc(1024)"); 345 LOG(" p1=%p p2=%p p3=%p p4=%p", 346 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 347 r = (p2 && p3); 348 if (!r) 349 ret = -1; 350 LOG(" => test %s", r ? "ok" : "FAILED"); 351 LOG(""); 352 LOG("- free p1, p2, p3"); 353 free(p1); 354 free(p2); 355 free(p3); 356 p1 = NULL; 357 p2 = NULL; 358 p3 = NULL; 359 360 /* test calloc */ 361 p3 = calloc(4, 1024); 362 p4 = calloc(0x100, 1024 * 1024); 363 LOG("- p3 = calloc(4, 1024)"); 364 LOG("- p4 = calloc(0x100, 1024*1024) too big: should fail!"); 365 LOG(" p1=%p p2=%p p3=%p p4=%p", 366 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 367 r = (p3 && !p4); 368 if (!r) 369 ret = -1; 370 LOG(" => test %s", r ? "ok" : "FAILED"); 371 LOG(""); 372 LOG("- free p3, p4"); 373 free(p3); 374 free(p4); 375 p3 = NULL; 376 p4 = NULL; 377 378 /* test memalign */ 379 p3 = memalign(0x1000, 1024); 380 LOG("- p3 = memalign(%d, 1024)", 0x1000); 381 p1 = malloc(1024); 382 LOG("- p1 = malloc(1024)"); 383 p4 = memalign(0x100, 512); 384 LOG("- p4 = memalign(%d, 512)", 0x100); 385 LOG(" p1=%p p2=%p p3=%p p4=%p", 386 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 387 r = (p1 && p3 && p4 && 388 !((vaddr_t)p3 % 0x1000) && !((vaddr_t)p4 % 0x100)); 389 if (!r) 390 ret = -1; 391 LOG(" => test %s", r ? "ok" : "FAILED"); 392 LOG(""); 393 LOG("- free p1, p3, p4"); 394 free(p1); 395 free(p3); 396 free(p4); 397 p1 = NULL; 398 p3 = NULL; 399 p4 = NULL; 400 401 /* test memalign with invalid alignments */ 402 p3 = memalign(100, 1024); 403 LOG("- p3 = memalign(%d, 1024)", 100); 404 p4 = memalign(0, 1024); 405 LOG("- p4 = memalign(%d, 1024)", 0); 406 LOG(" p1=%p p2=%p p3=%p p4=%p", 407 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 408 r = (!p3 && !p4); 409 if (!r) 410 ret = -1; 411 LOG(" => test %s", r ? "ok" : "FAILED"); 412 LOG(""); 413 LOG("- free p3, p4"); 414 free(p3); 415 free(p4); 416 p3 = NULL; 417 p4 = NULL; 418 419 /* test free(NULL) */ 420 LOG("- free NULL"); 421 free(NULL); 422 LOG(""); 423 LOG("malloc test done"); 424 425 return ret; 426 } 427 428 #ifdef CFG_NS_VIRTUALIZATION 429 /* test nex_malloc support. resulting trace shall be manually checked */ 430 static int self_test_nex_malloc(void) 431 { 432 char *p1 = NULL, *p2 = NULL; 433 int *p3 = NULL, *p4 = NULL; 434 bool r; 435 int ret = 0; 436 437 LOG("nex_malloc tests:"); 438 LOG(" p1=%p p2=%p p3=%p p4=%p", 439 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 440 /* test malloc */ 441 p1 = nex_malloc(1024); 442 LOG("- p1 = nex_malloc(1024)"); 443 p2 = nex_malloc(1024); 444 LOG("- p2 = nex_malloc(1024)"); 445 LOG(" p1=%p p2=%p p3=%p p4=%p", 446 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 447 r = (p1 && p2 && nex_malloc_buffer_is_within_alloced(p1, 1024) && 448 !nex_malloc_buffer_is_within_alloced(p1 + 25, 1000) && 449 !nex_malloc_buffer_is_within_alloced(p1 - 25, 500) && 450 nex_malloc_buffer_overlaps_heap(p1 - 25, 500)); 451 if (!r) 452 ret = -1; 453 LOG(" => test %s", r ? "ok" : "FAILED"); 454 LOG(""); 455 456 /* test realloc */ 457 p3 = nex_realloc(p1, 3 * 1024); 458 if (p3) 459 p1 = NULL; 460 LOG("- p3 = nex_realloc(p1, 3*1024)"); 461 LOG("- nex_free p2"); 462 nex_free(p2); 463 p2 = nex_malloc(1024); 464 LOG("- p2 = nex_malloc(1024)"); 465 LOG(" p1=%p p2=%p p3=%p p4=%p", 466 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 467 r = (p2 && p3); 468 if (!r) 469 ret = -1; 470 LOG(" => test %s", r ? "ok" : "FAILED"); 471 LOG(""); 472 LOG("- nex_free p1, p2, p3"); 473 nex_free(p1); 474 nex_free(p2); 475 nex_free(p3); 476 p1 = NULL; 477 p2 = NULL; 478 p3 = NULL; 479 480 /* test calloc */ 481 p3 = nex_calloc(4, 1024); 482 p4 = nex_calloc(0x100, 1024 * 1024); 483 LOG("- p3 = nex_calloc(4, 1024)"); 484 LOG("- p4 = nex_calloc(0x100, 1024*1024) too big: should fail!"); 485 LOG(" p1=%p p2=%p p3=%p p4=%p", 486 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 487 r = (p3 && !p4); 488 if (!r) 489 ret = -1; 490 LOG(" => test %s", r ? "ok" : "FAILED"); 491 LOG(""); 492 LOG("- nex_free p3, p4"); 493 nex_free(p3); 494 nex_free(p4); 495 p3 = NULL; 496 p4 = NULL; 497 498 /* test memalign */ 499 p3 = nex_memalign(0x1000, 1024); 500 LOG("- p3 = nex_memalign(%d, 1024)", 0x1000); 501 p1 = nex_malloc(1024); 502 LOG("- p1 = nex_malloc(1024)"); 503 p4 = nex_memalign(0x100, 512); 504 LOG("- p4 = nex_memalign(%d, 512)", 0x100); 505 LOG(" p1=%p p2=%p p3=%p p4=%p", 506 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 507 r = (p1 && p3 && p4 && 508 !((vaddr_t)p3 % 0x1000) && !((vaddr_t)p4 % 0x100)); 509 if (!r) 510 ret = -1; 511 LOG(" => test %s", r ? "ok" : "FAILED"); 512 LOG(""); 513 LOG("- nex_free p1, p3, p4"); 514 nex_free(p1); 515 nex_free(p3); 516 nex_free(p4); 517 p1 = NULL; 518 p3 = NULL; 519 p4 = NULL; 520 521 /* test memalign with invalid alignments */ 522 p3 = nex_memalign(100, 1024); 523 LOG("- p3 = nex_memalign(%d, 1024)", 100); 524 p4 = nex_memalign(0, 1024); 525 LOG("- p4 = nex_memalign(%d, 1024)", 0); 526 LOG(" p1=%p p2=%p p3=%p p4=%p", 527 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 528 r = (!p3 && !p4); 529 if (!r) 530 ret = -1; 531 LOG(" => test %s", r ? "ok" : "FAILED"); 532 LOG(""); 533 LOG("- nex_free p3, p4"); 534 nex_free(p3); 535 nex_free(p4); 536 p3 = NULL; 537 p4 = NULL; 538 539 /* test free(NULL) */ 540 LOG("- nex_free NULL"); 541 nex_free(NULL); 542 LOG(""); 543 LOG("nex_malloc test done"); 544 545 return ret; 546 } 547 #else /* CFG_NS_VIRTUALIZATION */ 548 static int self_test_nex_malloc(void) 549 { 550 return 0; 551 } 552 #endif 553 554 /* exported entry points for some basic test */ 555 TEE_Result core_self_tests(uint32_t nParamTypes __unused, 556 TEE_Param pParams[TEE_NUM_PARAMS] __unused) 557 { 558 if (self_test_mul_signed_overflow() || self_test_add_overflow() || 559 self_test_sub_overflow() || self_test_mul_unsigned_overflow() || 560 self_test_division() || self_test_malloc() || 561 self_test_nex_malloc()) { 562 EMSG("some self_test_xxx failed! you should enable local LOG"); 563 return TEE_ERROR_GENERIC; 564 } 565 return TEE_SUCCESS; 566 } 567 568 /* Exported entrypoint for dt_driver tests */ 569 TEE_Result core_dt_driver_tests(uint32_t nParamTypes __unused, 570 TEE_Param pParams[TEE_NUM_PARAMS] __unused) 571 { 572 if (IS_ENABLED(CFG_DT_DRIVER_EMBEDDED_TEST)) { 573 if (dt_driver_test_status()) 574 return TEE_ERROR_GENERIC; 575 } else { 576 IMSG("dt_driver tests are not embedded"); 577 } 578 579 return TEE_SUCCESS; 580 } 581