1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 * Copyright (c) 2015-2020, 2022 Linaro Limited 5 * Copyright (c) 2020-2023, Arm Limited 6 */ 7 8 #include <assert.h> 9 #include <kernel/ldelf_loader.h> 10 #include <kernel/ldelf_syscalls.h> 11 #include <kernel/scall.h> 12 #include <kernel/user_access.h> 13 #include <ldelf.h> 14 #include <mm/mobj.h> 15 #include <mm/vm.h> 16 17 #define BOUNCE_BUFFER_SIZE 4096 18 19 extern uint8_t ldelf_data[]; 20 extern const unsigned int ldelf_code_size; 21 extern const unsigned int ldelf_data_size; 22 extern const unsigned int ldelf_entry; 23 24 /* ldelf has the same architecture/register width as the kernel */ 25 #if defined(ARM32) || defined(RV32) 26 static const bool is_32bit = true; 27 #else 28 static const bool is_32bit; 29 #endif 30 31 static TEE_Result alloc_and_map_fobj(struct user_mode_ctx *uctx, size_t sz, 32 uint32_t prot, uint32_t flags, vaddr_t *va) 33 { 34 size_t num_pgs = ROUNDUP(sz, SMALL_PAGE_SIZE) / SMALL_PAGE_SIZE; 35 struct fobj *fobj = fobj_ta_mem_alloc(num_pgs); 36 struct mobj *mobj = mobj_with_fobj_alloc(fobj, NULL, 37 TEE_MATTR_MEM_TYPE_TAGGED); 38 TEE_Result res = TEE_SUCCESS; 39 40 fobj_put(fobj); 41 if (!mobj) 42 return TEE_ERROR_OUT_OF_MEMORY; 43 res = vm_map(uctx, va, num_pgs * SMALL_PAGE_SIZE, prot, flags, mobj, 0); 44 mobj_put(mobj); 45 46 return res; 47 } 48 49 /* 50 * This function may leave a few mappings behind on error, but that's taken 51 * care of by tee_ta_init_user_ta_session() since the entire context is 52 * removed then. 53 */ 54 TEE_Result ldelf_load_ldelf(struct user_mode_ctx *uctx) 55 { 56 TEE_Result res = TEE_SUCCESS; 57 vaddr_t stack_addr = 0; 58 vaddr_t code_addr = 0; 59 vaddr_t rw_addr = 0; 60 vaddr_t bb_addr = 0; 61 uint32_t prot = 0; 62 63 uctx->is_32bit = is_32bit; 64 65 res = alloc_and_map_fobj(uctx, BOUNCE_BUFFER_SIZE, TEE_MATTR_PRW, 0, 66 &bb_addr); 67 if (res) 68 return res; 69 uctx->bbuf = (void *)bb_addr; 70 uctx->bbuf_size = BOUNCE_BUFFER_SIZE; 71 72 res = alloc_and_map_fobj(uctx, LDELF_STACK_SIZE, 73 TEE_MATTR_URW | TEE_MATTR_PRW, VM_FLAG_LDELF, 74 &stack_addr); 75 if (res) 76 return res; 77 uctx->ldelf_stack_ptr = stack_addr + LDELF_STACK_SIZE; 78 79 res = alloc_and_map_fobj(uctx, ldelf_code_size, TEE_MATTR_PRW, 80 VM_FLAG_LDELF, &code_addr); 81 if (res) 82 return res; 83 uctx->entry_func = code_addr + ldelf_entry; 84 85 rw_addr = ROUNDUP(code_addr + ldelf_code_size, SMALL_PAGE_SIZE); 86 res = alloc_and_map_fobj(uctx, ldelf_data_size, 87 TEE_MATTR_URW | TEE_MATTR_PRW, VM_FLAG_LDELF, 88 &rw_addr); 89 if (res) 90 return res; 91 92 vm_set_ctx(uctx->ts_ctx); 93 94 memcpy((void *)code_addr, ldelf_data, ldelf_code_size); 95 96 res = copy_to_user((void *)rw_addr, ldelf_data + ldelf_code_size, 97 ldelf_data_size); 98 if (res) 99 return res; 100 101 prot = TEE_MATTR_URX; 102 if (IS_ENABLED(CFG_CORE_BTI)) 103 prot |= TEE_MATTR_GUARDED; 104 105 res = vm_set_prot(uctx, code_addr, 106 ROUNDUP(ldelf_code_size, SMALL_PAGE_SIZE), prot); 107 if (res) 108 return res; 109 110 DMSG("ldelf load address %#"PRIxVA, code_addr); 111 112 return TEE_SUCCESS; 113 } 114 115 TEE_Result ldelf_init_with_ldelf(struct ts_session *sess, 116 struct user_mode_ctx *uctx) 117 { 118 TEE_Result res = TEE_SUCCESS; 119 struct ldelf_arg *arg = NULL; 120 uint32_t panic_code = 0; 121 uint32_t panicked = 0; 122 uaddr_t usr_stack = 0; 123 struct ldelf_arg *arg_bbuf = NULL; 124 125 usr_stack = uctx->ldelf_stack_ptr; 126 usr_stack -= ROUNDUP(sizeof(*arg), STACK_ALIGNMENT); 127 arg = (struct ldelf_arg *)usr_stack; 128 sess->handle_scall = scall_handle_ldelf; 129 130 res = clear_user(arg, sizeof(*arg)); 131 if (res) 132 return res; 133 134 res = PUT_USER_SCALAR(uctx->ts_ctx->uuid, &arg->uuid); 135 if (res) 136 return res; 137 138 res = thread_enter_user_mode((vaddr_t)arg, 0, 0, 0, 139 usr_stack, uctx->entry_func, 140 is_32bit, &panicked, &panic_code); 141 142 sess->handle_scall = sess->ctx->ops->handle_scall; 143 thread_user_clear_vfp(uctx); 144 ldelf_sess_cleanup(sess); 145 146 if (panicked) { 147 abort_print_current_ts(); 148 EMSG("ldelf panicked"); 149 return TEE_ERROR_GENERIC; 150 } 151 if (res) { 152 EMSG("ldelf failed with res: %#"PRIx32, res); 153 return res; 154 } 155 156 res = BB_MEMDUP_USER(arg, sizeof(*arg), &arg_bbuf); 157 if (res) 158 return res; 159 160 if (is_user_ta_ctx(uctx->ts_ctx)) { 161 /* 162 * This is already checked by the elf loader, but since it runs 163 * in user mode we're not trusting it entirely. 164 */ 165 if (arg_bbuf->flags & ~TA_FLAGS_MASK) 166 return TEE_ERROR_BAD_FORMAT; 167 168 to_user_ta_ctx(uctx->ts_ctx)->ta_ctx.flags = arg_bbuf->flags; 169 } 170 171 uctx->is_32bit = arg_bbuf->is_32bit; 172 uctx->entry_func = arg_bbuf->entry_func; 173 uctx->load_addr = arg_bbuf->load_addr; 174 uctx->stack_ptr = arg_bbuf->stack_ptr; 175 uctx->dump_entry_func = arg_bbuf->dump_entry; 176 #ifdef CFG_FTRACE_SUPPORT 177 uctx->ftrace_entry_func = arg_bbuf->ftrace_entry; 178 sess->fbuf = arg_bbuf->fbuf; 179 #endif 180 uctx->dl_entry_func = arg_bbuf->dl_entry; 181 182 bb_free(arg_bbuf, sizeof(*arg)); 183 184 return TEE_SUCCESS; 185 } 186 187 TEE_Result ldelf_dump_state(struct user_mode_ctx *uctx) 188 { 189 TEE_Result res = TEE_SUCCESS; 190 uaddr_t usr_stack = uctx->ldelf_stack_ptr; 191 struct dump_entry_arg *arg = NULL; 192 uint32_t panic_code = 0; 193 uint32_t panicked = 0; 194 struct thread_specific_data *tsd = thread_get_tsd(); 195 struct ts_session *sess = NULL; 196 struct vm_region *r = NULL; 197 size_t arg_size = 0; 198 size_t n = 0; 199 200 TAILQ_FOREACH(r, &uctx->vm_info.regions, link) 201 if (r->attr & TEE_MATTR_URWX) 202 n++; 203 204 arg_size = ROUNDUP(sizeof(*arg) + n * sizeof(struct dump_map), 205 STACK_ALIGNMENT); 206 207 usr_stack = uctx->ldelf_stack_ptr; 208 usr_stack -= arg_size; 209 210 arg = bb_alloc(arg_size); 211 if (!arg) 212 return TEE_ERROR_OUT_OF_MEMORY; 213 memset(arg, 0, arg_size); 214 215 arg->num_maps = n; 216 n = 0; 217 TAILQ_FOREACH(r, &uctx->vm_info.regions, link) { 218 if (r->attr & TEE_MATTR_URWX) { 219 if (r->mobj) 220 mobj_get_pa(r->mobj, r->offset, 0, 221 &arg->maps[n].pa); 222 arg->maps[n].va = r->va; 223 arg->maps[n].sz = r->size; 224 if (r->attr & TEE_MATTR_UR) 225 arg->maps[n].flags |= DUMP_MAP_READ; 226 if (r->attr & TEE_MATTR_UW) 227 arg->maps[n].flags |= DUMP_MAP_WRITE; 228 if (r->attr & TEE_MATTR_UX) 229 arg->maps[n].flags |= DUMP_MAP_EXEC; 230 if (r->attr & TEE_MATTR_SECURE) 231 arg->maps[n].flags |= DUMP_MAP_SECURE; 232 if (r->flags & VM_FLAG_EPHEMERAL) 233 arg->maps[n].flags |= DUMP_MAP_EPHEM; 234 if (r->flags & VM_FLAG_LDELF) 235 arg->maps[n].flags |= DUMP_MAP_LDELF; 236 n++; 237 } 238 } 239 240 arg->is_32bit = uctx->is_32bit; 241 #ifdef ARM32 242 arg->arm32.regs[0] = tsd->abort_regs.r0; 243 arg->arm32.regs[1] = tsd->abort_regs.r1; 244 arg->arm32.regs[2] = tsd->abort_regs.r2; 245 arg->arm32.regs[3] = tsd->abort_regs.r3; 246 arg->arm32.regs[4] = tsd->abort_regs.r4; 247 arg->arm32.regs[5] = tsd->abort_regs.r5; 248 arg->arm32.regs[6] = tsd->abort_regs.r6; 249 arg->arm32.regs[7] = tsd->abort_regs.r7; 250 arg->arm32.regs[8] = tsd->abort_regs.r8; 251 arg->arm32.regs[9] = tsd->abort_regs.r9; 252 arg->arm32.regs[10] = tsd->abort_regs.r10; 253 arg->arm32.regs[11] = tsd->abort_regs.r11; 254 arg->arm32.regs[12] = tsd->abort_regs.ip; 255 arg->arm32.regs[13] = tsd->abort_regs.usr_sp; /*SP*/ 256 arg->arm32.regs[14] = tsd->abort_regs.usr_lr; /*LR*/ 257 arg->arm32.regs[15] = tsd->abort_regs.elr; /*PC*/ 258 #endif /*ARM32*/ 259 #ifdef ARM64 260 if (uctx->is_32bit) { 261 arg->arm32.regs[0] = tsd->abort_regs.x0; 262 arg->arm32.regs[1] = tsd->abort_regs.x1; 263 arg->arm32.regs[2] = tsd->abort_regs.x2; 264 arg->arm32.regs[3] = tsd->abort_regs.x3; 265 arg->arm32.regs[4] = tsd->abort_regs.x4; 266 arg->arm32.regs[5] = tsd->abort_regs.x5; 267 arg->arm32.regs[6] = tsd->abort_regs.x6; 268 arg->arm32.regs[7] = tsd->abort_regs.x7; 269 arg->arm32.regs[8] = tsd->abort_regs.x8; 270 arg->arm32.regs[9] = tsd->abort_regs.x9; 271 arg->arm32.regs[10] = tsd->abort_regs.x10; 272 arg->arm32.regs[11] = tsd->abort_regs.x11; 273 arg->arm32.regs[12] = tsd->abort_regs.x12; 274 arg->arm32.regs[13] = tsd->abort_regs.x13; /*SP*/ 275 arg->arm32.regs[14] = tsd->abort_regs.x14; /*LR*/ 276 arg->arm32.regs[15] = tsd->abort_regs.elr; /*PC*/ 277 } else { 278 arg->arm64.fp = tsd->abort_regs.x29; 279 arg->arm64.pc = tsd->abort_regs.elr; 280 arg->arm64.sp = tsd->abort_regs.sp_el0; 281 } 282 #endif /*ARM64*/ 283 #if defined(RV64) || defined(RV32) 284 arg->rv.fp = tsd->abort_regs.s0; 285 arg->rv.pc = tsd->abort_regs.epc; 286 arg->rv.sp = tsd->abort_regs.sp; 287 #endif /*RV64||RV32*/ 288 289 res = copy_to_user((void *)usr_stack, arg, arg_size); 290 if (res) 291 return res; 292 293 sess = ts_get_current_session(); 294 sess->handle_scall = scall_handle_ldelf; 295 296 res = thread_enter_user_mode(usr_stack, 0, 0, 0, 297 usr_stack, uctx->dump_entry_func, 298 is_32bit, &panicked, &panic_code); 299 300 sess->handle_scall = sess->ctx->ops->handle_scall; 301 thread_user_clear_vfp(uctx); 302 ldelf_sess_cleanup(sess); 303 304 if (panicked) { 305 uctx->dump_entry_func = 0; 306 EMSG("ldelf dump function panicked"); 307 abort_print_current_ts(); 308 res = TEE_ERROR_TARGET_DEAD; 309 } 310 311 return res; 312 } 313 314 #ifdef CFG_FTRACE_SUPPORT 315 TEE_Result ldelf_dump_ftrace(struct user_mode_ctx *uctx, 316 void *buf, size_t *blen) 317 { 318 uaddr_t usr_stack = uctx->ldelf_stack_ptr; 319 TEE_Result res = TEE_SUCCESS; 320 uint32_t panic_code = 0; 321 uint32_t panicked = 0; 322 size_t *arg = NULL; 323 struct ts_session *sess = NULL; 324 325 if (!uctx->ftrace_entry_func) 326 return TEE_ERROR_NOT_SUPPORTED; 327 328 usr_stack -= ROUNDUP(sizeof(*arg), STACK_ALIGNMENT); 329 arg = (size_t *)usr_stack; 330 331 res = vm_check_access_rights(uctx, 332 TEE_MEMORY_ACCESS_READ | 333 TEE_MEMORY_ACCESS_ANY_OWNER, 334 (uaddr_t)arg, sizeof(*arg)); 335 if (res) { 336 EMSG("ldelf stack is inaccessible!"); 337 return res; 338 } 339 340 *arg = *blen; 341 342 sess = ts_get_current_session(); 343 sess->handle_scall = scall_handle_ldelf; 344 345 res = thread_enter_user_mode((vaddr_t)buf, (vaddr_t)arg, 0, 0, 346 usr_stack, uctx->ftrace_entry_func, 347 is_32bit, &panicked, &panic_code); 348 349 sess->handle_scall = sess->ctx->ops->handle_scall; 350 thread_user_clear_vfp(uctx); 351 ldelf_sess_cleanup(sess); 352 353 if (panicked) { 354 uctx->ftrace_entry_func = 0; 355 EMSG("ldelf ftrace function panicked"); 356 abort_print_current_ts(); 357 res = TEE_ERROR_TARGET_DEAD; 358 } 359 360 if (!res) { 361 if (*arg > *blen) 362 res = TEE_ERROR_SHORT_BUFFER; 363 *blen = *arg; 364 } 365 366 return res; 367 } 368 #endif /*CFG_FTRACE_SUPPORT*/ 369 370 TEE_Result ldelf_dlopen(struct user_mode_ctx *uctx, TEE_UUID *uuid, 371 uint32_t flags) 372 { 373 uaddr_t usr_stack = uctx->ldelf_stack_ptr; 374 TEE_Result res = TEE_ERROR_GENERIC; 375 struct dl_entry_arg *usr_arg = NULL; 376 struct dl_entry_arg *arg = NULL; 377 uint32_t panic_code = 0; 378 uint32_t panicked = 0; 379 struct ts_session *sess = NULL; 380 381 assert(uuid); 382 383 arg = bb_alloc(sizeof(*arg)); 384 if (!arg) 385 return TEE_ERROR_OUT_OF_MEMORY; 386 387 memset(arg, 0, sizeof(*arg)); 388 arg->cmd = LDELF_DL_ENTRY_DLOPEN; 389 arg->dlopen.uuid = *uuid; 390 arg->dlopen.flags = flags; 391 392 usr_stack -= ROUNDUP(sizeof(*arg), STACK_ALIGNMENT); 393 usr_arg = (void *)usr_stack; 394 395 res = copy_to_user(usr_arg, arg, sizeof(*arg)); 396 if (res) 397 return res; 398 399 sess = ts_get_current_session(); 400 sess->handle_scall = scall_handle_ldelf; 401 402 res = thread_enter_user_mode(usr_stack, 0, 0, 0, 403 usr_stack, uctx->dl_entry_func, 404 is_32bit, &panicked, &panic_code); 405 406 sess->handle_scall = sess->ctx->ops->handle_scall; 407 ldelf_sess_cleanup(sess); 408 409 if (panicked) { 410 EMSG("ldelf dl_entry function panicked"); 411 abort_print_current_ts(); 412 res = TEE_ERROR_TARGET_DEAD; 413 } 414 if (!res) { 415 TEE_Result res2 = TEE_SUCCESS; 416 417 res2 = GET_USER_SCALAR(res, &usr_arg->ret); 418 if (res2) 419 res = res2; 420 } 421 422 return res; 423 } 424 425 TEE_Result ldelf_dlsym(struct user_mode_ctx *uctx, TEE_UUID *uuid, 426 const char *sym, size_t symlen, vaddr_t *val) 427 { 428 uaddr_t usr_stack = uctx->ldelf_stack_ptr; 429 TEE_Result res = TEE_ERROR_GENERIC; 430 struct dl_entry_arg *usr_arg = NULL; 431 struct dl_entry_arg *arg = NULL; 432 uint32_t panic_code = 0; 433 uint32_t panicked = 0; 434 struct ts_session *sess = NULL; 435 436 usr_stack -= ROUNDUP(sizeof(*arg) + symlen + 1, STACK_ALIGNMENT); 437 usr_arg = (void *)usr_stack; 438 arg = bb_alloc(sizeof(*arg)); 439 if (!arg) 440 return TEE_ERROR_OUT_OF_MEMORY; 441 memset(arg, 0, sizeof(*arg)); 442 arg->cmd = LDELF_DL_ENTRY_DLSYM; 443 arg->dlsym.uuid = *uuid; 444 res = copy_to_user(usr_arg, arg, sizeof(*arg)); 445 if (res) 446 return res; 447 res = copy_to_user(usr_arg->dlsym.symbol, sym, symlen + 1); 448 if (res) 449 return res; 450 451 sess = ts_get_current_session(); 452 sess->handle_scall = scall_handle_ldelf; 453 454 res = thread_enter_user_mode((vaddr_t)usr_arg, 0, 0, 0, 455 usr_stack, uctx->dl_entry_func, 456 is_32bit, &panicked, &panic_code); 457 458 sess->handle_scall = sess->ctx->ops->handle_scall; 459 ldelf_sess_cleanup(sess); 460 461 if (panicked) { 462 EMSG("ldelf dl_entry function panicked"); 463 abort_print_current_ts(); 464 res = TEE_ERROR_TARGET_DEAD; 465 } 466 if (!res) { 467 TEE_Result res2 = TEE_SUCCESS; 468 469 res2 = GET_USER_SCALAR(res, &usr_arg->ret); 470 if (res2) 471 res = res2; 472 if (!res) 473 res = GET_USER_SCALAR(*val, &usr_arg->dlsym.val); 474 } 475 476 return res; 477 } 478