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 270 return TEE_SUCCESS; 271 err_oom: 272 res = TEE_ERROR_OUT_OF_MEMORY; 273 err: 274 ta_bin_close(binh); 275 return res; 276 } 277 278 static TEE_Result system_close_ta_binary(struct system_ctx *ctx, 279 uint32_t param_types, 280 TEE_Param params[TEE_NUM_PARAMS]) 281 { 282 TEE_Result res = TEE_SUCCESS; 283 struct bin_handle *binh = NULL; 284 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 285 TEE_PARAM_TYPE_NONE, 286 TEE_PARAM_TYPE_NONE, 287 TEE_PARAM_TYPE_NONE); 288 289 if (exp_pt != param_types) 290 return TEE_ERROR_BAD_PARAMETERS; 291 292 if (params[0].value.b) 293 return TEE_ERROR_BAD_PARAMETERS; 294 295 binh = handle_put(&ctx->db, params[0].value.a); 296 if (!binh) 297 return TEE_ERROR_BAD_PARAMETERS; 298 299 if (binh->offs_bytes < binh->size_bytes) 300 res = binh->op->read(binh->h, NULL, 301 binh->size_bytes - binh->offs_bytes); 302 303 ta_bin_close(binh); 304 return res; 305 } 306 307 static TEE_Result binh_copy_to(struct bin_handle *binh, vaddr_t va, 308 size_t offs_bytes, size_t num_bytes) 309 { 310 TEE_Result res = TEE_SUCCESS; 311 size_t l = num_bytes; 312 313 if (offs_bytes < binh->offs_bytes) 314 return TEE_ERROR_BAD_STATE; 315 if (offs_bytes > binh->offs_bytes) { 316 res = binh->op->read(binh->h, NULL, 317 offs_bytes - binh->offs_bytes); 318 if (res) 319 return res; 320 binh->offs_bytes = offs_bytes; 321 } 322 323 if (binh->offs_bytes + l > binh->size_bytes) { 324 size_t rb = binh->size_bytes - binh->offs_bytes; 325 326 res = binh->op->read(binh->h, (void *)va, rb); 327 if (res) 328 return res; 329 memset((uint8_t *)va + rb, 0, l - rb); 330 binh->offs_bytes = binh->size_bytes; 331 } else { 332 res = binh->op->read(binh->h, (void *)va, l); 333 if (res) 334 return res; 335 binh->offs_bytes += l; 336 } 337 338 return TEE_SUCCESS; 339 } 340 341 static TEE_Result system_map_ta_binary(struct system_ctx *ctx, 342 struct tee_ta_session *s, 343 uint32_t param_types, 344 TEE_Param params[TEE_NUM_PARAMS]) 345 { 346 const uint32_t accept_flags = PTA_SYSTEM_MAP_FLAG_SHAREABLE | 347 PTA_SYSTEM_MAP_FLAG_WRITEABLE | 348 PTA_SYSTEM_MAP_FLAG_EXECUTABLE; 349 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 350 TEE_PARAM_TYPE_VALUE_INPUT, 351 TEE_PARAM_TYPE_VALUE_INOUT, 352 TEE_PARAM_TYPE_VALUE_INPUT); 353 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 354 struct bin_handle *binh = NULL; 355 TEE_Result res = TEE_SUCCESS; 356 struct file_slice *fs = NULL; 357 bool file_is_locked = false; 358 struct mobj *mobj = NULL; 359 uint32_t offs_bytes = 0; 360 uint32_t offs_pages = 0; 361 uint32_t num_bytes = 0; 362 uint32_t pad_begin = 0; 363 uint32_t pad_end = 0; 364 size_t num_pages = 0; 365 uint32_t flags = 0; 366 uint32_t prot = 0; 367 vaddr_t va = 0; 368 369 if (exp_pt != param_types) 370 return TEE_ERROR_BAD_PARAMETERS; 371 372 binh = handle_lookup(&ctx->db, params[0].value.a); 373 if (!binh) 374 return TEE_ERROR_BAD_PARAMETERS; 375 flags = params[0].value.b; 376 offs_bytes = params[1].value.a; 377 num_bytes = params[1].value.b; 378 va = reg_pair_to_64(params[2].value.a, params[2].value.b); 379 pad_begin = params[3].value.a; 380 pad_end = params[3].value.b; 381 382 if ((flags & accept_flags) != flags) 383 return TEE_ERROR_BAD_PARAMETERS; 384 385 if ((flags & PTA_SYSTEM_MAP_FLAG_SHAREABLE) && 386 (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) 387 return TEE_ERROR_BAD_PARAMETERS; 388 389 if ((flags & PTA_SYSTEM_MAP_FLAG_EXECUTABLE) && 390 (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) 391 return TEE_ERROR_BAD_PARAMETERS; 392 393 if (offs_bytes & SMALL_PAGE_MASK) 394 return TEE_ERROR_BAD_PARAMETERS; 395 396 prot = TEE_MATTR_UR | TEE_MATTR_PR; 397 if (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE) 398 prot |= TEE_MATTR_UW | TEE_MATTR_PW; 399 if (flags & PTA_SYSTEM_MAP_FLAG_EXECUTABLE) 400 prot |= TEE_MATTR_UX; 401 402 offs_pages = offs_bytes >> SMALL_PAGE_SHIFT; 403 num_pages = ROUNDUP(num_bytes, SMALL_PAGE_SIZE) / SMALL_PAGE_SIZE; 404 405 if (!file_trylock(binh->f)) { 406 /* 407 * Before we can block on the file lock we must make all 408 * our page tables available for reclaiming in order to 409 * avoid a dead-lock with the other thread (which already 410 * is holding the file lock) mapping lots of memory below. 411 */ 412 tee_mmu_set_ctx(NULL); 413 file_lock(binh->f); 414 tee_mmu_set_ctx(s->ctx); 415 } 416 file_is_locked = true; 417 fs = file_find_slice(binh->f, offs_pages); 418 if (fs) { 419 /* If there's registered slice it has to match */ 420 if (fs->page_offset != offs_pages || 421 num_pages > fs->fobj->num_pages) { 422 res = TEE_ERROR_BAD_PARAMETERS; 423 goto err; 424 } 425 426 /* If there's a slice we must be mapping shareable */ 427 if (!(flags & PTA_SYSTEM_MAP_FLAG_SHAREABLE)) { 428 res = TEE_ERROR_BAD_PARAMETERS; 429 goto err; 430 } 431 432 mobj = mobj_with_fobj_alloc(fs->fobj, binh->f); 433 if (!mobj) { 434 res = TEE_ERROR_OUT_OF_MEMORY; 435 goto err; 436 } 437 res = vm_map_pad(&utc->uctx, &va, num_pages * SMALL_PAGE_SIZE, 438 prot, VM_FLAG_READONLY, 439 mobj, 0, pad_begin, pad_end); 440 mobj_put(mobj); 441 if (res) 442 goto err; 443 } else { 444 struct fobj *f = fobj_ta_mem_alloc(num_pages); 445 struct file *file = NULL; 446 uint32_t vm_flags = 0; 447 448 if (!f) { 449 res = TEE_ERROR_OUT_OF_MEMORY; 450 goto err; 451 } 452 if (!(flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) { 453 file = binh->f; 454 vm_flags |= VM_FLAG_READONLY; 455 } 456 457 mobj = mobj_with_fobj_alloc(f, file); 458 fobj_put(f); 459 if (!mobj) { 460 res = TEE_ERROR_OUT_OF_MEMORY; 461 goto err; 462 } 463 res = vm_map_pad(&utc->uctx, &va, num_pages * SMALL_PAGE_SIZE, 464 TEE_MATTR_PRW, vm_flags, mobj, 0, 465 pad_begin, pad_end); 466 mobj_put(mobj); 467 if (res) 468 goto err; 469 res = binh_copy_to(binh, va, offs_bytes, num_bytes); 470 if (res) 471 goto err_unmap_va; 472 res = vm_set_prot(&utc->uctx, va, num_pages * SMALL_PAGE_SIZE, 473 prot); 474 if (res) 475 goto err_unmap_va; 476 477 /* 478 * The context currently is active set it again to update 479 * the mapping. 480 */ 481 tee_mmu_set_ctx(s->ctx); 482 483 if (!(flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE)) { 484 res = file_add_slice(binh->f, f, offs_pages); 485 if (res) 486 goto err_unmap_va; 487 } 488 } 489 490 file_unlock(binh->f); 491 492 reg_pair_from_64(va, ¶ms[2].value.a, ¶ms[2].value.b); 493 return TEE_SUCCESS; 494 495 err_unmap_va: 496 if (vm_unmap(&utc->uctx, va, num_pages * SMALL_PAGE_SIZE)) 497 panic(); 498 499 /* 500 * The context currently is active set it again to update 501 * the mapping. 502 */ 503 tee_mmu_set_ctx(s->ctx); 504 505 err: 506 if (file_is_locked) 507 file_unlock(binh->f); 508 509 return res; 510 } 511 512 static TEE_Result system_copy_from_ta_binary(struct system_ctx *ctx, 513 uint32_t param_types, 514 TEE_Param params[TEE_NUM_PARAMS]) 515 { 516 struct bin_handle *binh = NULL; 517 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 518 TEE_PARAM_TYPE_MEMREF_OUTPUT, 519 TEE_PARAM_TYPE_NONE, 520 TEE_PARAM_TYPE_NONE); 521 522 if (exp_pt != param_types) 523 return TEE_ERROR_BAD_PARAMETERS; 524 525 binh = handle_lookup(&ctx->db, params[0].value.a); 526 if (!binh) 527 return TEE_ERROR_BAD_PARAMETERS; 528 529 return binh_copy_to(binh, (vaddr_t)params[1].memref.buffer, 530 params[0].value.b, params[1].memref.size); 531 } 532 533 static TEE_Result system_set_prot(struct tee_ta_session *s, 534 uint32_t param_types, 535 TEE_Param params[TEE_NUM_PARAMS]) 536 { 537 const uint32_t accept_flags = PTA_SYSTEM_MAP_FLAG_WRITEABLE | 538 PTA_SYSTEM_MAP_FLAG_EXECUTABLE; 539 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 540 TEE_PARAM_TYPE_VALUE_INPUT, 541 TEE_PARAM_TYPE_NONE, 542 TEE_PARAM_TYPE_NONE); 543 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 544 uint32_t prot = TEE_MATTR_UR | TEE_MATTR_PR; 545 TEE_Result res = TEE_SUCCESS; 546 uint32_t vm_flags = 0; 547 uint32_t flags = 0; 548 vaddr_t va = 0; 549 size_t sz = 0; 550 551 if (exp_pt != param_types) 552 return TEE_ERROR_BAD_PARAMETERS; 553 554 flags = params[0].value.b; 555 556 if ((flags & accept_flags) != flags) 557 return TEE_ERROR_BAD_PARAMETERS; 558 if (flags & PTA_SYSTEM_MAP_FLAG_WRITEABLE) 559 prot |= TEE_MATTR_UW | TEE_MATTR_PW; 560 if (flags & PTA_SYSTEM_MAP_FLAG_EXECUTABLE) 561 prot |= TEE_MATTR_UX; 562 563 va = reg_pair_to_64(params[1].value.a, params[1].value.b), 564 sz = ROUNDUP(params[0].value.a, SMALL_PAGE_SIZE); 565 566 res = vm_get_flags(&utc->uctx, va, sz, &vm_flags); 567 if (res) 568 return res; 569 if (vm_flags & VM_FLAG_PERMANENT) 570 return TEE_ERROR_ACCESS_DENIED; 571 572 /* 573 * If the segment is a mapping of a part of a file (vm_flags & 574 * VM_FLAG_READONLY) it cannot be made writeable as all mapped 575 * files are mapped read-only. 576 */ 577 if ((vm_flags & VM_FLAG_READONLY) && 578 (prot & (TEE_MATTR_UW | TEE_MATTR_PW))) 579 return TEE_ERROR_ACCESS_DENIED; 580 581 return vm_set_prot(&utc->uctx, va, sz, prot); 582 } 583 584 static TEE_Result system_remap(struct tee_ta_session *s, uint32_t param_types, 585 TEE_Param params[TEE_NUM_PARAMS]) 586 { 587 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT, 588 TEE_PARAM_TYPE_VALUE_INPUT, 589 TEE_PARAM_TYPE_VALUE_INOUT, 590 TEE_PARAM_TYPE_VALUE_INPUT); 591 struct user_ta_ctx *utc = to_user_ta_ctx(s->ctx); 592 TEE_Result res = TEE_SUCCESS; 593 uint32_t num_bytes = 0; 594 uint32_t pad_begin = 0; 595 uint32_t vm_flags = 0; 596 uint32_t pad_end = 0; 597 vaddr_t old_va = 0; 598 vaddr_t new_va = 0; 599 600 if (exp_pt != param_types) 601 return TEE_ERROR_BAD_PARAMETERS; 602 603 num_bytes = params[0].value.a; 604 old_va = reg_pair_to_64(params[1].value.a, params[1].value.b); 605 new_va = reg_pair_to_64(params[2].value.a, params[2].value.b); 606 pad_begin = params[3].value.a; 607 pad_end = params[3].value.b; 608 609 res = vm_get_flags(&utc->uctx, old_va, num_bytes, &vm_flags); 610 if (res) 611 return res; 612 if (vm_flags & VM_FLAG_PERMANENT) 613 return TEE_ERROR_ACCESS_DENIED; 614 615 res = vm_remap(&utc->uctx, &new_va, old_va, num_bytes, pad_begin, 616 pad_end); 617 if (!res) 618 reg_pair_from_64(new_va, ¶ms[2].value.a, 619 ¶ms[2].value.b); 620 621 return res; 622 } 623 624 /* ldelf has the same architecture/register width as the kernel */ 625 #ifdef ARM32 626 static const bool is_arm32 = true; 627 #else 628 static const bool is_arm32; 629 #endif 630 631 static TEE_Result call_ldelf_dlopen(struct user_ta_ctx *utc, TEE_UUID *uuid, 632 uint32_t flags) 633 { 634 uaddr_t usr_stack = utc->ldelf_stack_ptr; 635 TEE_Result res = TEE_ERROR_GENERIC; 636 struct dl_entry_arg *arg = NULL; 637 uint32_t panic_code = 0; 638 uint32_t panicked = 0; 639 640 assert(uuid); 641 642 usr_stack -= ROUNDUP(sizeof(*arg), STACK_ALIGNMENT); 643 arg = (struct dl_entry_arg *)usr_stack; 644 645 res = tee_mmu_check_access_rights(&utc->uctx, 646 TEE_MEMORY_ACCESS_READ | 647 TEE_MEMORY_ACCESS_WRITE | 648 TEE_MEMORY_ACCESS_ANY_OWNER, 649 (uaddr_t)arg, sizeof(*arg)); 650 if (res) { 651 EMSG("ldelf stack is inaccessible!"); 652 return res; 653 } 654 655 memset(arg, 0, sizeof(*arg)); 656 arg->cmd = LDELF_DL_ENTRY_DLOPEN; 657 arg->dlopen.uuid = *uuid; 658 arg->dlopen.flags = flags; 659 660 res = thread_enter_user_mode((vaddr_t)arg, 0, 0, 0, 661 usr_stack, utc->dl_entry_func, 662 is_arm32, &panicked, &panic_code); 663 if (panicked) { 664 EMSG("ldelf dl_entry function panicked"); 665 abort_print_current_ta(); 666 res = TEE_ERROR_TARGET_DEAD; 667 } 668 if (!res) 669 res = arg->ret; 670 671 return res; 672 } 673 674 static TEE_Result call_ldelf_dlsym(struct user_ta_ctx *utc, TEE_UUID *uuid, 675 const char *sym, size_t maxlen, vaddr_t *val) 676 { 677 uaddr_t usr_stack = utc->ldelf_stack_ptr; 678 TEE_Result res = TEE_ERROR_GENERIC; 679 struct dl_entry_arg *arg = NULL; 680 uint32_t panic_code = 0; 681 uint32_t panicked = 0; 682 size_t len = strnlen(sym, maxlen); 683 684 if (len == maxlen) 685 return TEE_ERROR_BAD_PARAMETERS; 686 687 usr_stack -= ROUNDUP(sizeof(*arg) + len + 1, STACK_ALIGNMENT); 688 arg = (struct dl_entry_arg *)usr_stack; 689 690 res = tee_mmu_check_access_rights(&utc->uctx, 691 TEE_MEMORY_ACCESS_READ | 692 TEE_MEMORY_ACCESS_WRITE | 693 TEE_MEMORY_ACCESS_ANY_OWNER, 694 (uaddr_t)arg, sizeof(*arg) + len + 1); 695 if (res) { 696 EMSG("ldelf stack is inaccessible!"); 697 return res; 698 } 699 700 memset(arg, 0, sizeof(*arg)); 701 arg->cmd = LDELF_DL_ENTRY_DLSYM; 702 arg->dlsym.uuid = *uuid; 703 memcpy(arg->dlsym.symbol, sym, len); 704 arg->dlsym.symbol[len] = '\0'; 705 706 res = thread_enter_user_mode((vaddr_t)arg, 0, 0, 0, 707 usr_stack, utc->dl_entry_func, 708 is_arm32, &panicked, &panic_code); 709 if (panicked) { 710 EMSG("ldelf dl_entry function panicked"); 711 abort_print_current_ta(); 712 res = TEE_ERROR_TARGET_DEAD; 713 } 714 if (!res) { 715 res = arg->ret; 716 if (!res) 717 *val = arg->dlsym.val; 718 } 719 720 return res; 721 } 722 723 static TEE_Result system_dlopen(struct tee_ta_session *cs, uint32_t param_types, 724 TEE_Param params[TEE_NUM_PARAMS]) 725 { 726 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 727 TEE_PARAM_TYPE_VALUE_INPUT, 728 TEE_PARAM_TYPE_NONE, 729 TEE_PARAM_TYPE_NONE); 730 TEE_Result res = TEE_ERROR_GENERIC; 731 struct tee_ta_session *s = NULL; 732 struct user_ta_ctx *utc = NULL; 733 TEE_UUID *uuid = NULL; 734 uint32_t flags = 0; 735 736 if (exp_pt != param_types) 737 return TEE_ERROR_BAD_PARAMETERS; 738 739 uuid = params[0].memref.buffer; 740 if (!uuid || params[0].memref.size != sizeof(*uuid)) 741 return TEE_ERROR_BAD_PARAMETERS; 742 743 flags = params[1].value.a; 744 745 utc = to_user_ta_ctx(cs->ctx); 746 747 s = tee_ta_pop_current_session(); 748 res = call_ldelf_dlopen(utc, uuid, flags); 749 tee_ta_push_current_session(s); 750 751 return res; 752 } 753 754 static TEE_Result system_dlsym(struct tee_ta_session *cs, uint32_t param_types, 755 TEE_Param params[TEE_NUM_PARAMS]) 756 { 757 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INPUT, 758 TEE_PARAM_TYPE_MEMREF_INPUT, 759 TEE_PARAM_TYPE_VALUE_OUTPUT, 760 TEE_PARAM_TYPE_NONE); 761 TEE_Result res = TEE_ERROR_GENERIC; 762 struct tee_ta_session *s = NULL; 763 struct user_ta_ctx *utc = NULL; 764 const char *sym = NULL; 765 TEE_UUID *uuid = NULL; 766 size_t maxlen = 0; 767 vaddr_t va = 0; 768 769 if (exp_pt != param_types) 770 return TEE_ERROR_BAD_PARAMETERS; 771 772 uuid = params[0].memref.buffer; 773 if (uuid && params[0].memref.size != sizeof(*uuid)) 774 return TEE_ERROR_BAD_PARAMETERS; 775 776 sym = params[1].memref.buffer; 777 if (!sym) 778 return TEE_ERROR_BAD_PARAMETERS; 779 maxlen = params[1].memref.size; 780 781 utc = to_user_ta_ctx(cs->ctx); 782 783 s = tee_ta_pop_current_session(); 784 res = call_ldelf_dlsym(utc, uuid, sym, maxlen, &va); 785 tee_ta_push_current_session(s); 786 787 if (!res) 788 reg_pair_from_64(va, ¶ms[2].value.a, ¶ms[2].value.b); 789 790 return res; 791 } 792 793 static TEE_Result system_get_tpm_event_log(uint32_t param_types, 794 TEE_Param params[TEE_NUM_PARAMS]) 795 { 796 uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_OUTPUT, 797 TEE_PARAM_TYPE_NONE, 798 TEE_PARAM_TYPE_NONE, 799 TEE_PARAM_TYPE_NONE); 800 size_t size = 0; 801 TEE_Result res = TEE_SUCCESS; 802 803 if (exp_pt != param_types) 804 return TEE_ERROR_BAD_PARAMETERS; 805 806 size = params[0].memref.size; 807 res = tpm_get_event_log(params[0].memref.buffer, &size); 808 params[0].memref.size = size; 809 810 return res; 811 } 812 813 static TEE_Result open_session(uint32_t param_types __unused, 814 TEE_Param params[TEE_NUM_PARAMS] __unused, 815 void **sess_ctx) 816 { 817 struct tee_ta_session *s = NULL; 818 struct system_ctx *ctx = NULL; 819 820 /* Check that we're called from a user TA */ 821 s = tee_ta_get_calling_session(); 822 if (!s) 823 return TEE_ERROR_ACCESS_DENIED; 824 if (!is_user_ta_ctx(s->ctx)) 825 return TEE_ERROR_ACCESS_DENIED; 826 827 ctx = calloc(1, sizeof(*ctx)); 828 if (!ctx) 829 return TEE_ERROR_OUT_OF_MEMORY; 830 831 *sess_ctx = ctx; 832 833 return TEE_SUCCESS; 834 } 835 836 static void close_session(void *sess_ctx) 837 { 838 struct system_ctx *ctx = sess_ctx; 839 840 handle_db_destroy(&ctx->db, ta_bin_close); 841 free(ctx); 842 } 843 844 static TEE_Result invoke_command(void *sess_ctx, uint32_t cmd_id, 845 uint32_t param_types, 846 TEE_Param params[TEE_NUM_PARAMS]) 847 { 848 struct tee_ta_session *s = tee_ta_get_calling_session(); 849 850 switch (cmd_id) { 851 case PTA_SYSTEM_ADD_RNG_ENTROPY: 852 return system_rng_reseed(s, param_types, params); 853 case PTA_SYSTEM_DERIVE_TA_UNIQUE_KEY: 854 return system_derive_ta_unique_key(s, param_types, params); 855 case PTA_SYSTEM_MAP_ZI: 856 return system_map_zi(s, param_types, params); 857 case PTA_SYSTEM_UNMAP: 858 return system_unmap(s, param_types, params); 859 case PTA_SYSTEM_OPEN_TA_BINARY: 860 return system_open_ta_binary(sess_ctx, param_types, params); 861 case PTA_SYSTEM_CLOSE_TA_BINARY: 862 return system_close_ta_binary(sess_ctx, param_types, params); 863 case PTA_SYSTEM_MAP_TA_BINARY: 864 return system_map_ta_binary(sess_ctx, s, param_types, params); 865 case PTA_SYSTEM_COPY_FROM_TA_BINARY: 866 return system_copy_from_ta_binary(sess_ctx, param_types, 867 params); 868 case PTA_SYSTEM_SET_PROT: 869 return system_set_prot(s, param_types, params); 870 case PTA_SYSTEM_REMAP: 871 return system_remap(s, param_types, params); 872 case PTA_SYSTEM_DLOPEN: 873 return system_dlopen(s, param_types, params); 874 case PTA_SYSTEM_DLSYM: 875 return system_dlsym(s, param_types, params); 876 case PTA_SYSTEM_GET_TPM_EVENT_LOG: 877 return system_get_tpm_event_log(param_types, params); 878 default: 879 break; 880 } 881 882 return TEE_ERROR_NOT_IMPLEMENTED; 883 } 884 885 pseudo_ta_register(.uuid = PTA_SYSTEM_UUID, .name = "system.pta", 886 .flags = PTA_DEFAULT_FLAGS | TA_FLAG_CONCURRENT, 887 .open_session_entry_point = open_session, 888 .close_session_entry_point = close_session, 889 .invoke_command_entry_point = invoke_command); 890