1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2018-2019, Linaro Limited 4 */ 5 6 #include <assert.h> 7 #include <crypto/crypto.h> 8 #include <kernel/handle.h> 9 #include <kernel/huk_subkey.h> 10 #include <kernel/misc.h> 11 #include <kernel/msg_param.h> 12 #include <kernel/pseudo_ta.h> 13 #include <kernel/user_ta.h> 14 #include <kernel/user_ta_store.h> 15 #include <ldelf.h> 16 #include <mm/file.h> 17 #include <mm/fobj.h> 18 #include <mm/tee_mmu.h> 19 #include <pta_system.h> 20 #include <string.h> 21 #include <tee_api_defines_extensions.h> 22 #include <tee_api_defines.h> 23 #include <util.h> 24 #include <kernel/tpm.h> 25 26 struct bin_handle { 27 const struct user_ta_store_ops *op; 28 struct user_ta_store_handle *h; 29 struct file *f; 30 size_t offs_bytes; 31 size_t size_bytes; 32 }; 33 34 struct system_ctx { 35 struct handle_db db; 36 const struct user_ta_store_ops *store_op; 37 }; 38 39 static unsigned int system_pnum; 40 41 static TEE_Result system_rng_reseed(struct tee_ta_session *s __unused, 42 uint32_t param_types, 43 TEE_Param params[TEE_NUM_PARAMS]) 44 { 45 size_t entropy_sz; 46 uint8_t *entropy_input; 47 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 48 TEE_PARAM_TYPE_NONE, 49 TEE_PARAM_TYPE_NONE, 50 TEE_PARAM_TYPE_NONE); 51 52 if (exp_pt != param_types) 53 return TEE_ERROR_BAD_PARAMETERS; 54 entropy_input = params[0].memref.buffer; 55 entropy_sz = params[0].memref.size; 56 57 if (!entropy_sz || !entropy_input) 58 return TEE_ERROR_BAD_PARAMETERS; 59 60 crypto_rng_add_event(CRYPTO_RNG_SRC_NONSECURE, &system_pnum, 61 entropy_input, entropy_sz); 62 return TEE_SUCCESS; 63 } 64 65 static TEE_Result system_derive_ta_unique_key(struct tee_ta_session *s, 66 uint32_t param_types, 67 TEE_Param params[TEE_NUM_PARAMS]) 68 { 69 size_t data_len = sizeof(TEE_UUID); 70 TEE_Result res = TEE_ERROR_GENERIC; 71 uint8_t *data = NULL; 72 uint32_t access_flags = 0; 73 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 74 TEE_PARAM_TYPE_MEMREF_OUTPUT, 75 TEE_PARAM_TYPE_NONE, 76 TEE_PARAM_TYPE_NONE); 77 struct user_ta_ctx *utc = NULL; 78 79 if (exp_pt != param_types) 80 return TEE_ERROR_BAD_PARAMETERS; 81 82 if (params[0].memref.size > TA_DERIVED_EXTRA_DATA_MAX_SIZE || 83 params[1].memref.size < TA_DERIVED_KEY_MIN_SIZE || 84 params[1].memref.size > TA_DERIVED_KEY_MAX_SIZE) 85 return TEE_ERROR_BAD_PARAMETERS; 86 87 utc = to_user_ta_ctx(s->ctx); 88 89 /* 90 * The derived key shall not end up in non-secure memory by 91 * mistake. 92 * 93 * Note that we're allowing shared memory as long as it's 94 * secure. This is needed because a TA always uses shared memory 95 * when communicating with another TA. 96 */ 97 access_flags = TEE_MEMORY_ACCESS_WRITE | TEE_MEMORY_ACCESS_ANY_OWNER | 98 TEE_MEMORY_ACCESS_SECURE; 99 res = tee_mmu_check_access_rights(&utc->uctx, access_flags, 100 (uaddr_t)params[1].memref.buffer, 101 params[1].memref.size); 102 if (res != TEE_SUCCESS) 103 return TEE_ERROR_SECURITY; 104 105 /* Take extra data into account. */ 106 if (ADD_OVERFLOW(data_len, params[0].memref.size, &data_len)) 107 return TEE_ERROR_SECURITY; 108 109 data = calloc(data_len, 1); 110 if (!data) 111 return TEE_ERROR_OUT_OF_MEMORY; 112 113 memcpy(data, &s->ctx->uuid, sizeof(TEE_UUID)); 114 115 /* Append the user provided data */ 116 memcpy(data + sizeof(TEE_UUID), params[0].memref.buffer, 117 params[0].memref.size); 118 119 res = huk_subkey_derive(HUK_SUBKEY_UNIQUE_TA, data, data_len, 120 params[1].memref.buffer, 121 params[1].memref.size); 122 free(data); 123 124 return res; 125 } 126 127 static TEE_Result system_map_zi(struct tee_ta_session *s, uint32_t param_types, 128 TEE_Param params[TEE_NUM_PARAMS]) 129 { 130 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 131 TEE_PARAM_TYPE_VALUE_INOUT, 132 TEE_PARAM_TYPE_VALUE_INPUT, 133 TEE_PARAM_TYPE_NONE); 134 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 135 uint32_t prot = TEE_MATTR_URW | TEE_MATTR_PRW; 136 TEE_Result res = TEE_ERROR_GENERIC; 137 struct mobj *mobj = NULL; 138 uint32_t pad_begin = 0; 139 uint32_t vm_flags = 0; 140 struct fobj *f = NULL; 141 uint32_t pad_end = 0; 142 size_t num_bytes = 0; 143 vaddr_t va = 0; 144 145 if (exp_pt != param_types) 146 return TEE_ERROR_BAD_PARAMETERS; 147 if (params[0].value.b & ~PTA_SYSTEM_MAP_FLAG_SHAREABLE) 148 return TEE_ERROR_BAD_PARAMETERS; 149 150 if (params[0].value.b & PTA_SYSTEM_MAP_FLAG_SHAREABLE) 151 vm_flags |= VM_FLAG_SHAREABLE; 152 153 num_bytes = params[0].value.a; 154 va = reg_pair_to_64(params[1].value.a, params[1].value.b); 155 pad_begin = params[2].value.a; 156 pad_end = params[2].value.b; 157 158 f = fobj_ta_mem_alloc(ROUNDUP_DIV(num_bytes, SMALL_PAGE_SIZE)); 159 if (!f) 160 return TEE_ERROR_OUT_OF_MEMORY; 161 mobj = mobj_with_fobj_alloc(f, NULL); 162 fobj_put(f); 163 if (!mobj) 164 return TEE_ERROR_OUT_OF_MEMORY; 165 res = vm_map_pad(&utc->uctx, &va, num_bytes, prot, vm_flags, 166 mobj, 0, pad_begin, pad_end); 167 mobj_put(mobj); 168 if (!res) 169 reg_pair_from_64(va, ¶ms[1].value.a, ¶ms[1].value.b); 170 171 return res; 172 } 173 174 static TEE_Result system_unmap(struct tee_ta_session *s, uint32_t param_types, 175 TEE_Param params[TEE_NUM_PARAMS]) 176 { 177 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 178 TEE_PARAM_TYPE_VALUE_INPUT, 179 TEE_PARAM_TYPE_NONE, 180 TEE_PARAM_TYPE_NONE); 181 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 182 TEE_Result res = TEE_SUCCESS; 183 uint32_t vm_flags = 0; 184 vaddr_t va = 0; 185 size_t sz = 0; 186 187 if (exp_pt != param_types) 188 return TEE_ERROR_BAD_PARAMETERS; 189 190 if (params[0].value.b) 191 return TEE_ERROR_BAD_PARAMETERS; 192 193 va = reg_pair_to_64(params[1].value.a, params[1].value.b); 194 sz = ROUNDUP(params[0].value.a, SMALL_PAGE_SIZE); 195 196 res = vm_get_flags(&utc->uctx, va, sz, &vm_flags); 197 if (res) 198 return res; 199 if (vm_flags & VM_FLAG_PERMANENT) 200 return TEE_ERROR_ACCESS_DENIED; 201 202 return vm_unmap(&to_user_ta_ctx(s->ctx)->uctx, va, sz); 203 } 204 205 static void ta_bin_close(void *ptr) 206 { 207 struct bin_handle *binh = ptr; 208 209 if (binh) { 210 if (binh->op && binh->h) 211 binh->op->close(binh->h); 212 file_put(binh->f); 213 } 214 free(binh); 215 } 216 217 static TEE_Result system_open_ta_binary(struct system_ctx *ctx, 218 uint32_t param_types, 219 TEE_Param params[TEE_NUM_PARAMS]) 220 { 221 TEE_Result res = TEE_SUCCESS; 222 struct bin_handle *binh = NULL; 223 int h = 0; 224 TEE_UUID *uuid = NULL; 225 uint8_t tag[FILE_TAG_SIZE] = { 0 }; 226 unsigned int tag_len = sizeof(tag); 227 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 228 TEE_PARAM_TYPE_VALUE_OUTPUT, 229 TEE_PARAM_TYPE_NONE, 230 TEE_PARAM_TYPE_NONE); 231 232 if (exp_pt != param_types) 233 return TEE_ERROR_BAD_PARAMETERS; 234 if (params[0].memref.size != sizeof(*uuid)) 235 return TEE_ERROR_BAD_PARAMETERS; 236 237 uuid = params[0].memref.buffer; 238 239 binh = calloc(1, sizeof(*binh)); 240 if (!binh) 241 return TEE_ERROR_OUT_OF_MEMORY; 242 243 SCATTERED_ARRAY_FOREACH(binh->op, ta_stores, struct user_ta_store_ops) { 244 DMSG("Lookup user TA ELF %pUl (%s)", 245 (void *)uuid, binh->op->description); 246 247 res = binh->op->open(uuid, &binh->h); 248 DMSG("res=0x%x", res); 249 if (res != TEE_ERROR_ITEM_NOT_FOUND && 250 res != TEE_ERROR_STORAGE_NOT_AVAILABLE) 251 break; 252 } 253 if (res) 254 goto err; 255 256 res = binh->op->get_size(binh->h, &binh->size_bytes); 257 if (res) 258 goto err; 259 res = binh->op->get_tag(binh->h, tag, &tag_len); 260 if (res) 261 goto err; 262 binh->f = file_get_by_tag(tag, tag_len); 263 if (!binh->f) 264 goto err_oom; 265 266 h = handle_get(&ctx->db, binh); 267 if (h < 0) 268 goto err_oom; 269 params[0].value.a = h; 270 271 return TEE_SUCCESS; 272 err_oom: 273 res = TEE_ERROR_OUT_OF_MEMORY; 274 err: 275 ta_bin_close(binh); 276 return res; 277 } 278 279 static TEE_Result system_close_ta_binary(struct system_ctx *ctx, 280 uint32_t param_types, 281 TEE_Param params[TEE_NUM_PARAMS]) 282 { 283 TEE_Result res = TEE_SUCCESS; 284 struct bin_handle *binh = NULL; 285 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 286 TEE_PARAM_TYPE_NONE, 287 TEE_PARAM_TYPE_NONE, 288 TEE_PARAM_TYPE_NONE); 289 290 if (exp_pt != param_types) 291 return TEE_ERROR_BAD_PARAMETERS; 292 293 if (params[0].value.b) 294 return TEE_ERROR_BAD_PARAMETERS; 295 296 binh = handle_put(&ctx->db, params[0].value.a); 297 if (!binh) 298 return TEE_ERROR_BAD_PARAMETERS; 299 300 if (binh->offs_bytes < binh->size_bytes) 301 res = binh->op->read(binh->h, NULL, 302 binh->size_bytes - binh->offs_bytes); 303 304 ta_bin_close(binh); 305 return res; 306 } 307 308 static TEE_Result binh_copy_to(struct bin_handle *binh, vaddr_t va, 309 size_t offs_bytes, size_t num_bytes) 310 { 311 TEE_Result res = TEE_SUCCESS; 312 size_t next_offs = 0; 313 314 if (offs_bytes < binh->offs_bytes) 315 return TEE_ERROR_BAD_STATE; 316 317 if (ADD_OVERFLOW(offs_bytes, num_bytes, &next_offs)) 318 return TEE_ERROR_BAD_PARAMETERS; 319 320 if (offs_bytes > binh->offs_bytes) { 321 res = binh->op->read(binh->h, NULL, 322 offs_bytes - binh->offs_bytes); 323 if (res) 324 return res; 325 binh->offs_bytes = offs_bytes; 326 } 327 328 if (next_offs > binh->size_bytes) { 329 size_t rb = binh->size_bytes - binh->offs_bytes; 330 331 res = binh->op->read(binh->h, (void *)va, rb); 332 if (res) 333 return res; 334 memset((uint8_t *)va + rb, 0, num_bytes - rb); 335 binh->offs_bytes = binh->size_bytes; 336 } else { 337 res = binh->op->read(binh->h, (void *)va, num_bytes); 338 if (res) 339 return res; 340 binh->offs_bytes = next_offs; 341 } 342 343 return TEE_SUCCESS; 344 } 345 346 static TEE_Result system_map_ta_binary(struct system_ctx *ctx, 347 struct tee_ta_session *s, 348 uint32_t param_types, 349 TEE_Param params[TEE_NUM_PARAMS]) 350 { 351 const uint32_t accept_flags = PTA_SYSTEM_MAP_FLAG_SHAREABLE | 352 PTA_SYSTEM_MAP_FLAG_WRITEABLE | 353 PTA_SYSTEM_MAP_FLAG_EXECUTABLE; 354 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 355 TEE_PARAM_TYPE_VALUE_INPUT, 356 TEE_PARAM_TYPE_VALUE_INOUT, 357 TEE_PARAM_TYPE_VALUE_INPUT); 358 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 359 struct bin_handle *binh = NULL; 360 uint32_t num_rounded_bytes = 0; 361 TEE_Result res = TEE_SUCCESS; 362 struct file_slice *fs = NULL; 363 bool file_is_locked = false; 364 struct mobj *mobj = NULL; 365 uint32_t offs_bytes = 0; 366 uint32_t offs_pages = 0; 367 uint32_t num_bytes = 0; 368 uint32_t pad_begin = 0; 369 uint32_t pad_end = 0; 370 size_t num_pages = 0; 371 uint32_t flags = 0; 372 uint32_t prot = 0; 373 vaddr_t va = 0; 374 375 if (exp_pt != param_types) 376 return TEE_ERROR_BAD_PARAMETERS; 377 378 binh = handle_lookup(&ctx->db, params[0].value.a); 379 if (!binh) 380 return TEE_ERROR_BAD_PARAMETERS; 381 flags = params[0].value.b; 382 offs_bytes = params[1].value.a; 383 num_bytes = params[1].value.b; 384 va = reg_pair_to_64(params[2].value.a, params[2].value.b); 385 pad_begin = params[3].value.a; 386 pad_end = params[3].value.b; 387 388 if ((flags & accept_flags) != flags) 389 return TEE_ERROR_BAD_PARAMETERS; 390 391 if ((flags & PTA_SYSTEM_MAP_FLAG_SHAREABLE) && 392 (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) 393 return TEE_ERROR_BAD_PARAMETERS; 394 395 if ((flags & PTA_SYSTEM_MAP_FLAG_EXECUTABLE) && 396 (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) 397 return TEE_ERROR_BAD_PARAMETERS; 398 399 if (offs_bytes & SMALL_PAGE_MASK) 400 return TEE_ERROR_BAD_PARAMETERS; 401 402 prot = TEE_MATTR_UR | TEE_MATTR_PR; 403 if (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE) 404 prot |= TEE_MATTR_UW | TEE_MATTR_PW; 405 if (flags & PTA_SYSTEM_MAP_FLAG_EXECUTABLE) 406 prot |= TEE_MATTR_UX; 407 408 offs_pages = offs_bytes >> SMALL_PAGE_SHIFT; 409 if (ROUNDUP_OVERFLOW(num_bytes, SMALL_PAGE_SIZE, &num_rounded_bytes)) 410 return TEE_ERROR_BAD_PARAMETERS; 411 num_pages = num_rounded_bytes / SMALL_PAGE_SIZE; 412 413 if (!file_trylock(binh->f)) { 414 /* 415 * Before we can block on the file lock we must make all 416 * our page tables available for reclaiming in order to 417 * avoid a dead-lock with the other thread (which already 418 * is holding the file lock) mapping lots of memory below. 419 */ 420 tee_mmu_set_ctx(NULL); 421 file_lock(binh->f); 422 tee_mmu_set_ctx(s->ctx); 423 } 424 file_is_locked = true; 425 fs = file_find_slice(binh->f, offs_pages); 426 if (fs) { 427 /* If there's registered slice it has to match */ 428 if (fs->page_offset != offs_pages || 429 num_pages > fs->fobj->num_pages) { 430 res = TEE_ERROR_BAD_PARAMETERS; 431 goto err; 432 } 433 434 /* If there's a slice we must be mapping shareable */ 435 if (!(flags & PTA_SYSTEM_MAP_FLAG_SHAREABLE)) { 436 res = TEE_ERROR_BAD_PARAMETERS; 437 goto err; 438 } 439 440 mobj = mobj_with_fobj_alloc(fs->fobj, binh->f); 441 if (!mobj) { 442 res = TEE_ERROR_OUT_OF_MEMORY; 443 goto err; 444 } 445 res = vm_map_pad(&utc->uctx, &va, num_rounded_bytes, 446 prot, VM_FLAG_READONLY, 447 mobj, 0, pad_begin, pad_end); 448 mobj_put(mobj); 449 if (res) 450 goto err; 451 } else { 452 struct fobj *f = fobj_ta_mem_alloc(num_pages); 453 struct file *file = NULL; 454 uint32_t vm_flags = 0; 455 456 if (!f) { 457 res = TEE_ERROR_OUT_OF_MEMORY; 458 goto err; 459 } 460 if (!(flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) { 461 file = binh->f; 462 vm_flags |= VM_FLAG_READONLY; 463 } 464 465 mobj = mobj_with_fobj_alloc(f, file); 466 fobj_put(f); 467 if (!mobj) { 468 res = TEE_ERROR_OUT_OF_MEMORY; 469 goto err; 470 } 471 res = vm_map_pad(&utc->uctx, &va, num_rounded_bytes, 472 TEE_MATTR_PRW, vm_flags, mobj, 0, 473 pad_begin, pad_end); 474 mobj_put(mobj); 475 if (res) 476 goto err; 477 res = binh_copy_to(binh, va, offs_bytes, num_bytes); 478 if (res) 479 goto err_unmap_va; 480 res = vm_set_prot(&utc->uctx, va, num_rounded_bytes, 481 prot); 482 if (res) 483 goto err_unmap_va; 484 485 /* 486 * The context currently is active set it again to update 487 * the mapping. 488 */ 489 tee_mmu_set_ctx(s->ctx); 490 491 if (!(flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) { 492 res = file_add_slice(binh->f, f, offs_pages); 493 if (res) 494 goto err_unmap_va; 495 } 496 } 497 498 file_unlock(binh->f); 499 500 reg_pair_from_64(va, ¶ms[2].value.a, ¶ms[2].value.b); 501 return TEE_SUCCESS; 502 503 err_unmap_va: 504 if (vm_unmap(&utc->uctx, va, num_rounded_bytes)) 505 panic(); 506 507 /* 508 * The context currently is active set it again to update 509 * the mapping. 510 */ 511 tee_mmu_set_ctx(s->ctx); 512 513 err: 514 if (file_is_locked) 515 file_unlock(binh->f); 516 517 return res; 518 } 519 520 static TEE_Result system_copy_from_ta_binary(struct system_ctx *ctx, 521 uint32_t param_types, 522 TEE_Param params[TEE_NUM_PARAMS]) 523 { 524 struct bin_handle *binh = NULL; 525 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 526 TEE_PARAM_TYPE_MEMREF_OUTPUT, 527 TEE_PARAM_TYPE_NONE, 528 TEE_PARAM_TYPE_NONE); 529 530 if (exp_pt != param_types) 531 return TEE_ERROR_BAD_PARAMETERS; 532 533 binh = handle_lookup(&ctx->db, params[0].value.a); 534 if (!binh) 535 return TEE_ERROR_BAD_PARAMETERS; 536 537 return binh_copy_to(binh, (vaddr_t)params[1].memref.buffer, 538 params[0].value.b, params[1].memref.size); 539 } 540 541 static TEE_Result system_set_prot(struct tee_ta_session *s, 542 uint32_t param_types, 543 TEE_Param params[TEE_NUM_PARAMS]) 544 { 545 const uint32_t accept_flags = PTA_SYSTEM_MAP_FLAG_WRITEABLE | 546 PTA_SYSTEM_MAP_FLAG_EXECUTABLE; 547 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 548 TEE_PARAM_TYPE_VALUE_INPUT, 549 TEE_PARAM_TYPE_NONE, 550 TEE_PARAM_TYPE_NONE); 551 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 552 uint32_t prot = TEE_MATTR_UR | TEE_MATTR_PR; 553 TEE_Result res = TEE_SUCCESS; 554 uint32_t vm_flags = 0; 555 uint32_t flags = 0; 556 vaddr_t va = 0; 557 size_t sz = 0; 558 559 if (exp_pt != param_types) 560 return TEE_ERROR_BAD_PARAMETERS; 561 562 flags = params[0].value.b; 563 564 if ((flags & accept_flags) != flags) 565 return TEE_ERROR_BAD_PARAMETERS; 566 if (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE) 567 prot |= TEE_MATTR_UW | TEE_MATTR_PW; 568 if (flags & PTA_SYSTEM_MAP_FLAG_EXECUTABLE) 569 prot |= TEE_MATTR_UX; 570 571 va = reg_pair_to_64(params[1].value.a, params[1].value.b); 572 sz = ROUNDUP(params[0].value.a, SMALL_PAGE_SIZE); 573 574 res = vm_get_flags(&utc->uctx, va, sz, &vm_flags); 575 if (res) 576 return res; 577 if (vm_flags & VM_FLAG_PERMANENT) 578 return TEE_ERROR_ACCESS_DENIED; 579 580 /* 581 * If the segment is a mapping of a part of a file (vm_flags & 582 * VM_FLAG_READONLY) it cannot be made writeable as all mapped 583 * files are mapped read-only. 584 */ 585 if ((vm_flags & VM_FLAG_READONLY) && 586 (prot & (TEE_MATTR_UW | TEE_MATTR_PW))) 587 return TEE_ERROR_ACCESS_DENIED; 588 589 return vm_set_prot(&utc->uctx, va, sz, prot); 590 } 591 592 static TEE_Result system_remap(struct tee_ta_session *s, uint32_t param_types, 593 TEE_Param params[TEE_NUM_PARAMS]) 594 { 595 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 596 TEE_PARAM_TYPE_VALUE_INPUT, 597 TEE_PARAM_TYPE_VALUE_INOUT, 598 TEE_PARAM_TYPE_VALUE_INPUT); 599 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 600 TEE_Result res = TEE_SUCCESS; 601 uint32_t num_bytes = 0; 602 uint32_t pad_begin = 0; 603 uint32_t vm_flags = 0; 604 uint32_t pad_end = 0; 605 vaddr_t old_va = 0; 606 vaddr_t new_va = 0; 607 608 if (exp_pt != param_types) 609 return TEE_ERROR_BAD_PARAMETERS; 610 611 num_bytes = params[0].value.a; 612 old_va = reg_pair_to_64(params[1].value.a, params[1].value.b); 613 new_va = reg_pair_to_64(params[2].value.a, params[2].value.b); 614 pad_begin = params[3].value.a; 615 pad_end = params[3].value.b; 616 617 res = vm_get_flags(&utc->uctx, old_va, num_bytes, &vm_flags); 618 if (res) 619 return res; 620 if (vm_flags & VM_FLAG_PERMANENT) 621 return TEE_ERROR_ACCESS_DENIED; 622 623 res = vm_remap(&utc->uctx, &new_va, old_va, num_bytes, pad_begin, 624 pad_end); 625 if (!res) 626 reg_pair_from_64(new_va, ¶ms[2].value.a, 627 ¶ms[2].value.b); 628 629 return res; 630 } 631 632 /* ldelf has the same architecture/register width as the kernel */ 633 #ifdef ARM32 634 static const bool is_arm32 = true; 635 #else 636 static const bool is_arm32; 637 #endif 638 639 static TEE_Result call_ldelf_dlopen(struct user_ta_ctx *utc, TEE_UUID *uuid, 640 uint32_t flags) 641 { 642 uaddr_t usr_stack = utc->ldelf_stack_ptr; 643 TEE_Result res = TEE_ERROR_GENERIC; 644 struct dl_entry_arg *arg = NULL; 645 uint32_t panic_code = 0; 646 uint32_t panicked = 0; 647 648 assert(uuid); 649 650 usr_stack -= ROUNDUP(sizeof(*arg), STACK_ALIGNMENT); 651 arg = (struct dl_entry_arg *)usr_stack; 652 653 res = tee_mmu_check_access_rights(&utc->uctx, 654 TEE_MEMORY_ACCESS_READ | 655 TEE_MEMORY_ACCESS_WRITE | 656 TEE_MEMORY_ACCESS_ANY_OWNER, 657 (uaddr_t)arg, sizeof(*arg)); 658 if (res) { 659 EMSG("ldelf stack is inaccessible!"); 660 return res; 661 } 662 663 memset(arg, 0, sizeof(*arg)); 664 arg->cmd = LDELF_DL_ENTRY_DLOPEN; 665 arg->dlopen.uuid = *uuid; 666 arg->dlopen.flags = flags; 667 668 res = thread_enter_user_mode((vaddr_t)arg, 0, 0, 0, 669 usr_stack, utc->dl_entry_func, 670 is_arm32, &panicked, &panic_code); 671 if (panicked) { 672 EMSG("ldelf dl_entry function panicked"); 673 abort_print_current_ta(); 674 res = TEE_ERROR_TARGET_DEAD; 675 } 676 if (!res) 677 res = arg->ret; 678 679 return res; 680 } 681 682 static TEE_Result call_ldelf_dlsym(struct user_ta_ctx *utc, TEE_UUID *uuid, 683 const char *sym, size_t maxlen, vaddr_t *val) 684 { 685 uaddr_t usr_stack = utc->ldelf_stack_ptr; 686 TEE_Result res = TEE_ERROR_GENERIC; 687 struct dl_entry_arg *arg = NULL; 688 uint32_t panic_code = 0; 689 uint32_t panicked = 0; 690 size_t len = strnlen(sym, maxlen); 691 692 if (len == maxlen) 693 return TEE_ERROR_BAD_PARAMETERS; 694 695 usr_stack -= ROUNDUP(sizeof(*arg) + len + 1, STACK_ALIGNMENT); 696 arg = (struct dl_entry_arg *)usr_stack; 697 698 res = tee_mmu_check_access_rights(&utc->uctx, 699 TEE_MEMORY_ACCESS_READ | 700 TEE_MEMORY_ACCESS_WRITE | 701 TEE_MEMORY_ACCESS_ANY_OWNER, 702 (uaddr_t)arg, sizeof(*arg) + len + 1); 703 if (res) { 704 EMSG("ldelf stack is inaccessible!"); 705 return res; 706 } 707 708 memset(arg, 0, sizeof(*arg)); 709 arg->cmd = LDELF_DL_ENTRY_DLSYM; 710 arg->dlsym.uuid = *uuid; 711 memcpy(arg->dlsym.symbol, sym, len); 712 arg->dlsym.symbol[len] = '\0'; 713 714 res = thread_enter_user_mode((vaddr_t)arg, 0, 0, 0, 715 usr_stack, utc->dl_entry_func, 716 is_arm32, &panicked, &panic_code); 717 if (panicked) { 718 EMSG("ldelf dl_entry function panicked"); 719 abort_print_current_ta(); 720 res = TEE_ERROR_TARGET_DEAD; 721 } 722 if (!res) { 723 res = arg->ret; 724 if (!res) 725 *val = arg->dlsym.val; 726 } 727 728 return res; 729 } 730 731 static TEE_Result system_dlopen(struct tee_ta_session *cs, uint32_t param_types, 732 TEE_Param params[TEE_NUM_PARAMS]) 733 { 734 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 735 TEE_PARAM_TYPE_VALUE_INPUT, 736 TEE_PARAM_TYPE_NONE, 737 TEE_PARAM_TYPE_NONE); 738 TEE_Result res = TEE_ERROR_GENERIC; 739 struct tee_ta_session *s = NULL; 740 struct user_ta_ctx *utc = NULL; 741 TEE_UUID *uuid = NULL; 742 uint32_t flags = 0; 743 744 if (exp_pt != param_types) 745 return TEE_ERROR_BAD_PARAMETERS; 746 747 uuid = params[0].memref.buffer; 748 if (!uuid || params[0].memref.size != sizeof(*uuid)) 749 return TEE_ERROR_BAD_PARAMETERS; 750 751 flags = params[1].value.a; 752 753 utc = to_user_ta_ctx(cs->ctx); 754 755 s = tee_ta_pop_current_session(); 756 res = call_ldelf_dlopen(utc, uuid, flags); 757 tee_ta_push_current_session(s); 758 759 return res; 760 } 761 762 static TEE_Result system_dlsym(struct tee_ta_session *cs, uint32_t param_types, 763 TEE_Param params[TEE_NUM_PARAMS]) 764 { 765 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 766 TEE_PARAM_TYPE_MEMREF_INPUT, 767 TEE_PARAM_TYPE_VALUE_OUTPUT, 768 TEE_PARAM_TYPE_NONE); 769 TEE_Result res = TEE_ERROR_GENERIC; 770 struct tee_ta_session *s = NULL; 771 struct user_ta_ctx *utc = NULL; 772 const char *sym = NULL; 773 TEE_UUID *uuid = NULL; 774 size_t maxlen = 0; 775 vaddr_t va = 0; 776 777 if (exp_pt != param_types) 778 return TEE_ERROR_BAD_PARAMETERS; 779 780 uuid = params[0].memref.buffer; 781 if (uuid && params[0].memref.size != sizeof(*uuid)) 782 return TEE_ERROR_BAD_PARAMETERS; 783 784 sym = params[1].memref.buffer; 785 if (!sym) 786 return TEE_ERROR_BAD_PARAMETERS; 787 maxlen = params[1].memref.size; 788 789 utc = to_user_ta_ctx(cs->ctx); 790 791 s = tee_ta_pop_current_session(); 792 res = call_ldelf_dlsym(utc, uuid, sym, maxlen, &va); 793 tee_ta_push_current_session(s); 794 795 if (!res) 796 reg_pair_from_64(va, ¶ms[2].value.a, ¶ms[2].value.b); 797 798 return res; 799 } 800 801 static TEE_Result system_get_tpm_event_log(uint32_t param_types, 802 TEE_Param params[TEE_NUM_PARAMS]) 803 { 804 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, 805 TEE_PARAM_TYPE_NONE, 806 TEE_PARAM_TYPE_NONE, 807 TEE_PARAM_TYPE_NONE); 808 size_t size = 0; 809 TEE_Result res = TEE_SUCCESS; 810 811 if (exp_pt != param_types) 812 return TEE_ERROR_BAD_PARAMETERS; 813 814 size = params[0].memref.size; 815 res = tpm_get_event_log(params[0].memref.buffer, &size); 816 params[0].memref.size = size; 817 818 return res; 819 } 820 821 static TEE_Result open_session(uint32_t param_types __unused, 822 TEE_Param params[TEE_NUM_PARAMS] __unused, 823 void **sess_ctx) 824 { 825 struct tee_ta_session *s = NULL; 826 struct system_ctx *ctx = NULL; 827 828 /* Check that we're called from a user TA */ 829 s = tee_ta_get_calling_session(); 830 if (!s) 831 return TEE_ERROR_ACCESS_DENIED; 832 if (!is_user_ta_ctx(s->ctx)) 833 return TEE_ERROR_ACCESS_DENIED; 834 835 ctx = calloc(1, sizeof(*ctx)); 836 if (!ctx) 837 return TEE_ERROR_OUT_OF_MEMORY; 838 839 *sess_ctx = ctx; 840 841 return TEE_SUCCESS; 842 } 843 844 static void close_session(void *sess_ctx) 845 { 846 struct system_ctx *ctx = sess_ctx; 847 848 handle_db_destroy(&ctx->db, ta_bin_close); 849 free(ctx); 850 } 851 852 static TEE_Result invoke_command(void *sess_ctx, uint32_t cmd_id, 853 uint32_t param_types, 854 TEE_Param params[TEE_NUM_PARAMS]) 855 { 856 struct tee_ta_session *s = tee_ta_get_calling_session(); 857 858 switch (cmd_id) { 859 case PTA_SYSTEM_ADD_RNG_ENTROPY: 860 return system_rng_reseed(s, param_types, params); 861 case PTA_SYSTEM_DERIVE_TA_UNIQUE_KEY: 862 return system_derive_ta_unique_key(s, param_types, params); 863 case PTA_SYSTEM_MAP_ZI: 864 return system_map_zi(s, param_types, params); 865 case PTA_SYSTEM_UNMAP: 866 return system_unmap(s, param_types, params); 867 case PTA_SYSTEM_OPEN_TA_BINARY: 868 return system_open_ta_binary(sess_ctx, param_types, params); 869 case PTA_SYSTEM_CLOSE_TA_BINARY: 870 return system_close_ta_binary(sess_ctx, param_types, params); 871 case PTA_SYSTEM_MAP_TA_BINARY: 872 return system_map_ta_binary(sess_ctx, s, param_types, params); 873 case PTA_SYSTEM_COPY_FROM_TA_BINARY: 874 return system_copy_from_ta_binary(sess_ctx, param_types, 875 params); 876 case PTA_SYSTEM_SET_PROT: 877 return system_set_prot(s, param_types, params); 878 case PTA_SYSTEM_REMAP: 879 return system_remap(s, param_types, params); 880 case PTA_SYSTEM_DLOPEN: 881 return system_dlopen(s, param_types, params); 882 case PTA_SYSTEM_DLSYM: 883 return system_dlsym(s, param_types, params); 884 case PTA_SYSTEM_GET_TPM_EVENT_LOG: 885 return system_get_tpm_event_log(param_types, params); 886 default: 887 break; 888 } 889 890 return TEE_ERROR_NOT_IMPLEMENTED; 891 } 892 893 pseudo_ta_register(.uuid = PTA_SYSTEM_UUID, .name = "system.pta", 894 .flags = PTA_DEFAULT_FLAGS | TA_FLAG_CONCURRENT, 895 .open_session_entry_point = open_session, 896 .close_session_entry_point = close_session, 897 .invoke_command_entry_point = invoke_command); 898