1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2020 ARM Limited 3 4 #define _GNU_SOURCE 5 6 #include <assert.h> 7 #include <errno.h> 8 #include <fcntl.h> 9 #include <signal.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <ucontext.h> 14 #include <sys/mman.h> 15 #include <sys/stat.h> 16 #include <sys/types.h> 17 18 #include "kselftest.h" 19 #include "mte_common_util.h" 20 #include "mte_def.h" 21 22 #define RUNS (MT_TAG_COUNT) 23 #define UNDERFLOW MT_GRANULE_SIZE 24 #define OVERFLOW MT_GRANULE_SIZE 25 #define TAG_CHECK_ON 0 26 #define TAG_CHECK_OFF 1 27 #define ATAG_CHECK_ON 1 28 #define ATAG_CHECK_OFF 0 29 30 #define TEST_NAME_MAX 256 31 32 enum mte_mem_check_type { 33 CHECK_ANON_MEM = 0, 34 CHECK_FILE_MEM = 1, 35 CHECK_CLEAR_PROT_MTE = 2, 36 }; 37 38 enum mte_tag_op_type { 39 TAG_OP_ALL = 0, 40 TAG_OP_STONLY = 1, 41 }; 42 43 struct check_mmap_testcase { 44 int check_type; 45 int mem_type; 46 int mte_sync; 47 int mapping; 48 int tag_check; 49 int atag_check; 50 int tag_op; 51 bool enable_tco; 52 }; 53 54 #define TAG_OP_ALL 0 55 #define TAG_OP_STONLY 1 56 57 static size_t page_size; 58 static int sizes[] = { 59 1, 537, 989, 1269, MT_GRANULE_SIZE - 1, MT_GRANULE_SIZE, 60 /* page size - 1*/ 0, /* page_size */ 0, /* page size + 1 */ 0 61 }; 62 63 static int check_mte_memory(char *ptr, int size, int mode, 64 int tag_check,int atag_check, int tag_op) 65 { 66 char buf[MT_GRANULE_SIZE]; 67 68 if (!mtefar_support && atag_check == ATAG_CHECK_ON) 69 return KSFT_SKIP; 70 71 if (atag_check == ATAG_CHECK_ON) 72 ptr = mte_insert_atag(ptr); 73 74 mte_initialize_current_context(mode, (uintptr_t)ptr, size); 75 memset(ptr, '1', size); 76 mte_wait_after_trig(); 77 if (cur_mte_cxt.fault_valid == true) 78 return KSFT_FAIL; 79 80 mte_initialize_current_context(mode, (uintptr_t)ptr, -UNDERFLOW); 81 memset(ptr - UNDERFLOW, '2', UNDERFLOW); 82 mte_wait_after_trig(); 83 if (cur_mte_cxt.fault_valid == false && tag_check == TAG_CHECK_ON) 84 return KSFT_FAIL; 85 if (cur_mte_cxt.fault_valid == true && tag_check == TAG_CHECK_OFF) 86 return KSFT_FAIL; 87 88 mte_initialize_current_context(mode, (uintptr_t)ptr, size + OVERFLOW); 89 memset(ptr + size, '3', OVERFLOW); 90 mte_wait_after_trig(); 91 if (cur_mte_cxt.fault_valid == false && tag_check == TAG_CHECK_ON) 92 return KSFT_FAIL; 93 if (cur_mte_cxt.fault_valid == true && tag_check == TAG_CHECK_OFF) 94 return KSFT_FAIL; 95 96 if (tag_op == TAG_OP_STONLY) { 97 mte_initialize_current_context(mode, (uintptr_t)ptr, -UNDERFLOW); 98 memcpy(buf, ptr - UNDERFLOW, MT_GRANULE_SIZE); 99 mte_wait_after_trig(); 100 if (cur_mte_cxt.fault_valid == true) 101 return KSFT_FAIL; 102 103 mte_initialize_current_context(mode, (uintptr_t)ptr, size + OVERFLOW); 104 memcpy(buf, ptr + size, MT_GRANULE_SIZE); 105 mte_wait_after_trig(); 106 if (cur_mte_cxt.fault_valid == true) 107 return KSFT_FAIL; 108 } 109 110 return KSFT_PASS; 111 } 112 113 static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, 114 int tag_check, int atag_check, int tag_op) 115 { 116 char *ptr, *map_ptr; 117 int run, result, map_size; 118 int item = ARRAY_SIZE(sizes); 119 120 if (tag_op == TAG_OP_STONLY && !mtestonly_support) 121 return KSFT_SKIP; 122 123 mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, tag_op); 124 for (run = 0; run < item; run++) { 125 map_size = sizes[run] + OVERFLOW + UNDERFLOW; 126 map_ptr = (char *)mte_allocate_memory(map_size, mem_type, mapping, false); 127 if (check_allocated_memory(map_ptr, map_size, mem_type, false) != KSFT_PASS) 128 return KSFT_FAIL; 129 130 ptr = map_ptr + UNDERFLOW; 131 mte_initialize_current_context(mode, (uintptr_t)ptr, sizes[run]); 132 /* Only mte enabled memory will allow tag insertion */ 133 ptr = mte_insert_tags((void *)ptr, sizes[run]); 134 if (!ptr || cur_mte_cxt.fault_valid == true) { 135 ksft_print_msg("FAIL: Insert tags on anonymous mmap memory\n"); 136 munmap((void *)map_ptr, map_size); 137 return KSFT_FAIL; 138 } 139 result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check, tag_op); 140 mte_clear_tags((void *)ptr, sizes[run]); 141 mte_free_memory((void *)map_ptr, map_size, mem_type, false); 142 if (result != KSFT_PASS) 143 return result; 144 } 145 return KSFT_PASS; 146 } 147 148 static int check_file_memory_mapping(int mem_type, int mode, int mapping, 149 int tag_check, int atag_check, int tag_op) 150 { 151 char *ptr, *map_ptr; 152 int run, fd, map_size; 153 int total = ARRAY_SIZE(sizes); 154 int result = KSFT_PASS; 155 156 if (tag_op == TAG_OP_STONLY && !mtestonly_support) 157 return KSFT_SKIP; 158 159 mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, tag_op); 160 for (run = 0; run < total; run++) { 161 fd = create_temp_file(); 162 if (fd == -1) 163 return KSFT_FAIL; 164 165 map_size = sizes[run] + UNDERFLOW + OVERFLOW; 166 map_ptr = (char *)mte_allocate_file_memory(map_size, mem_type, mapping, false, fd); 167 if (check_allocated_memory(map_ptr, map_size, mem_type, false) != KSFT_PASS) { 168 close(fd); 169 return KSFT_FAIL; 170 } 171 ptr = map_ptr + UNDERFLOW; 172 mte_initialize_current_context(mode, (uintptr_t)ptr, sizes[run]); 173 /* Only mte enabled memory will allow tag insertion */ 174 ptr = mte_insert_tags((void *)ptr, sizes[run]); 175 if (!ptr || cur_mte_cxt.fault_valid == true) { 176 ksft_print_msg("FAIL: Insert tags on file based memory\n"); 177 munmap((void *)map_ptr, map_size); 178 close(fd); 179 return KSFT_FAIL; 180 } 181 result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check, tag_op); 182 mte_clear_tags((void *)ptr, sizes[run]); 183 munmap((void *)map_ptr, map_size); 184 close(fd); 185 if (result != KSFT_PASS) 186 return result; 187 } 188 return KSFT_PASS; 189 } 190 191 static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping, int atag_check) 192 { 193 char *ptr, *map_ptr; 194 int run, prot_flag, result, fd, map_size; 195 int total = ARRAY_SIZE(sizes); 196 197 prot_flag = PROT_READ | PROT_WRITE; 198 mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG, false); 199 for (run = 0; run < total; run++) { 200 map_size = sizes[run] + OVERFLOW + UNDERFLOW; 201 ptr = (char *)mte_allocate_memory_tag_range(sizes[run], mem_type, mapping, 202 UNDERFLOW, OVERFLOW); 203 if (check_allocated_memory_range(ptr, sizes[run], mem_type, 204 UNDERFLOW, OVERFLOW) != KSFT_PASS) 205 return KSFT_FAIL; 206 map_ptr = ptr - UNDERFLOW; 207 /* Try to clear PROT_MTE property and verify it by tag checking */ 208 if (mprotect(map_ptr, map_size, prot_flag)) { 209 mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, 210 UNDERFLOW, OVERFLOW); 211 ksft_print_msg("FAIL: mprotect not ignoring clear PROT_MTE property\n"); 212 return KSFT_FAIL; 213 } 214 result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check, TAG_OP_ALL); 215 mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW); 216 if (result != KSFT_PASS) 217 return result; 218 219 fd = create_temp_file(); 220 if (fd == -1) 221 return KSFT_FAIL; 222 ptr = (char *)mte_allocate_file_memory_tag_range(sizes[run], mem_type, mapping, 223 UNDERFLOW, OVERFLOW, fd); 224 if (check_allocated_memory_range(ptr, sizes[run], mem_type, 225 UNDERFLOW, OVERFLOW) != KSFT_PASS) { 226 close(fd); 227 return KSFT_FAIL; 228 } 229 map_ptr = ptr - UNDERFLOW; 230 /* Try to clear PROT_MTE property and verify it by tag checking */ 231 if (mprotect(map_ptr, map_size, prot_flag)) { 232 ksft_print_msg("FAIL: mprotect not ignoring clear PROT_MTE property\n"); 233 mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, 234 UNDERFLOW, OVERFLOW); 235 close(fd); 236 return KSFT_FAIL; 237 } 238 result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check, TAG_OP_ALL); 239 mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW); 240 close(fd); 241 if (result != KSFT_PASS) 242 return result; 243 } 244 return KSFT_PASS; 245 } 246 247 const char *format_test_name(struct check_mmap_testcase *tc) 248 { 249 static char test_name[TEST_NAME_MAX]; 250 const char *check_type_str; 251 const char *mem_type_str; 252 const char *sync_str; 253 const char *mapping_str; 254 const char *tag_check_str; 255 const char *atag_check_str; 256 const char *tag_op_str; 257 258 switch (tc->check_type) { 259 case CHECK_ANON_MEM: 260 check_type_str = "anonymous memory"; 261 break; 262 case CHECK_FILE_MEM: 263 check_type_str = "file memory"; 264 break; 265 case CHECK_CLEAR_PROT_MTE: 266 check_type_str = "clear PROT_MTE flags"; 267 break; 268 default: 269 assert(0); 270 break; 271 } 272 273 switch (tc->mem_type) { 274 case USE_MMAP: 275 mem_type_str = "mmap"; 276 break; 277 case USE_MPROTECT: 278 mem_type_str = "mmap/mprotect"; 279 break; 280 default: 281 assert(0); 282 break; 283 } 284 285 switch (tc->mte_sync) { 286 case MTE_NONE_ERR: 287 sync_str = "no error"; 288 break; 289 case MTE_SYNC_ERR: 290 sync_str = "sync error"; 291 break; 292 case MTE_ASYNC_ERR: 293 sync_str = "async error"; 294 break; 295 default: 296 assert(0); 297 break; 298 } 299 300 switch (tc->mapping) { 301 case MAP_SHARED: 302 mapping_str = "shared"; 303 break; 304 case MAP_PRIVATE: 305 mapping_str = "private"; 306 break; 307 default: 308 assert(0); 309 break; 310 } 311 312 switch (tc->tag_check) { 313 case TAG_CHECK_ON: 314 tag_check_str = "tag check on"; 315 break; 316 case TAG_CHECK_OFF: 317 tag_check_str = "tag check off"; 318 break; 319 default: 320 assert(0); 321 break; 322 } 323 324 switch (tc->atag_check) { 325 case ATAG_CHECK_ON: 326 atag_check_str = "with address tag [63:60]"; 327 break; 328 case ATAG_CHECK_OFF: 329 atag_check_str = "without address tag [63:60]"; 330 break; 331 default: 332 assert(0); 333 break; 334 } 335 336 snprintf(test_name, sizeof(test_name), 337 "Check %s with %s mapping, %s mode, %s memory and %s (%s)\n", 338 check_type_str, mapping_str, sync_str, mem_type_str, 339 tag_check_str, atag_check_str); 340 341 switch (tc->tag_op) { 342 case TAG_OP_ALL: 343 tag_op_str = ""; 344 break; 345 case TAG_OP_STONLY: 346 tag_op_str = " / store-only"; 347 break; 348 default: 349 assert(0); 350 break; 351 } 352 353 snprintf(test_name, TEST_NAME_MAX, 354 "Check %s with %s mapping, %s mode, %s memory and %s (%s%s)\n", 355 check_type_str, mapping_str, sync_str, mem_type_str, 356 tag_check_str, atag_check_str, tag_op_str); 357 358 return test_name; 359 } 360 361 int main(int argc, char *argv[]) 362 { 363 int err, i; 364 int item = ARRAY_SIZE(sizes); 365 struct check_mmap_testcase test_cases[]= { 366 { 367 .check_type = CHECK_ANON_MEM, 368 .mem_type = USE_MMAP, 369 .mte_sync = MTE_SYNC_ERR, 370 .mapping = MAP_PRIVATE, 371 .tag_check = TAG_CHECK_OFF, 372 .atag_check = ATAG_CHECK_OFF, 373 .tag_op = TAG_OP_ALL, 374 .enable_tco = true, 375 }, 376 { 377 .check_type = CHECK_FILE_MEM, 378 .mem_type = USE_MPROTECT, 379 .mte_sync = MTE_SYNC_ERR, 380 .mapping = MAP_PRIVATE, 381 .tag_check = TAG_CHECK_OFF, 382 .atag_check = ATAG_CHECK_OFF, 383 .tag_op = TAG_OP_ALL, 384 .enable_tco = true, 385 }, 386 { 387 .check_type = CHECK_ANON_MEM, 388 .mem_type = USE_MMAP, 389 .mte_sync = MTE_NONE_ERR, 390 .mapping = MAP_PRIVATE, 391 .tag_check = TAG_CHECK_OFF, 392 .atag_check = ATAG_CHECK_OFF, 393 .tag_op = TAG_OP_ALL, 394 .enable_tco = false, 395 }, 396 { 397 .check_type = CHECK_FILE_MEM, 398 .mem_type = USE_MPROTECT, 399 .mte_sync = MTE_NONE_ERR, 400 .mapping = MAP_PRIVATE, 401 .tag_check = TAG_CHECK_OFF, 402 .atag_check = ATAG_CHECK_OFF, 403 .tag_op = TAG_OP_ALL, 404 .enable_tco = false, 405 }, 406 { 407 .check_type = CHECK_ANON_MEM, 408 .mem_type = USE_MMAP, 409 .mte_sync = MTE_SYNC_ERR, 410 .mapping = MAP_PRIVATE, 411 .tag_check = TAG_CHECK_ON, 412 .atag_check = ATAG_CHECK_OFF, 413 .tag_op = TAG_OP_ALL, 414 .enable_tco = false, 415 }, 416 { 417 .check_type = CHECK_ANON_MEM, 418 .mem_type = USE_MPROTECT, 419 .mte_sync = MTE_SYNC_ERR, 420 .mapping = MAP_PRIVATE, 421 .tag_check = TAG_CHECK_ON, 422 .atag_check = ATAG_CHECK_OFF, 423 .tag_op = TAG_OP_ALL, 424 .enable_tco = false, 425 }, 426 { 427 .check_type = CHECK_ANON_MEM, 428 .mem_type = USE_MMAP, 429 .mte_sync = MTE_SYNC_ERR, 430 .mapping = MAP_SHARED, 431 .tag_check = TAG_CHECK_ON, 432 .atag_check = ATAG_CHECK_OFF, 433 .tag_op = TAG_OP_ALL, 434 .enable_tco = false, 435 }, 436 { 437 .check_type = CHECK_ANON_MEM, 438 .mem_type = USE_MPROTECT, 439 .mte_sync = MTE_SYNC_ERR, 440 .mapping = MAP_SHARED, 441 .tag_check = TAG_CHECK_ON, 442 .atag_check = ATAG_CHECK_OFF, 443 .tag_op = TAG_OP_ALL, 444 .enable_tco = false, 445 }, 446 { 447 .check_type = CHECK_ANON_MEM, 448 .mem_type = USE_MMAP, 449 .mte_sync = MTE_ASYNC_ERR, 450 .mapping = MAP_PRIVATE, 451 .tag_check = TAG_CHECK_ON, 452 .atag_check = ATAG_CHECK_OFF, 453 .tag_op = TAG_OP_ALL, 454 .enable_tco = false, 455 }, 456 { 457 .check_type = CHECK_ANON_MEM, 458 .mem_type = USE_MPROTECT, 459 .mte_sync = MTE_ASYNC_ERR, 460 .mapping = MAP_PRIVATE, 461 .tag_check = TAG_CHECK_ON, 462 .atag_check = ATAG_CHECK_OFF, 463 .tag_op = TAG_OP_ALL, 464 .enable_tco = false, 465 }, 466 { 467 .check_type = CHECK_ANON_MEM, 468 .mem_type = USE_MMAP, 469 .mte_sync = MTE_ASYNC_ERR, 470 .mapping = MAP_SHARED, 471 .tag_check = TAG_CHECK_ON, 472 .atag_check = ATAG_CHECK_OFF, 473 .tag_op = TAG_OP_ALL, 474 .enable_tco = false, 475 }, 476 { 477 .check_type = CHECK_ANON_MEM, 478 .mem_type = USE_MPROTECT, 479 .mte_sync = MTE_ASYNC_ERR, 480 .mapping = MAP_SHARED, 481 .tag_check = TAG_CHECK_ON, 482 .atag_check = ATAG_CHECK_OFF, 483 .tag_op = TAG_OP_ALL, 484 .enable_tco = false, 485 }, 486 { 487 .check_type = CHECK_FILE_MEM, 488 .mem_type = USE_MMAP, 489 .mte_sync = MTE_SYNC_ERR, 490 .mapping = MAP_PRIVATE, 491 .tag_check = TAG_CHECK_ON, 492 .atag_check = ATAG_CHECK_OFF, 493 .tag_op = TAG_OP_ALL, 494 .enable_tco = false, 495 }, 496 { 497 .check_type = CHECK_FILE_MEM, 498 .mem_type = USE_MPROTECT, 499 .mte_sync = MTE_SYNC_ERR, 500 .mapping = MAP_PRIVATE, 501 .tag_check = TAG_CHECK_ON, 502 .atag_check = ATAG_CHECK_OFF, 503 .tag_op = TAG_OP_ALL, 504 .enable_tco = false, 505 }, 506 { 507 .check_type = CHECK_FILE_MEM, 508 .mem_type = USE_MMAP, 509 .mte_sync = MTE_SYNC_ERR, 510 .mapping = MAP_SHARED, 511 .tag_check = TAG_CHECK_ON, 512 .atag_check = ATAG_CHECK_OFF, 513 .tag_op = TAG_OP_ALL, 514 .enable_tco = false, 515 }, 516 { 517 .check_type = CHECK_FILE_MEM, 518 .mem_type = USE_MPROTECT, 519 .mte_sync = MTE_SYNC_ERR, 520 .mapping = MAP_SHARED, 521 .tag_check = TAG_CHECK_ON, 522 .atag_check = ATAG_CHECK_OFF, 523 .tag_op = TAG_OP_ALL, 524 .enable_tco = false, 525 }, 526 { 527 .check_type = CHECK_FILE_MEM, 528 .mem_type = USE_MMAP, 529 .mte_sync = MTE_ASYNC_ERR, 530 .mapping = MAP_PRIVATE, 531 .tag_check = TAG_CHECK_ON, 532 .atag_check = ATAG_CHECK_OFF, 533 .tag_op = TAG_OP_ALL, 534 .enable_tco = false, 535 }, 536 { 537 .check_type = CHECK_FILE_MEM, 538 .mem_type = USE_MPROTECT, 539 .mte_sync = MTE_ASYNC_ERR, 540 .mapping = MAP_PRIVATE, 541 .tag_check = TAG_CHECK_ON, 542 .atag_check = ATAG_CHECK_OFF, 543 .tag_op = TAG_OP_ALL, 544 .enable_tco = false, 545 }, 546 { 547 .check_type = CHECK_FILE_MEM, 548 .mem_type = USE_MMAP, 549 .mte_sync = MTE_ASYNC_ERR, 550 .mapping = MAP_SHARED, 551 .tag_check = TAG_CHECK_ON, 552 .atag_check = ATAG_CHECK_OFF, 553 .tag_op = TAG_OP_ALL, 554 .enable_tco = false, 555 }, 556 { 557 .check_type = CHECK_FILE_MEM, 558 .mem_type = USE_MPROTECT, 559 .mte_sync = MTE_ASYNC_ERR, 560 .mapping = MAP_SHARED, 561 .tag_check = TAG_CHECK_ON, 562 .atag_check = ATAG_CHECK_OFF, 563 .tag_op = TAG_OP_ALL, 564 .enable_tco = false, 565 }, 566 { 567 .check_type = CHECK_CLEAR_PROT_MTE, 568 .mem_type = USE_MMAP, 569 .mte_sync = MTE_SYNC_ERR, 570 .mapping = MAP_PRIVATE, 571 .tag_check = TAG_CHECK_ON, 572 .atag_check = ATAG_CHECK_OFF, 573 .tag_op = TAG_OP_ALL, 574 .enable_tco = false, 575 }, 576 { 577 .check_type = CHECK_CLEAR_PROT_MTE, 578 .mem_type = USE_MPROTECT, 579 .mte_sync = MTE_SYNC_ERR, 580 .mapping = MAP_PRIVATE, 581 .tag_check = TAG_CHECK_ON, 582 .atag_check = ATAG_CHECK_OFF, 583 .tag_op = TAG_OP_ALL, 584 .enable_tco = false, 585 }, 586 { 587 .check_type = CHECK_ANON_MEM, 588 .mem_type = USE_MMAP, 589 .mte_sync = MTE_SYNC_ERR, 590 .mapping = MAP_PRIVATE, 591 .tag_check = TAG_CHECK_ON, 592 .atag_check = ATAG_CHECK_ON, 593 .tag_op = TAG_OP_ALL, 594 .enable_tco = false, 595 }, 596 { 597 .check_type = CHECK_ANON_MEM, 598 .mem_type = USE_MPROTECT, 599 .mte_sync = MTE_SYNC_ERR, 600 .mapping = MAP_PRIVATE, 601 .tag_check = TAG_CHECK_ON, 602 .atag_check = ATAG_CHECK_ON, 603 .tag_op = TAG_OP_ALL, 604 .enable_tco = false, 605 }, 606 { 607 .check_type = CHECK_ANON_MEM, 608 .mem_type = USE_MMAP, 609 .mte_sync = MTE_SYNC_ERR, 610 .mapping = MAP_SHARED, 611 .tag_check = TAG_CHECK_ON, 612 .atag_check = ATAG_CHECK_ON, 613 .tag_op = TAG_OP_ALL, 614 .enable_tco = false, 615 }, 616 { 617 .check_type = CHECK_ANON_MEM, 618 .mem_type = USE_MPROTECT, 619 .mte_sync = MTE_SYNC_ERR, 620 .mapping = MAP_SHARED, 621 .tag_check = TAG_CHECK_ON, 622 .atag_check = ATAG_CHECK_ON, 623 .tag_op = TAG_OP_ALL, 624 .enable_tco = false, 625 }, 626 { 627 .check_type = CHECK_FILE_MEM, 628 .mem_type = USE_MMAP, 629 .mte_sync = MTE_SYNC_ERR, 630 .mapping = MAP_PRIVATE, 631 .tag_check = TAG_CHECK_ON, 632 .atag_check = ATAG_CHECK_ON, 633 .tag_op = TAG_OP_ALL, 634 .enable_tco = false, 635 }, 636 { 637 .check_type = CHECK_FILE_MEM, 638 .mem_type = USE_MPROTECT, 639 .mte_sync = MTE_SYNC_ERR, 640 .mapping = MAP_PRIVATE, 641 .tag_check = TAG_CHECK_ON, 642 .atag_check = ATAG_CHECK_ON, 643 .tag_op = TAG_OP_ALL, 644 .enable_tco = false, 645 }, 646 { 647 .check_type = CHECK_FILE_MEM, 648 .mem_type = USE_MMAP, 649 .mte_sync = MTE_SYNC_ERR, 650 .mapping = MAP_SHARED, 651 .tag_check = TAG_CHECK_ON, 652 .atag_check = ATAG_CHECK_ON, 653 .tag_op = TAG_OP_ALL, 654 .enable_tco = false, 655 }, 656 { 657 .check_type = CHECK_FILE_MEM, 658 .mem_type = USE_MPROTECT, 659 .mte_sync = MTE_SYNC_ERR, 660 .mapping = MAP_SHARED, 661 .tag_check = TAG_CHECK_ON, 662 .atag_check = ATAG_CHECK_ON, 663 .tag_op = TAG_OP_ALL, 664 .enable_tco = false, 665 }, 666 { 667 .check_type = CHECK_FILE_MEM, 668 .mem_type = USE_MMAP, 669 .mte_sync = MTE_ASYNC_ERR, 670 .mapping = MAP_PRIVATE, 671 .tag_check = TAG_CHECK_ON, 672 .atag_check = ATAG_CHECK_ON, 673 .tag_op = TAG_OP_ALL, 674 .enable_tco = false, 675 }, 676 { 677 .check_type = CHECK_ANON_MEM, 678 .mem_type = USE_MMAP, 679 .mte_sync = MTE_SYNC_ERR, 680 .mapping = MAP_PRIVATE, 681 .tag_check = TAG_CHECK_ON, 682 .atag_check = ATAG_CHECK_OFF, 683 .tag_op = TAG_OP_STONLY, 684 .enable_tco = false, 685 }, 686 { 687 .check_type = CHECK_ANON_MEM, 688 .mem_type = USE_MPROTECT, 689 .mte_sync = MTE_SYNC_ERR, 690 .mapping = MAP_PRIVATE, 691 .tag_check = TAG_CHECK_ON, 692 .atag_check = ATAG_CHECK_OFF, 693 .tag_op = TAG_OP_STONLY, 694 .enable_tco = false, 695 }, 696 { 697 .check_type = CHECK_ANON_MEM, 698 .mem_type = USE_MMAP, 699 .mte_sync = MTE_SYNC_ERR, 700 .mapping = MAP_SHARED, 701 .tag_check = TAG_CHECK_ON, 702 .atag_check = ATAG_CHECK_OFF, 703 .tag_op = TAG_OP_STONLY, 704 .enable_tco = false, 705 }, 706 { 707 .check_type = CHECK_ANON_MEM, 708 .mem_type = USE_MPROTECT, 709 .mte_sync = MTE_SYNC_ERR, 710 .mapping = MAP_SHARED, 711 .tag_check = TAG_CHECK_ON, 712 .atag_check = ATAG_CHECK_OFF, 713 .tag_op = TAG_OP_STONLY, 714 .enable_tco = false, 715 }, 716 { 717 .check_type = CHECK_ANON_MEM, 718 .mem_type = USE_MMAP, 719 .mte_sync = MTE_ASYNC_ERR, 720 .mapping = MAP_PRIVATE, 721 .tag_check = TAG_CHECK_ON, 722 .atag_check = ATAG_CHECK_OFF, 723 .tag_op = TAG_OP_STONLY, 724 .enable_tco = false, 725 }, 726 { 727 .check_type = CHECK_ANON_MEM, 728 .mem_type = USE_MPROTECT, 729 .mte_sync = MTE_ASYNC_ERR, 730 .mapping = MAP_PRIVATE, 731 .tag_check = TAG_CHECK_ON, 732 .atag_check = ATAG_CHECK_OFF, 733 .tag_op = TAG_OP_STONLY, 734 .enable_tco = false, 735 }, 736 { 737 .check_type = CHECK_ANON_MEM, 738 .mem_type = USE_MMAP, 739 .mte_sync = MTE_ASYNC_ERR, 740 .mapping = MAP_SHARED, 741 .tag_check = TAG_CHECK_ON, 742 .atag_check = ATAG_CHECK_OFF, 743 .tag_op = TAG_OP_STONLY, 744 .enable_tco = false, 745 }, 746 { 747 .check_type = CHECK_ANON_MEM, 748 .mem_type = USE_MPROTECT, 749 .mte_sync = MTE_ASYNC_ERR, 750 .mapping = MAP_SHARED, 751 .tag_check = TAG_CHECK_ON, 752 .atag_check = ATAG_CHECK_OFF, 753 .tag_op = TAG_OP_STONLY, 754 .enable_tco = false, 755 }, 756 { 757 .check_type = CHECK_FILE_MEM, 758 .mem_type = USE_MMAP, 759 .mte_sync = MTE_SYNC_ERR, 760 .mapping = MAP_PRIVATE, 761 .tag_check = TAG_CHECK_ON, 762 .atag_check = ATAG_CHECK_OFF, 763 .tag_op = TAG_OP_STONLY, 764 .enable_tco = false, 765 }, 766 { 767 .check_type = CHECK_FILE_MEM, 768 .mem_type = USE_MPROTECT, 769 .mte_sync = MTE_SYNC_ERR, 770 .mapping = MAP_PRIVATE, 771 .tag_check = TAG_CHECK_ON, 772 .atag_check = ATAG_CHECK_OFF, 773 .tag_op = TAG_OP_STONLY, 774 .enable_tco = false, 775 }, 776 { 777 .check_type = CHECK_FILE_MEM, 778 .mem_type = USE_MMAP, 779 .mte_sync = MTE_SYNC_ERR, 780 .mapping = MAP_SHARED, 781 .tag_check = TAG_CHECK_ON, 782 .atag_check = ATAG_CHECK_OFF, 783 .tag_op = TAG_OP_STONLY, 784 .enable_tco = false, 785 }, 786 { 787 .check_type = CHECK_FILE_MEM, 788 .mem_type = USE_MPROTECT, 789 .mte_sync = MTE_SYNC_ERR, 790 .mapping = MAP_SHARED, 791 .tag_check = TAG_CHECK_ON, 792 .atag_check = ATAG_CHECK_OFF, 793 .tag_op = TAG_OP_STONLY, 794 .enable_tco = false, 795 }, 796 { 797 .check_type = CHECK_FILE_MEM, 798 .mem_type = USE_MMAP, 799 .mte_sync = MTE_ASYNC_ERR, 800 .mapping = MAP_PRIVATE, 801 .tag_check = TAG_CHECK_ON, 802 .atag_check = ATAG_CHECK_OFF, 803 .tag_op = TAG_OP_STONLY, 804 .enable_tco = false, 805 }, 806 { 807 .check_type = CHECK_FILE_MEM, 808 .mem_type = USE_MPROTECT, 809 .mte_sync = MTE_ASYNC_ERR, 810 .mapping = MAP_PRIVATE, 811 .tag_check = TAG_CHECK_ON, 812 .atag_check = ATAG_CHECK_OFF, 813 .tag_op = TAG_OP_STONLY, 814 .enable_tco = false, 815 }, 816 { 817 .check_type = CHECK_FILE_MEM, 818 .mem_type = USE_MMAP, 819 .mte_sync = MTE_ASYNC_ERR, 820 .mapping = MAP_SHARED, 821 .tag_check = TAG_CHECK_ON, 822 .atag_check = ATAG_CHECK_OFF, 823 .tag_op = TAG_OP_STONLY, 824 .enable_tco = false, 825 }, 826 { 827 .check_type = CHECK_FILE_MEM, 828 .mem_type = USE_MPROTECT, 829 .mte_sync = MTE_ASYNC_ERR, 830 .mapping = MAP_SHARED, 831 .tag_check = TAG_CHECK_ON, 832 .atag_check = ATAG_CHECK_OFF, 833 .tag_op = TAG_OP_STONLY, 834 .enable_tco = false, 835 }, 836 { 837 .check_type = CHECK_ANON_MEM, 838 .mem_type = USE_MMAP, 839 .mte_sync = MTE_SYNC_ERR, 840 .mapping = MAP_PRIVATE, 841 .tag_check = TAG_CHECK_ON, 842 .atag_check = ATAG_CHECK_ON, 843 .tag_op = TAG_OP_STONLY, 844 .enable_tco = false, 845 }, 846 { 847 .check_type = CHECK_ANON_MEM, 848 .mem_type = USE_MPROTECT, 849 .mte_sync = MTE_SYNC_ERR, 850 .mapping = MAP_PRIVATE, 851 .tag_check = TAG_CHECK_ON, 852 .atag_check = ATAG_CHECK_ON, 853 .tag_op = TAG_OP_STONLY, 854 .enable_tco = false, 855 }, 856 { 857 .check_type = CHECK_ANON_MEM, 858 .mem_type = USE_MMAP, 859 .mte_sync = MTE_SYNC_ERR, 860 .mapping = MAP_SHARED, 861 .tag_check = TAG_CHECK_ON, 862 .atag_check = ATAG_CHECK_ON, 863 .tag_op = TAG_OP_STONLY, 864 .enable_tco = false, 865 }, 866 { 867 .check_type = CHECK_ANON_MEM, 868 .mem_type = USE_MPROTECT, 869 .mte_sync = MTE_SYNC_ERR, 870 .mapping = MAP_SHARED, 871 .tag_check = TAG_CHECK_ON, 872 .atag_check = ATAG_CHECK_ON, 873 .tag_op = TAG_OP_STONLY, 874 .enable_tco = false, 875 }, 876 { 877 .check_type = CHECK_FILE_MEM, 878 .mem_type = USE_MMAP, 879 .mte_sync = MTE_SYNC_ERR, 880 .mapping = MAP_PRIVATE, 881 .tag_check = TAG_CHECK_ON, 882 .atag_check = ATAG_CHECK_ON, 883 .tag_op = TAG_OP_STONLY, 884 .enable_tco = false, 885 }, 886 { 887 .check_type = CHECK_FILE_MEM, 888 .mem_type = USE_MPROTECT, 889 .mte_sync = MTE_SYNC_ERR, 890 .mapping = MAP_PRIVATE, 891 .tag_check = TAG_CHECK_ON, 892 .atag_check = ATAG_CHECK_ON, 893 .tag_op = TAG_OP_STONLY, 894 .enable_tco = false, 895 }, 896 { 897 .check_type = CHECK_FILE_MEM, 898 .mem_type = USE_MMAP, 899 .mte_sync = MTE_SYNC_ERR, 900 .mapping = MAP_SHARED, 901 .tag_check = TAG_CHECK_ON, 902 .atag_check = ATAG_CHECK_ON, 903 .tag_op = TAG_OP_STONLY, 904 .enable_tco = false, 905 }, 906 { 907 .check_type = CHECK_FILE_MEM, 908 .mem_type = USE_MPROTECT, 909 .mte_sync = MTE_SYNC_ERR, 910 .mapping = MAP_SHARED, 911 .tag_check = TAG_CHECK_ON, 912 .atag_check = ATAG_CHECK_ON, 913 .tag_op = TAG_OP_STONLY, 914 .enable_tco = false, 915 }, 916 { 917 .check_type = CHECK_FILE_MEM, 918 .mem_type = USE_MMAP, 919 .mte_sync = MTE_ASYNC_ERR, 920 .mapping = MAP_PRIVATE, 921 .tag_check = TAG_CHECK_ON, 922 .atag_check = ATAG_CHECK_ON, 923 .tag_op = TAG_OP_STONLY, 924 .enable_tco = false, 925 }, 926 { 927 .check_type = CHECK_CLEAR_PROT_MTE, 928 .mem_type = USE_MMAP, 929 .mte_sync = MTE_SYNC_ERR, 930 .mapping = MAP_PRIVATE, 931 .tag_check = TAG_CHECK_ON, 932 .atag_check = ATAG_CHECK_ON, 933 .tag_op = TAG_OP_ALL, 934 .enable_tco = false, 935 }, 936 { 937 .check_type = CHECK_CLEAR_PROT_MTE, 938 .mem_type = USE_MPROTECT, 939 .mte_sync = MTE_SYNC_ERR, 940 .mapping = MAP_PRIVATE, 941 .tag_check = TAG_CHECK_ON, 942 .atag_check = ATAG_CHECK_ON, 943 .tag_op = TAG_OP_ALL, 944 .enable_tco = false, 945 }, 946 }; 947 948 err = mte_default_setup(); 949 if (err) 950 return err; 951 page_size = getpagesize(); 952 if (!page_size) { 953 ksft_print_msg("ERR: Unable to get page size\n"); 954 return KSFT_FAIL; 955 } 956 sizes[item - 3] = page_size - 1; 957 sizes[item - 2] = page_size; 958 sizes[item - 1] = page_size + 1; 959 960 /* Set test plan */ 961 ksft_set_plan(ARRAY_SIZE(test_cases)); 962 963 for (i = 0 ; i < ARRAY_SIZE(test_cases); i++) { 964 /* Register signal handlers */ 965 mte_register_signal(SIGBUS, mte_default_handler, 966 test_cases[i].atag_check == ATAG_CHECK_ON); 967 mte_register_signal(SIGSEGV, mte_default_handler, 968 test_cases[i].atag_check == ATAG_CHECK_ON); 969 970 if (test_cases[i].enable_tco) 971 mte_enable_pstate_tco(); 972 else 973 mte_disable_pstate_tco(); 974 975 switch (test_cases[i].check_type) { 976 case CHECK_ANON_MEM: 977 evaluate_test(check_anonymous_memory_mapping(test_cases[i].mem_type, 978 test_cases[i].mte_sync, 979 test_cases[i].mapping, 980 test_cases[i].tag_check, 981 test_cases[i].atag_check, 982 test_cases[i].tag_op), 983 format_test_name(&test_cases[i])); 984 break; 985 case CHECK_FILE_MEM: 986 evaluate_test(check_file_memory_mapping(test_cases[i].mem_type, 987 test_cases[i].mte_sync, 988 test_cases[i].mapping, 989 test_cases[i].tag_check, 990 test_cases[i].atag_check, 991 test_cases[i].tag_op), 992 format_test_name(&test_cases[i])); 993 break; 994 case CHECK_CLEAR_PROT_MTE: 995 evaluate_test(check_clear_prot_mte_flag(test_cases[i].mem_type, 996 test_cases[i].mte_sync, 997 test_cases[i].mapping, 998 test_cases[i].atag_check), 999 format_test_name(&test_cases[i])); 1000 break; 1001 default: 1002 exit(KSFT_FAIL); 1003 } 1004 } 1005 1006 mte_restore_setup(); 1007 ksft_print_cnts(); 1008 return ksft_get_fail_cnt() == 0 ? KSFT_PASS : KSFT_FAIL; 1009 } 1010