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 124 usr_stack = uctx->ldelf_stack_ptr; 125 usr_stack -= ROUNDUP(sizeof(*arg), STACK_ALIGNMENT); 126 arg = (struct ldelf_arg *)usr_stack; 127 sess->handle_scall = scall_handle_ldelf; 128 129 res = clear_user(arg, sizeof(*arg)); 130 if (res) 131 return res; 132 133 res = PUT_USER_SCALAR(uctx->ts_ctx->uuid, &arg->uuid); 134 if (res) 135 return res; 136 137 res = thread_enter_user_mode((vaddr_t)arg, 0, 0, 0, 138 usr_stack, uctx->entry_func, 139 is_32bit, &panicked, &panic_code); 140 141 sess->handle_scall = sess->ctx->ops->handle_scall; 142 thread_user_clear_vfp(uctx); 143 ldelf_sess_cleanup(sess); 144 145 if (panicked) { 146 abort_print_current_ts(); 147 EMSG("ldelf panicked"); 148 return TEE_ERROR_GENERIC; 149 } 150 if (res) { 151 EMSG("ldelf failed with res: %#"PRIx32, res); 152 return res; 153 } 154 155 res = vm_check_access_rights(uctx, 156 TEE_MEMORY_ACCESS_READ | 157 TEE_MEMORY_ACCESS_ANY_OWNER, 158 (uaddr_t)arg, sizeof(*arg)); 159 if (res) 160 return res; 161 162 if (is_user_ta_ctx(uctx->ts_ctx)) { 163 /* 164 * This is already checked by the elf loader, but since it runs 165 * in user mode we're not trusting it entirely. 166 */ 167 if (arg->flags & ~TA_FLAGS_MASK) 168 return TEE_ERROR_BAD_FORMAT; 169 170 to_user_ta_ctx(uctx->ts_ctx)->ta_ctx.flags = arg->flags; 171 } 172 173 uctx->is_32bit = arg->is_32bit; 174 uctx->entry_func = arg->entry_func; 175 uctx->load_addr = arg->load_addr; 176 uctx->stack_ptr = arg->stack_ptr; 177 uctx->dump_entry_func = arg->dump_entry; 178 #ifdef CFG_FTRACE_SUPPORT 179 uctx->ftrace_entry_func = arg->ftrace_entry; 180 sess->fbuf = arg->fbuf; 181 #endif 182 uctx->dl_entry_func = arg->dl_entry; 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 *arg = NULL; 376 uint32_t panic_code = 0; 377 uint32_t panicked = 0; 378 struct ts_session *sess = NULL; 379 380 assert(uuid); 381 382 arg = bb_alloc(sizeof(*arg)); 383 if (!arg) 384 return TEE_ERROR_OUT_OF_MEMORY; 385 386 memset(arg, 0, sizeof(*arg)); 387 arg->cmd = LDELF_DL_ENTRY_DLOPEN; 388 arg->dlopen.uuid = *uuid; 389 arg->dlopen.flags = flags; 390 391 usr_stack -= ROUNDUP(sizeof(*arg), STACK_ALIGNMENT); 392 393 res = copy_to_user((void *)usr_stack, arg, sizeof(*arg)); 394 if (res) 395 return res; 396 397 sess = ts_get_current_session(); 398 sess->handle_scall = scall_handle_ldelf; 399 400 res = thread_enter_user_mode(usr_stack, 0, 0, 0, 401 usr_stack, uctx->dl_entry_func, 402 is_32bit, &panicked, &panic_code); 403 404 sess->handle_scall = sess->ctx->ops->handle_scall; 405 ldelf_sess_cleanup(sess); 406 407 if (panicked) { 408 EMSG("ldelf dl_entry function panicked"); 409 abort_print_current_ts(); 410 res = TEE_ERROR_TARGET_DEAD; 411 } 412 if (!res) 413 res = arg->ret; 414 415 return res; 416 } 417 418 TEE_Result ldelf_dlsym(struct user_mode_ctx *uctx, TEE_UUID *uuid, 419 const char *sym, size_t symlen, vaddr_t *val) 420 { 421 uaddr_t usr_stack = uctx->ldelf_stack_ptr; 422 TEE_Result res = TEE_ERROR_GENERIC; 423 struct dl_entry_arg *usr_arg = NULL; 424 struct dl_entry_arg *arg = NULL; 425 uint32_t panic_code = 0; 426 uint32_t panicked = 0; 427 struct ts_session *sess = NULL; 428 429 usr_stack -= ROUNDUP(sizeof(*arg) + symlen + 1, STACK_ALIGNMENT); 430 usr_arg = (void *)usr_stack; 431 arg = bb_alloc(sizeof(*arg)); 432 if (!arg) 433 return TEE_ERROR_OUT_OF_MEMORY; 434 memset(arg, 0, sizeof(*arg)); 435 arg->cmd = LDELF_DL_ENTRY_DLSYM; 436 arg->dlsym.uuid = *uuid; 437 res = copy_to_user(usr_arg, arg, sizeof(*arg)); 438 if (res) 439 return res; 440 res = copy_to_user(usr_arg->dlsym.symbol, sym, symlen + 1); 441 if (res) 442 return res; 443 444 sess = ts_get_current_session(); 445 sess->handle_scall = scall_handle_ldelf; 446 447 res = thread_enter_user_mode((vaddr_t)usr_arg, 0, 0, 0, 448 usr_stack, uctx->dl_entry_func, 449 is_32bit, &panicked, &panic_code); 450 451 sess->handle_scall = sess->ctx->ops->handle_scall; 452 ldelf_sess_cleanup(sess); 453 454 if (panicked) { 455 EMSG("ldelf dl_entry function panicked"); 456 abort_print_current_ts(); 457 res = TEE_ERROR_TARGET_DEAD; 458 } 459 if (!res) { 460 TEE_Result res2 = TEE_SUCCESS; 461 462 res2 = GET_USER_SCALAR(res, &usr_arg->ret); 463 if (res2) 464 res = res2; 465 if (!res) 466 res = GET_USER_SCALAR(*val, &usr_arg->dlsym.val); 467 } 468 469 return res; 470 } 471