Age | Commit message (Collapse) | Author |
|
Change is_user_ta_ctx() to support NULL context reference. For such
references the function now returns boolean value false. This allows
caller to nicely abort their sequence when the context reference
is already released from the session instance. Note that caller shall
not assume a context refer to a PTA when is_user_ta_ctx() return
false, it shall call is_pseudo_ta_ctx().
A side effect is that few test on reference and function return value
can be simplified.
This change also ensures TA dump_state() function does not crash when
called provides a null context reference.
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
|
|
Introduces CFG_CORE_RESERVED_SHM which if set to y enables reserved shared
memory, else disables support for reserved shared memory.
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Introduces CFG_CORE_DYN_SHM which if set to y enables dynamic shared
memory, else disables support for dynamic shared memory. In contrast
with CFG_DYN_SHM_CAP it actually removes the support instead of just
omit reporting it.
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Changes the default weak tee_otp_get_die_id() implementation to use
huk_subkey_derive() to derive a unique die ID based on the hardware
unique key.
Note that the SSK derivation retains backwards compatibility if
CFG_CORE_HUK_SUBKEY_COMPAT is set to 'y' and tee_otp_get_die_id() wasn't
replaced with a platform specific implementation.
Reviewed-by: Joakim Bech <joakim.bech@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
mutex::owner_id was used for debugging purposes only.
Since commit 8aff6c039ee5 ("core: remove thread_{add,rem}_mutex()"), it is
never set to a valid thread ID anymore. Let's just remove the field.
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
If any error is encountered when the TEE core attempts to load a TA from
TA storage, the next storage is tried and so on until the TA is
successfully loaded or there is no more storage to try. In this case, a
generic error code (TEE_ERROR_ITEM_NOT_FOUND) is returned to the caller
of load_elf() and ultimately to the client. This is not super useful,
especially when debug traces are disabled, because the user has no way
to differentiate a true "not found" situation (which might be a
configuration or deployement issue) from an issue with the TA file
itself or an out-of-memory condition etc.
This commit changes the return code of load_elf() to better reflect the
errors. When load_elf_from_store() returns TEE_ERROR_ITEM_NOT_FOUND or
TEE_ERROR_STORAGE_NOT_AVAILABLE, the next storage is tried.
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
|
|
When OP-TEE is build with CFG_WITH_LPAE=y, the things stored in the
.nozi section do not need to be aligned on more than 4 KiB. Only the
non-LPAE case requires 16 KiB alignment for the L1 page table.
Use an #ifdef to minimize the extra space between .heap1 and .nozi,
thus making the heap size closer to what is requested by
CFG_CORE_HEAP_SIZE. This can be useful when trying to minimize the
size of the TEE core binary, which could otherwise be bigger than
necessary by as much as 12 KiB.
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Symbols defined inside output sections are relative to the section
start. Therefore, when we want to check the actual address, we need
to apply the ABSOLUTE() builtin function to the symbol.
Note that symbols defined outside output sections are absolute by
default, and therefore need not be treated the same.
kern.ld.S has two incorrect assertions which can never fail, because
the value that is checked is in fact 0 (since we are at the beginning
of a section in both cases).
Fix the code by adding the missing ABSOLUTE().
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Links tee.elf with the library archives instead of -llibname in order to
detect multiply defined symbols in several libraries.
Acked-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Introduces CFG_TA_ASLR to enable Address Space Layout Randomization of
Trusted Applications. ASLR makes the exploitation of memory corruption
vulnerabilities harder.
The feature is disabled by default except for the configurations I
could test (QEMU and HiKey960).
When CFG_TA_ASLR=y, the stack and subsequent ELF file(s) needed by the
TA are mapped into the user VA space with a random offset comprised
between CFG_TA_ASLR_MIN_OFFSET_PAGES and CFG_TA_ASLR_MAX_OFFSET_PAGES
pages (that is between 0 and 128 pages by default).
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (QEMU, HiKey960)
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Improve the layout of the TA dump message by using fixed width for
physical and virtual addresses: 0x + 8 or 16 characters, depending on
the address size (32 or 64 bits). This makes the output more
consistent, more readable, and nicer overall.
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Aside from reserving the shared memory, also reserve the TZDRAM OP-TEE
memory.
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
|
|
If the reserved-memory subnode does not exist, retrieve address-cells
and size-cells from the root node.
The linux kernel checks whether these properties match between the root
and reserved-memory nodes and discards non-matching nodes.
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
|
|
Rename the shared reserved memory node from "optee" to "optee_shm".
This should avoid confusion when we introduce the "optee_core" reserved
memory node in later commits.
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Rouven Czerwinski <r.czerwinski@pengutronix.de>
|
|
With the introduction of shared libutee/libutils/libmbedtls etc., it
is not uncommon for a TA to have more than 10 memory regions. When this
happens, the crash dump output is not properly aligned.
Similarly, since there is no width specifier when we print the region
size, misalignments can occur.
This commit makes the output look good for up to 100 regions of up to
16 MiB in size.
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
|
|
The symbol referenced by a R_ARM_ABS32 or R_AARCH64_ABS64 relocation
may very well be external to the binary being relocated (for example,
defined in a shared library). In this case, the section table index for
the symbol is SHN_UNDEF and we need to perform process-wide symbol
resolution.
This fixes an issue I found when linking a TA against a shared version
of libutee (this configuration is introduced in a later commit). In this
case, ta_head::entry is set to __utee_entry which is in libutee.so,
hence undefined in the TA binary.
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Remove useless newline character in few generic debug traces.
Remove argument __func__ from a FMSG trace since already
output by macro FMSG().
Remove error trace from syscall_storage_obj_read() that, prior
this change, output failing error code from storage read()
handler. This is useless and not done for other storage handlers
return code.
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
|
|
Use IMSG() traces when external and embedded DTB are tested.
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
|
|
Change trace message indicating absence of external DTB
from error level to debug level. Implementation and comment
clearly state the configuration is fully legitimate.
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
|
|
Make inline comments and trace messages more consistent by
using PTA as acronym for pseudo TA, rather than using pTA, PTA
and pta at various places.
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Adds configuration flag CFG_REE_FS_TA_BUFFERED, default enabled.
A new TA store is introduced which depends on the TEE FS TA store to
load the whole binary into a temporary buffer in secure DDR and
authenticate it before being processed further.
This reduces the attack surface of the TEE core in case of a
vulnerability in the ELF loader, at the expense of increased memory
usage at load time.
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reported-by: Bastien Simondi <bsimondi@netflix.com> [3.6]
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
|
|
get_elf_segments() final stage aggregates ELF segments. In the while
loop, the logic to remove the current index is to use memcpy() to shift
down everything beyond that point. This is incorrect; memmove() should
be used instead.
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reported-by: Bastien Simondi <bsimondi@netflix.com> [2.8]
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Joakim Bech <joakim.bech@linaro.org>
|
|
Inside load_elf_from_store(), the ta_head structure is retrieved from
un-authenticated area, and contains the stack size. The stack size could
either already be 0, or could be large enough so it becomes 0 when rounded
up to STACK_ALIGNMENT. This could result in vm_map() returning a virtual
address for a 0-size memory block or other issues.
Check the rounded-up stack_size value before using it.
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reported-by: Bastien Simondi <bsimondi@netflix.com> [2.7]
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Joakim Bech <joakim.bech@linaro.org>
|
|
The ELF relocation functions e32_process_rel() and e64_process_rel()
can experience integer overflows which could result in invalid memory
access. Use ADD_OVERFLOW() to prevent these.
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reported-by: Bastien Simondi <bsimondi@netflix.com> [1.8]
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
At the end of elf_load_body(), section headers are copied in a system heap
memory block, associated to state->shdr. As the computed size is the
result of an uncontrolled multiplication (ehdr.e_shnum * ehdr.e_shentsize),
it could have overflowed and result in allocating a small memory block.
Use an overflow checking macro to prevent this case.
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reported-by: Bastien Simondi <bsimondi@netflix.com> [1.7]
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Joakim Bech <joakim.bech@linaro.org>
|
|
Accepts query buffer size when invoking pseudo TAs with
CFG_SECURE_DATA_PATH=y.
Acked-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Don't create boot thread and don't initialize TEE runtime
if virtualization is enabled. This will be done by virtualization
framework for each virtual guest separately.
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
This one function can be called in init_primary_helper() in default
configuration or by virtualization framework for each virtual guest
separately if virtualization is enabled.
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
If virtualization support is enabled, malloc memory pool is not initialized
at this stage. When virtualization is disabled, nex_malloc and nex_calloc
are aliases for malloc/calloc so no problem will be there.
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
If virtualization is enabled, we need do configure right context
upon entry from SMCs. Also we need to switch back to default context
when leaving OP-TEE.
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
This patch adds virtualization framework to OP-TEE.
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Virtualization subsystem will initialize threads every time new
guest context is created, so it is good to have whole thread
initialization in one function.
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Variables that are needed by OP-TEE nexus will be moved
to nexus memory.
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
Acked-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
This patch is the first in series of patches that split OP-TEE RW memory
into two regions: nexus memory and TEE memory. Nexus memory will
be always mapped and it will be used to store all data that is
vital for OP-TEE core and is not bound to virtual guests.
TEE memory is a memory that holds data specific for certain guest.
There will be TEE memory bank for every guest and it will be mapped
into OP-TEE address space only during call from that guest.
This patch adds nexus memory and moves stacks into it. Also
it provides __nex_bss and __nex_data macros, so one can easily set right
section for a variable.
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
If virtualization enabled, this pool will be used to allocate
memory for OP-TEE nexus needs.
Without virtualization, generic malloc pool will be used.
Signed-off-by: Volodymyr Babchuk <vlad.babchuk@gmail.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
get_elf_segments() doesn't initialize the returned segs array properly,
some fields are left uninitialized. Fix this by doing a compound
assignment when initializing new elements in the array.
Reviewed-by: Joakim Bech <joakim.bech@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
In error condition on checking "ta_size", was returning
error from function without cleaning allocated memory.
Signed-off-by: Sahil Malhotra <sahil.malhotra@nxp.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Fixes: https://github.com/OP-TEE/optee_os/pull/2776
[jf: minor edits to commit message]
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
|
|
Fixes a race where FIQ isn't masked in the abort handler which results
lost register content and invalid processing of the abort when resumed.
Fixes: 18901324e00a ("Support ARM GICv3 mode")
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
When the TEE is about to load a TA it first asks the REE for the size of
the TA in question. Next it allocates memory for this based on the size
in the previous query. However, there is no guarantee that the REE
actually allocates the requested size. A compromised REE could for
example modify the RPC request. This means that even though an
allocation is successful, we still need to check that the size of the
allocated buffer has room to fit the entire TA we are about to load.
Fixes: "REE provided size not checked when loading TAs" as reported by
Riscure.
Signed-off-by: Joakim Bech <joakim.bech@linaro.org>
Tested-by: Joakim Bech <joakim.bech@linaro.org> (QEMU v7, v8)
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reported-by: Riscure <inforequest@riscure.com>
Reported-by: Alyssa Milburn <a.a.milburn@vu.nl>
Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
|
|
If tee_tadb_ta_read(..) is successful in secstor_ta_open(..), then we
must set an error code manually if the size check right after fails.
Fixes: "Loading from secure storage returns success with uninitialized
pointer" as reported by Riscure.
Signed-off-by: Joakim Bech <joakim.bech@linaro.org>
Tested-by: Joakim Bech <joakim.bech@linaro.org> (QEMU v7, v8)
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reported-by: Riscure <inforequest@riscure.com>
Reported-by: Alyssa Milburn <a.a.milburn@vu.nl>
Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
|
|
Previously we cleared (memset to zero) the size corresponding to code
and data segments, however the allocation for the TA is made on the
granularity of the memory pool, meaning that we did not clear all memory
and because of that we could potentially leak code and data of a
previous loaded TA.
Fixes: OP-TEE-2018-0006: "Potential disclosure of previously loaded TA
code and data"
Signed-off-by: Joakim Bech <joakim.bech@linaro.org>
Tested-by: Joakim Bech <joakim.bech@linaro.org> (QEMU v7, v8)
Suggested-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Reported-by: Riscure <inforequest@riscure.com>
Reported-by: Alyssa Milburn <a.a.milburn@vu.nl>
Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
|
|
GlobalPlatform spec allows null memory reference parameters as valid.
So update copy_in_params for pseudo_ta accordingly.
Also add check for mobj ptr being NULL before dereference as it causes
a data abort in case REE has passed NULL buffer ptr with size > 0 as
memref param.
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
The two symbols thread_excp_vect and thread_excp_vect_end are used to
mark the part of the privileged code that still to be mapped in order to
transition between user mode and privileged mode when compiled with
CFG_CORE_UNMAP_CORE_AT_EL0=y.
Prior to this patch it was assumed that thread_excp_vect_end would mark
the end of the thread_excp_vect() assembly function including literals
emitted by the assembler. This assumption was wrong and an extra .pool
directive is added before the thread_excp_vect_end to guarantee that all
literals will be included in the section starting with thread_excp_vect
and ending with thread_excp_vect_end.
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (HiKey960)
Reported-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Introduce timeout_init_us/timeout_elapsed() delay tracking with CNTPCT.
timeout_init_us(some_timeout_us); returns a reference to detect
timeout for the provided microsecond delay value from current time.
timeout_elapsed(reference) return true/false whether the reference
timeout is elapsed.
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
As an implementation of generic timer, arm64 platforms provides secure
EL1 physical timer. So enable corresponding framework. For more
information refer to section: D6.1.5 Timers - ARMv8-A RM.
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Acked-by: Joakim Bech <joakim.bech@linaro.org>
|
|
Prior to this patch the non-secure VFP state was only saved when it
seemed necessary based on control registers.
To make sure that non-secure VFP state isn't corrupted always save the
entire register file before modifying it. This is now the same behavior
on both ARMv8-A and ARMv7-A platforms.
Acked-by: Jerome Forissier <jerome.forissier@linaro.org>
Acked-by: Etienne Carriere <etienne.carriere@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
__thread_enter_user_mode() cannot be paged out, because the pager cannot
be invoked to restore any faulting code page after SP has been switched to
use SP_EL1. At this point, a synchronous exception would take the CPU to
the 0x200 offset in the exception vector, which corresponds to
[workaround_]el1_sync_sp1 and is an error-catching infinite loop. This
explains the behavior described in [1].
Add the requisite KEEP_PAGER so that the function is kept in the unpaged
area.
Fixes: [1] https://github.com/OP-TEE/optee_os/issues/2684
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Joakim Bech <joakim.bech@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
|
|
Introduce get_external_dt() as opposed to get_embedded_dt().
Change get_dt() to return embedded DTB location and falls back
to external DTB location.
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
|
|
get_embedded_dt() returns the location (virtual address) of the
embedded DTB or NULL if there is no embedded DTB.
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
|
|
When core updates the external DTB with OP-TEE node resources
it may load memory address ranges node that depend of information
read from the DTB. This change ensures non-secure memory is
discovered (possibly from the external DTB) before core modifies
the external DTB for a former boot stage.
Suggested-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
|