1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 * Copyright (c) 2025, Linaro Limited. 5 */ 6 #include <assert.h> 7 #include <config.h> 8 #include <kernel/asan.h> 9 #include <kernel/dt_driver.h> 10 #include <kernel/linker.h> 11 #include <kernel/panic.h> 12 #include <malloc.h> 13 #include <mm/core_memprot.h> 14 #include <setjmp.h> 15 #include <stdbool.h> 16 #include <trace.h> 17 #include <util.h> 18 19 #include "misc.h" 20 21 /* 22 * Enable expect LOG macro to enable/disable self tests traces. 23 * 24 * #define LOG DMSG_RAW 25 * #define LOG(...) 26 */ 27 #define LOG(...) 28 29 static int self_test_add_overflow(void) 30 { 31 uint32_t r_u32; 32 int32_t r_s32; 33 uintmax_t r_um; 34 intmax_t r_sm; 35 36 if (ADD_OVERFLOW(8U, 0U, &r_s32)) 37 return -1; 38 if (r_s32 != 8) 39 return -1; 40 if (ADD_OVERFLOW(32U, 30U, &r_u32)) 41 return -1; 42 if (r_u32 != 62) 43 return -1; 44 if (!ADD_OVERFLOW(UINT32_MAX, UINT32_MAX, &r_u32)) 45 return -1; 46 if (!ADD_OVERFLOW(UINT32_MAX / 2 + 1, UINT32_MAX / 2 + 1, &r_u32)) 47 return -1; 48 if (ADD_OVERFLOW(UINT32_MAX / 2, UINT32_MAX / 2 + 1, &r_u32)) 49 return -1; 50 if (r_u32 != UINT32_MAX) 51 return -1; 52 53 if (ADD_OVERFLOW((uint32_t)30, (int32_t)-31, &r_s32)) 54 return -1; 55 if (r_s32 != -1) 56 return -1; 57 if (ADD_OVERFLOW((int32_t)30, (int32_t)-31, &r_s32)) 58 return -1; 59 if (r_s32 != -1) 60 return -1; 61 if (ADD_OVERFLOW((int32_t)-31, (uint32_t)30, &r_s32)) 62 return -1; 63 if (r_s32 != -1) 64 return -1; 65 66 if (ADD_OVERFLOW(INT32_MIN + 1, -1, &r_s32)) 67 return -1; 68 if (r_s32 != INT32_MIN) 69 return -1; 70 if (!ADD_OVERFLOW(INT32_MIN, -1, &r_s32)) 71 return -1; 72 if (!ADD_OVERFLOW(INT32_MIN + 1, -2, &r_s32)) 73 return -1; 74 if (!ADD_OVERFLOW(INT32_MAX, INT32_MAX, &r_s32)) 75 return -1; 76 if (ADD_OVERFLOW(INT32_MAX, INT32_MAX, &r_u32)) 77 return -1; 78 if (!ADD_OVERFLOW(INTMAX_MAX, INTMAX_MAX, &r_sm)) 79 return -1; 80 if (ADD_OVERFLOW(INTMAX_MAX, INTMAX_MAX, &r_um)) 81 return -1; 82 if (!ADD_OVERFLOW(INT32_MAX / 2 + 1, INT32_MAX / 2 + 1, &r_s32)) 83 return -1; 84 if (ADD_OVERFLOW(INT32_MAX / 2, INT32_MAX / 2 + 1, &r_s32)) 85 return -1; 86 if (r_s32 != INT32_MAX) 87 return -1; 88 89 return 0; 90 } 91 92 static int self_test_sub_overflow(void) 93 { 94 uint32_t r_u32; 95 int32_t r_s32; 96 intmax_t r_sm; 97 98 if (SUB_OVERFLOW(8U, 1U, &r_s32)) 99 return -1; 100 if (r_s32 != 7) 101 return -1; 102 if (SUB_OVERFLOW(32U, 30U, &r_u32)) 103 return -1; 104 if (r_u32 != 2) 105 return -1; 106 if (!SUB_OVERFLOW(30U, 31U, &r_u32)) 107 return -1; 108 109 if (SUB_OVERFLOW(30, 31, &r_s32)) 110 return -1; 111 if (r_s32 != -1) 112 return -1; 113 if (SUB_OVERFLOW(-1, INT32_MAX, &r_s32)) 114 return -1; 115 if (r_s32 != INT32_MIN) 116 return -1; 117 if (!SUB_OVERFLOW(-2, INT32_MAX, &r_s32)) 118 return -1; 119 120 if (SUB_OVERFLOW((uint32_t)30, (int32_t)-31, &r_s32)) 121 return -1; 122 if (r_s32 != 61) 123 return -1; 124 if (SUB_OVERFLOW((int32_t)30, (int32_t)-31, &r_s32)) 125 return -1; 126 if (r_s32 != 61) 127 return -1; 128 if (SUB_OVERFLOW((int32_t)-31, (uint32_t)30, &r_s32)) 129 return -1; 130 if (r_s32 != -61) 131 return -1; 132 if (SUB_OVERFLOW((int32_t)-31, (int32_t)-30, &r_s32)) 133 return -1; 134 if (r_s32 != -1) 135 return -1; 136 137 if (SUB_OVERFLOW((int32_t)31, -(INTMAX_MIN + 1), &r_sm)) 138 return -1; 139 if (r_sm != (INTMAX_MIN + 32)) 140 return -1; 141 142 return 0; 143 } 144 145 static int self_test_mul_unsigned_overflow(void) 146 { 147 const size_t um_half_shift = sizeof(uintmax_t) * 8 / 2; 148 const uintmax_t um_half_mask = UINTMAX_MAX >> um_half_shift; 149 uint32_t r_u32; 150 uintmax_t r_um; 151 152 if (MUL_OVERFLOW(32, 30, &r_u32)) 153 return -1; 154 if (r_u32 != 960) 155 return -1; 156 if (MUL_OVERFLOW(-32, -30, &r_u32)) 157 return -1; 158 if (r_u32 != 960) 159 return -1; 160 161 if (MUL_OVERFLOW(UINTMAX_MAX, 1, &r_um)) 162 return -1; 163 if (r_um != UINTMAX_MAX) 164 return -1; 165 if (MUL_OVERFLOW(UINTMAX_MAX / 4, 4, &r_um)) 166 return -1; 167 if (r_um != (UINTMAX_MAX - 3)) 168 return -1; 169 if (!MUL_OVERFLOW(UINTMAX_MAX / 4 + 1, 4, &r_um)) 170 return -1; 171 if (!MUL_OVERFLOW(UINTMAX_MAX, UINTMAX_MAX, &r_um)) 172 return -1; 173 if (!MUL_OVERFLOW(um_half_mask << um_half_shift, 174 um_half_mask << um_half_shift, &r_um)) 175 return -1; 176 177 return 0; 178 } 179 180 static int self_test_mul_signed_overflow(void) 181 { 182 intmax_t r; 183 184 if (MUL_OVERFLOW(32, -30, &r)) 185 return -1; 186 if (r != -960) 187 return -1; 188 if (MUL_OVERFLOW(-32, 30, &r)) 189 return -1; 190 if (r != -960) 191 return -1; 192 if (MUL_OVERFLOW(32, 30, &r)) 193 return -1; 194 if (r != 960) 195 return -1; 196 197 if (MUL_OVERFLOW(INTMAX_MAX, 1, &r)) 198 return -1; 199 if (r != INTMAX_MAX) 200 return -1; 201 if (MUL_OVERFLOW(INTMAX_MAX / 4, 4, &r)) 202 return -1; 203 if (r != (INTMAX_MAX - 3)) 204 return -1; 205 if (!MUL_OVERFLOW(INTMAX_MAX / 4 + 1, 4, &r)) 206 return -1; 207 if (!MUL_OVERFLOW(INTMAX_MAX, INTMAX_MAX, &r)) 208 return -1; 209 if (MUL_OVERFLOW(INTMAX_MIN + 1, 1, &r)) 210 return -1; 211 if (r != INTMAX_MIN + 1) 212 return -1; 213 if (MUL_OVERFLOW(1, INTMAX_MIN + 1, &r)) 214 return -1; 215 if (r != INTMAX_MIN + 1) 216 return -1; 217 if (MUL_OVERFLOW(0, INTMAX_MIN, &r)) 218 return -1; 219 if (r != 0) 220 return -1; 221 if (MUL_OVERFLOW(1, INTMAX_MIN, &r)) 222 return -1; 223 if (r != INTMAX_MIN) 224 return -1; 225 226 return 0; 227 } 228 229 /* test division support. resulting trace shall be manually checked */ 230 static int self_test_division(void) 231 { 232 signed a, b, c, d; 233 bool r; 234 int ret = 0; 235 236 LOG(""); 237 LOG("division tests (division and modulo):"); 238 /* get some unpredicted values to prevent compilation optimizations: */ 239 /* => use the stack address */ 240 241 LOG("- test with unsigned small integers:"); 242 a = (signed)((unsigned)(vaddr_t)&a & 0xFFFFF); 243 b = (signed)((unsigned)(vaddr_t)&b & 0x00FFF) + 1; 244 c = a / b; 245 d = a % b; 246 r = ((b * c + d) == a); 247 if (!r) 248 ret = -1; 249 LOG(" 0x%08x / 0x%08x = %u / %u = %u = 0x%x)", 250 (unsigned)a, (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)c, 251 (unsigned)c); 252 LOG(" 0x%08x %% 0x%08x = %u %% %u = %u = 0x%x)", (unsigned)a, 253 (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)d, (unsigned)d); 254 LOG(" check results => %s", r ? "ok" : "FAILED !!!"); 255 LOG(""); 256 257 LOG("- test with signed small integers, negative numerator:"); 258 a = (signed)(vaddr_t)&a; 259 b = (signed)((unsigned)(vaddr_t)&b & 0x00FFF) - 1; 260 c = a / b; 261 d = a % b; 262 r = ((b * c + d) == a); 263 if (!r) 264 ret = -1; 265 LOG(" 0x%08x / 0x%08x = %d / %d = %d = 0x%x)", 266 (unsigned)a, (unsigned)b, (signed)a, (signed)b, (signed)c, 267 (unsigned)c); 268 LOG(" 0x%08x %% 0x%08x = %d %% %d = %d = 0x%x)", (unsigned)a, 269 (unsigned)b, (signed)a, (signed)b, (signed)d, (unsigned)d); 270 LOG(" check results => %s", r ? "ok" : "FAILED !!!"); 271 LOG(""); 272 273 LOG("- test with signed small integers, negative denominator:"); 274 a = (signed)((unsigned)(vaddr_t)&a & 0xFFFFF); 275 b = -(signed)((unsigned)(vaddr_t)&b & 0x00FFF) + 1; 276 c = a / b; 277 d = a % b; 278 279 LOG("- test with unsigned integers, big numerator (> 0x80000000):"); 280 a = (signed)(vaddr_t)&a; 281 b = (signed)((unsigned)(vaddr_t)&b & 0x00FFF) + 1; 282 c = (signed)((unsigned)a / (unsigned)b); 283 d = (signed)((unsigned)a % (unsigned)b); 284 r = (((unsigned)b * (unsigned)c + (unsigned)d) == (unsigned)a); 285 if (!r) 286 ret = -1; 287 LOG(" 0x%08x / 0x%08x = %u / %u = %u = 0x%x)", 288 (unsigned)a, (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)c, 289 (unsigned)c); 290 LOG(" 0x%08x %% 0x%08x = %u %% %u = %u = 0x%x)", (unsigned)a, 291 (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)d, (unsigned)d); 292 LOG(" check results => %s", r ? "ok" : "FAILED !!!"); 293 LOG(""); 294 295 LOG("- test with unsigned integers, big num. & denom. (> 0x80000000):"); 296 a = (signed)(vaddr_t)&a; 297 b = (signed)((unsigned)(vaddr_t)&a - 1); 298 c = (signed)((unsigned)a / (unsigned)b); 299 d = (signed)((unsigned)a % (unsigned)b); 300 r = (((unsigned)b * (unsigned)c + (unsigned)d) == (unsigned)a); 301 if (!r) 302 ret = -1; 303 LOG(" 0x%08x / 0x%08x = %u / %u = %u = 0x%x)", 304 (unsigned)a, (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)c, 305 (unsigned)c); 306 LOG(" 0x%08x %% 0x%08x = %u %% %u = %u = 0x%x)", (unsigned)a, 307 (unsigned)b, (unsigned)a, (unsigned)b, (unsigned)d, (unsigned)d); 308 LOG(" check results => %s", r ? "ok" : "FAILED !!!"); 309 LOG(""); 310 311 return ret; 312 } 313 314 /* test malloc support. resulting trace shall be manually checked */ 315 static int self_test_malloc(void) 316 { 317 char *p1 = NULL, *p2 = NULL; 318 int *p3 = NULL, *p4 = NULL; 319 bool r; 320 int ret = 0; 321 322 LOG("malloc tests:"); 323 LOG(" p1=%p p2=%p p3=%p p4=%p", 324 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 325 /* test malloc */ 326 p1 = malloc(1024); 327 LOG("- p1 = malloc(1024)"); 328 p2 = malloc(1024); 329 LOG("- p2 = malloc(1024)"); 330 LOG(" p1=%p p2=%p p3=%p p4=%p", 331 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 332 r = (p1 && p2 && malloc_buffer_is_within_alloced(p1, 1024) && 333 !malloc_buffer_is_within_alloced(p1 + 25, 1000) && 334 !malloc_buffer_is_within_alloced(p1 - 25, 500) && 335 malloc_buffer_overlaps_heap(p1 - 25, 500)); 336 if (!r) 337 ret = -1; 338 LOG(" => test %s", r ? "ok" : "FAILED"); 339 LOG(""); 340 341 /* test realloc */ 342 p3 = realloc(p1, 3 * 1024); 343 if (p3) 344 p1 = NULL; 345 LOG("- p3 = realloc(p1, 3*1024)"); 346 LOG("- free p2"); 347 free(p2); 348 p2 = malloc(1024); 349 LOG("- p2 = malloc(1024)"); 350 LOG(" p1=%p p2=%p p3=%p p4=%p", 351 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 352 r = (p2 && p3); 353 if (!r) 354 ret = -1; 355 LOG(" => test %s", r ? "ok" : "FAILED"); 356 LOG(""); 357 LOG("- free p1, p2, p3"); 358 free(p1); 359 free(p2); 360 free(p3); 361 p1 = NULL; 362 p2 = NULL; 363 p3 = NULL; 364 365 /* test calloc */ 366 p3 = calloc(4, 1024); 367 p4 = calloc(0x100, 1024 * 1024); 368 LOG("- p3 = calloc(4, 1024)"); 369 LOG("- p4 = calloc(0x100, 1024*1024) too big: should fail!"); 370 LOG(" p1=%p p2=%p p3=%p p4=%p", 371 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 372 r = (p3 && !p4); 373 if (!r) 374 ret = -1; 375 LOG(" => test %s", r ? "ok" : "FAILED"); 376 LOG(""); 377 LOG("- free p3, p4"); 378 free(p3); 379 free(p4); 380 p3 = NULL; 381 p4 = NULL; 382 383 /* test memalign */ 384 p3 = memalign(0x1000, 1024); 385 LOG("- p3 = memalign(%d, 1024)", 0x1000); 386 p1 = malloc(1024); 387 LOG("- p1 = malloc(1024)"); 388 p4 = memalign(0x100, 512); 389 LOG("- p4 = memalign(%d, 512)", 0x100); 390 LOG(" p1=%p p2=%p p3=%p p4=%p", 391 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 392 r = (p1 && p3 && p4 && 393 !((vaddr_t)p3 % 0x1000) && !((vaddr_t)p4 % 0x100)); 394 if (!r) 395 ret = -1; 396 LOG(" => test %s", r ? "ok" : "FAILED"); 397 LOG(""); 398 LOG("- free p1, p3, p4"); 399 free(p1); 400 free(p3); 401 free(p4); 402 p1 = NULL; 403 p3 = NULL; 404 p4 = NULL; 405 406 /* test memalign with invalid alignments */ 407 p3 = memalign(100, 1024); 408 LOG("- p3 = memalign(%d, 1024)", 100); 409 p4 = memalign(0, 1024); 410 LOG("- p4 = memalign(%d, 1024)", 0); 411 LOG(" p1=%p p2=%p p3=%p p4=%p", 412 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 413 r = (!p3 && !p4); 414 if (!r) 415 ret = -1; 416 LOG(" => test %s", r ? "ok" : "FAILED"); 417 LOG(""); 418 LOG("- free p3, p4"); 419 free(p3); 420 free(p4); 421 p3 = NULL; 422 p4 = NULL; 423 424 /* test free(NULL) */ 425 LOG("- free NULL"); 426 free(NULL); 427 LOG(""); 428 LOG("malloc test done"); 429 430 return ret; 431 } 432 433 #ifdef CFG_NS_VIRTUALIZATION 434 /* test nex_malloc support. resulting trace shall be manually checked */ 435 static int self_test_nex_malloc(void) 436 { 437 char *p1 = NULL, *p2 = NULL; 438 int *p3 = NULL, *p4 = NULL; 439 bool r; 440 int ret = 0; 441 442 LOG("nex_malloc tests:"); 443 LOG(" p1=%p p2=%p p3=%p p4=%p", 444 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 445 /* test malloc */ 446 p1 = nex_malloc(1024); 447 LOG("- p1 = nex_malloc(1024)"); 448 p2 = nex_malloc(1024); 449 LOG("- p2 = nex_malloc(1024)"); 450 LOG(" p1=%p p2=%p p3=%p p4=%p", 451 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 452 r = (p1 && p2 && nex_malloc_buffer_is_within_alloced(p1, 1024) && 453 !nex_malloc_buffer_is_within_alloced(p1 + 25, 1000) && 454 !nex_malloc_buffer_is_within_alloced(p1 - 25, 500) && 455 nex_malloc_buffer_overlaps_heap(p1 - 25, 500)); 456 if (!r) 457 ret = -1; 458 LOG(" => test %s", r ? "ok" : "FAILED"); 459 LOG(""); 460 461 /* test realloc */ 462 p3 = nex_realloc(p1, 3 * 1024); 463 if (p3) 464 p1 = NULL; 465 LOG("- p3 = nex_realloc(p1, 3*1024)"); 466 LOG("- nex_free p2"); 467 nex_free(p2); 468 p2 = nex_malloc(1024); 469 LOG("- p2 = nex_malloc(1024)"); 470 LOG(" p1=%p p2=%p p3=%p p4=%p", 471 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 472 r = (p2 && p3); 473 if (!r) 474 ret = -1; 475 LOG(" => test %s", r ? "ok" : "FAILED"); 476 LOG(""); 477 LOG("- nex_free p1, p2, p3"); 478 nex_free(p1); 479 nex_free(p2); 480 nex_free(p3); 481 p1 = NULL; 482 p2 = NULL; 483 p3 = NULL; 484 485 /* test calloc */ 486 p3 = nex_calloc(4, 1024); 487 p4 = nex_calloc(0x100, 1024 * 1024); 488 LOG("- p3 = nex_calloc(4, 1024)"); 489 LOG("- p4 = nex_calloc(0x100, 1024*1024) too big: should fail!"); 490 LOG(" p1=%p p2=%p p3=%p p4=%p", 491 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 492 r = (p3 && !p4); 493 if (!r) 494 ret = -1; 495 LOG(" => test %s", r ? "ok" : "FAILED"); 496 LOG(""); 497 LOG("- nex_free p3, p4"); 498 nex_free(p3); 499 nex_free(p4); 500 p3 = NULL; 501 p4 = NULL; 502 503 /* test memalign */ 504 p3 = nex_memalign(0x1000, 1024); 505 LOG("- p3 = nex_memalign(%d, 1024)", 0x1000); 506 p1 = nex_malloc(1024); 507 LOG("- p1 = nex_malloc(1024)"); 508 p4 = nex_memalign(0x100, 512); 509 LOG("- p4 = nex_memalign(%d, 512)", 0x100); 510 LOG(" p1=%p p2=%p p3=%p p4=%p", 511 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 512 r = (p1 && p3 && p4 && 513 !((vaddr_t)p3 % 0x1000) && !((vaddr_t)p4 % 0x100)); 514 if (!r) 515 ret = -1; 516 LOG(" => test %s", r ? "ok" : "FAILED"); 517 LOG(""); 518 LOG("- nex_free p1, p3, p4"); 519 nex_free(p1); 520 nex_free(p3); 521 nex_free(p4); 522 p1 = NULL; 523 p3 = NULL; 524 p4 = NULL; 525 526 /* test memalign with invalid alignments */ 527 p3 = nex_memalign(100, 1024); 528 LOG("- p3 = nex_memalign(%d, 1024)", 100); 529 p4 = nex_memalign(0, 1024); 530 LOG("- p4 = nex_memalign(%d, 1024)", 0); 531 LOG(" p1=%p p2=%p p3=%p p4=%p", 532 (void *)p1, (void *)p2, (void *)p3, (void *)p4); 533 r = (!p3 && !p4); 534 if (!r) 535 ret = -1; 536 LOG(" => test %s", r ? "ok" : "FAILED"); 537 LOG(""); 538 LOG("- nex_free p3, p4"); 539 nex_free(p3); 540 nex_free(p4); 541 p3 = NULL; 542 p4 = NULL; 543 544 /* test free(NULL) */ 545 LOG("- nex_free NULL"); 546 nex_free(NULL); 547 LOG(""); 548 LOG("nex_malloc test done"); 549 550 return ret; 551 } 552 #else /* CFG_NS_VIRTUALIZATION */ 553 static int self_test_nex_malloc(void) 554 { 555 return 0; 556 } 557 #endif 558 559 static int check_virt_to_phys(vaddr_t va, paddr_t exp_pa, 560 enum teecore_memtypes m) 561 { 562 paddr_t pa = 0; 563 void *v = NULL; 564 565 pa = virt_to_phys((void *)va); 566 LOG("virt_to_phys(%#"PRIxVA") => %#"PRIxPA" (expect %#"PRIxPA")", 567 va, pa, exp_pa); 568 if (pa != exp_pa) 569 goto fail; 570 571 if (!exp_pa) 572 return 0; 573 574 v = phys_to_virt(pa, m, 1); 575 LOG("phys_to_virt(%#"PRIxPA") => %p (expect %#"PRIxVA")", 576 pa, v, va); 577 if ((vaddr_t)v != va) 578 goto fail; 579 return 0; 580 581 fail: 582 LOG("Fail"); 583 return -1; 584 } 585 586 static int check_phys_to_virt(paddr_t pa, void *exp_va, 587 enum teecore_memtypes m) 588 { 589 paddr_t new_pa = 0; 590 void *v = NULL; 591 592 v = phys_to_virt(pa, m, 1); 593 LOG("phys_to_virt(%#"PRIxPA") => %p (expect %p)", 594 pa, v, exp_va); 595 if (v != exp_va) 596 goto fail; 597 598 if (!exp_va) 599 return 0; 600 601 new_pa = virt_to_phys(v); 602 LOG("virt_to_phys(%p) => %#"PRIxPA" (expect %#"PRIxPA")", 603 v, new_pa, pa); 604 if (new_pa != pa) 605 goto fail; 606 return 0; 607 608 fail: 609 LOG("Fail"); 610 return -1; 611 } 612 613 static int self_test_va2pa(void) 614 { 615 void *ptr = self_test_va2pa; 616 int ret = 0; 617 618 if (IS_ENABLED(CFG_DYN_CONFIG) && VCORE_FREE_SZ) { 619 vaddr_t va_base = VCORE_FREE_PA; 620 paddr_t pa_base = 0; 621 622 pa_base = virt_to_phys((void *)va_base); 623 if (!pa_base) { 624 LOG("virt_to_phys(%#"PRIxVA") => 0 Fail!", va_base); 625 return -1; 626 } 627 628 /* 629 * boot_mem_release_unused() and 630 * boot_mem_release_tmp_alloc() has been called during 631 * boot. 632 * 633 * First pages of VCORE_FREE are expected to be allocated 634 * with boot_mem_alloc() while the end of VCORE_FREE should 635 * have been freed by the two mentioned release functions. 636 */ 637 if (check_virt_to_phys(va_base, pa_base, MEM_AREA_TEE_RAM)) 638 ret = -1; 639 if (check_virt_to_phys(va_base + 16, pa_base + 16, 640 MEM_AREA_TEE_RAM)) 641 ret = -1; 642 if (check_virt_to_phys(va_base + VCORE_FREE_SZ - 643 SMALL_PAGE_SIZE, 0, MEM_AREA_TEE_RAM)) 644 ret = -1; 645 if (check_virt_to_phys(va_base + VCORE_FREE_SZ - 16, 0, 646 MEM_AREA_TEE_RAM)) 647 ret = -1; 648 } 649 650 if (!IS_ENABLED(CFG_WITH_PAGER) && 651 check_phys_to_virt(virt_to_phys(ptr), ptr, MEM_AREA_TEE_RAM)) 652 ret = -1; 653 if (check_phys_to_virt(virt_to_phys(ptr), NULL, MEM_AREA_IO_SEC)) 654 ret = -1; 655 if (check_virt_to_phys(0, 0, MEM_AREA_TEE_RAM)) 656 ret = -1; 657 if (check_phys_to_virt(0, NULL, MEM_AREA_TEE_RAM)) 658 ret = -1; 659 660 return ret; 661 } 662 663 #ifdef CFG_CORE_SANITIZE_KADDRESS 664 665 #define ASAN_TEST_SUCCESS 1 666 #define ASAN_TEST_BUF_SIZE 15 667 668 static char asan_test_sgbuf[ASAN_TEST_BUF_SIZE]; 669 char asan_test_gbuf[ASAN_TEST_BUF_SIZE]; 670 static const char asan_test_sgbuf_ro[ASAN_TEST_BUF_SIZE + 1]; 671 672 static jmp_buf asan_test_jmp; 673 674 struct asan_test_ctx { 675 char *pmalloc1; 676 char *pmalloc2[3]; 677 char write_value; 678 void (*write_func)(char *buf, size_t pos, char value); 679 char (*read_func)(char *buf, size_t pos); 680 void *(*memcpy_func)(void *__restrict dst, 681 const void *__restrict src, size_t size); 682 void *(*memset_func)(void *buf, int val, size_t size); 683 }; 684 685 static void asan_out_of_bounds_write(char *buf, size_t pos, 686 char value) 687 { 688 buf[pos] = value; 689 } 690 691 static char asan_out_of_bounds_read(char *buf, size_t pos) 692 { 693 return buf[pos]; 694 } 695 696 static void *asan_out_of_bounds_memcpy(void *__restrict dst, 697 const void *__restrict src, 698 size_t size) 699 { 700 return memcpy(dst, src, size); 701 } 702 703 static void *asan_out_of_bounds_memset(void *buf, int val, size_t size) 704 { 705 return memset(buf, val, size); 706 } 707 708 static void asan_panic_test(void) 709 { 710 longjmp(asan_test_jmp, ASAN_TEST_SUCCESS); 711 } 712 713 static void asan_test_cleanup(struct asan_test_ctx *ctx) 714 { 715 unsigned int i = 0; 716 717 free(ctx->pmalloc1); 718 719 for (; i < ARRAY_SIZE(ctx->pmalloc2); i++) 720 free(ctx->pmalloc2[i]); 721 } 722 723 static int asan_call_test(struct asan_test_ctx *ctx, 724 void (*test)(struct asan_test_ctx *ctx), 725 const char __maybe_unused *desc) 726 { 727 int ret = 0; 728 729 ret = setjmp(asan_test_jmp); 730 if (ret == 0) { 731 test(ctx); 732 ret = -1; 733 } else if (ret == ASAN_TEST_SUCCESS) { 734 ret = 0; 735 } else { 736 panic("Unexpected setjmp return"); 737 } 738 LOG(" => [asan] test %s: %s", desc, !ret ? "ok" : "FAILED"); 739 return ret; 740 } 741 742 #ifndef CFG_DYN_CONFIG 743 static void asan_stack(struct asan_test_ctx *ctx) 744 { 745 char buf[ASAN_TEST_BUF_SIZE] = {0}; 746 747 ctx->write_func(buf, ASAN_TEST_BUF_SIZE, ctx->write_value); 748 } 749 #endif 750 751 static void asan_global_stat(struct asan_test_ctx *ctx) 752 { 753 ctx->write_func(asan_test_sgbuf, ASAN_TEST_BUF_SIZE, 754 ctx->write_value); 755 } 756 757 static void asan_global_ro(struct asan_test_ctx *ctx) 758 { 759 ctx->read_func((char *)asan_test_sgbuf_ro, 760 ASAN_TEST_BUF_SIZE + 1); 761 } 762 763 static void asan_global(struct asan_test_ctx *ctx) 764 { 765 ctx->write_func(asan_test_gbuf, ASAN_TEST_BUF_SIZE, 766 ctx->write_value); 767 } 768 769 static void asan_malloc(struct asan_test_ctx *ctx) 770 { 771 ctx->pmalloc1 = malloc(ASAN_TEST_BUF_SIZE); 772 773 if (ctx->pmalloc1) 774 ctx->write_func(ctx->pmalloc1, ASAN_TEST_BUF_SIZE, 775 ctx->write_value); 776 } 777 778 static void asan_malloc2(struct asan_test_ctx *ctx) 779 { 780 unsigned int i = 0; 781 char *p = NULL; 782 size_t aligned_size = ROUNDUP(ASAN_TEST_BUF_SIZE, 8); 783 784 for (; i < ARRAY_SIZE(ctx->pmalloc2); i++) { 785 ctx->pmalloc2[i] = malloc(aligned_size); 786 if (!ctx->pmalloc2[i]) 787 return; 788 } 789 p = ctx->pmalloc2[1]; 790 ctx->write_func(p, aligned_size, ctx->write_value); 791 } 792 793 static void asan_use_after_free(struct asan_test_ctx *ctx) 794 { 795 char *a = malloc(ASAN_TEST_BUF_SIZE); 796 797 if (a) { 798 free(a); 799 ctx->write_func(a, 0, ctx->write_value); 800 } 801 } 802 803 static void asan_memcpy_dst(struct asan_test_ctx *ctx) 804 { 805 static char b[ASAN_TEST_BUF_SIZE + 1]; 806 static char a[ASAN_TEST_BUF_SIZE]; 807 808 ctx->memcpy_func(a, b, sizeof(b)); 809 } 810 811 static void asan_memcpy_src(struct asan_test_ctx *ctx) 812 { 813 static char b[ASAN_TEST_BUF_SIZE]; 814 static char a[ASAN_TEST_BUF_SIZE + 1]; 815 816 ctx->memcpy_func(a, b, sizeof(a)); 817 } 818 819 static void asan_memset(struct asan_test_ctx *ctx) 820 { 821 static char b[ASAN_TEST_BUF_SIZE]; 822 823 ctx->memset_func(b, ctx->write_value, ASAN_TEST_BUF_SIZE + 1); 824 } 825 826 static int self_test_asan(void) 827 { 828 uint32_t vfp_state = UINT32_C(0); 829 int ret = 0; 830 struct asan_test_ctx ctx = {0}; 831 832 ctx.write_value = 0xab; 833 ctx.write_func = asan_out_of_bounds_write; 834 ctx.read_func = asan_out_of_bounds_read; 835 ctx.memcpy_func = asan_out_of_bounds_memcpy; 836 ctx.memset_func = asan_out_of_bounds_memset; 837 838 asan_set_panic_cb(asan_panic_test); 839 /* 840 * We need enable access to floating-point registers, in other 841 * way sync exception during setjmp/longjmp will occur. 842 */ 843 vfp_state = thread_kernel_enable_vfp(); 844 845 if (asan_call_test(&ctx, asan_global_stat, "(s) glob overflow") || 846 asan_call_test(&ctx, asan_global, "glob overflow") || 847 asan_call_test(&ctx, asan_global_ro, "glob ro overflow") || 848 #ifndef CFG_DYN_CONFIG 849 asan_call_test(&ctx, asan_stack, "stack overflow") || 850 #endif 851 asan_call_test(&ctx, asan_malloc, "malloc") || 852 asan_call_test(&ctx, asan_malloc2, "malloc2") || 853 asan_call_test(&ctx, asan_use_after_free, "use_after_free") || 854 asan_call_test(&ctx, asan_memcpy_dst, "memcpy_dst") || 855 asan_call_test(&ctx, asan_memcpy_src, "memcpy_src") || 856 asan_call_test(&ctx, asan_memset, "memset")) { 857 ret = -1; 858 } 859 860 thread_kernel_disable_vfp(vfp_state); 861 asan_test_cleanup(&ctx); 862 asan_set_panic_cb(asan_panic); 863 return ret; 864 } 865 #else 866 static int self_test_asan(void) 867 { 868 return 0; 869 } 870 #endif 871 872 /* exported entry points for some basic test */ 873 TEE_Result core_self_tests(uint32_t nParamTypes __unused, 874 TEE_Param pParams[TEE_NUM_PARAMS] __unused) 875 { 876 if (self_test_mul_signed_overflow() || self_test_add_overflow() || 877 self_test_sub_overflow() || self_test_mul_unsigned_overflow() || 878 self_test_division() || self_test_malloc() || 879 self_test_nex_malloc() || self_test_va2pa() || 880 self_test_asan()) { 881 EMSG("some self_test_xxx failed! you should enable local LOG"); 882 return TEE_ERROR_GENERIC; 883 } 884 return TEE_SUCCESS; 885 } 886 887 /* Exported entrypoint for dt_driver tests */ 888 TEE_Result core_dt_driver_tests(uint32_t nParamTypes __unused, 889 TEE_Param pParams[TEE_NUM_PARAMS] __unused) 890 { 891 if (IS_ENABLED(CFG_DT_DRIVER_EMBEDDED_TEST)) { 892 if (dt_driver_test_status()) 893 return TEE_ERROR_GENERIC; 894 } else { 895 IMSG("dt_driver tests are not embedded"); 896 } 897 898 return TEE_SUCCESS; 899 } 900