mirror of
https://github.com/espressif/esp-idf.git
synced 2026-05-30 09:36:36 +03:00
- Also fixed an issue where NewLib ROM APIs, when called from TEE, were using the syscall table located in the REE SRAM. This could be abused as an attack vector to invoke illegal functions from the TEE. To prevent this, the syscall table is now switched to the TEE-specific copy during every M-U mode transition.
287 lines
4.8 KiB
C
287 lines
4.8 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <errno.h>
|
|
#include <pthread.h>
|
|
#include <unistd.h>
|
|
|
|
#include "soc/soc_caps.h"
|
|
#include "rom/libc_stubs.h"
|
|
|
|
#include "esp_attr.h"
|
|
#include "esp_cpu.h"
|
|
#include "esp_random.h"
|
|
|
|
#include "sdkconfig.h"
|
|
|
|
#if CONFIG_LIBC_NEWLIB
|
|
// NOTE: Remove compile-time warnings for the below newlib-provided functions
|
|
struct _reent *__getreent(void)
|
|
{
|
|
return _GLOBAL_REENT;
|
|
}
|
|
|
|
int _fstat_r(struct _reent *r, int fd, struct stat *st)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int _close_r(struct _reent *r, int fd)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
off_t _lseek_r(struct _reent *r, int fd, off_t offset, int whence)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
ssize_t _read_r(struct _reent *r, int fd, void *ptr, size_t len)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
ssize_t _write_r(struct _reent *r, int fd, const void *ptr, size_t len)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
ssize_t _open_r(struct _reent *r, const char *path, int flags, int mode)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int _getpid_r(struct _reent *r)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
int _kill_r(struct _reent *r, int pid, int sig)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int _getentropy_r(struct _reent *r, void *buffer, size_t length)
|
|
{
|
|
esp_fill_random(buffer, length);
|
|
return 0;
|
|
}
|
|
|
|
struct syscall_stub_table *syscall_table_ptr;
|
|
static struct syscall_stub_table *syscall_table_ptr_ree;
|
|
|
|
static struct syscall_stub_table s_stub_table_tee = {
|
|
.__getreent = &__getreent,
|
|
};
|
|
|
|
void IRAM_ATTR syscall_enter_tee(void)
|
|
{
|
|
if (syscall_table_ptr) {
|
|
syscall_table_ptr_ree = syscall_table_ptr;
|
|
syscall_table_ptr = &s_stub_table_tee;
|
|
}
|
|
}
|
|
|
|
void IRAM_ATTR syscall_exit_tee(void)
|
|
{
|
|
if (syscall_table_ptr_ree) {
|
|
syscall_table_ptr = syscall_table_ptr_ree;
|
|
syscall_table_ptr_ree = NULL;
|
|
}
|
|
}
|
|
#else
|
|
/*
|
|
* Picolibc does not initialize 'errno' and places it in the TBSS section.
|
|
*
|
|
* To allow convenient initialization and support interoperability with Newlib,
|
|
* 'errno' is defined in the TDATA section. The linker script ensures that
|
|
* it is positioned at the beginning of the TDATA segment.
|
|
*/
|
|
__thread int errno __attribute__((section(".tdata.errno"))) = 0;
|
|
|
|
int *__errno(void)
|
|
{
|
|
return &errno;
|
|
}
|
|
|
|
int fstat(int fd, struct stat *st)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int close(int fd)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
off_t lseek(int fd, off_t offset, int whence)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
ssize_t read(int fd, void *ptr, size_t len)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
ssize_t write(int fd, const void *ptr, size_t len)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int getpid(void)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
int kill(int pid, int sig)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int getentropy(void *buffer, size_t length)
|
|
{
|
|
esp_fill_random(buffer, length);
|
|
return 0;
|
|
}
|
|
|
|
int open(const char *path, int flags, ...)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int rename(const char *src, const char *dst)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int unlink(const char *path)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
extern uint32_t _tee_tdata_start;
|
|
static void *s_tp_ree[SOC_CPU_CORES_NUM];
|
|
|
|
void IRAM_ATTR syscall_enter_tee(void)
|
|
{
|
|
int core_id = esp_cpu_get_core_id();
|
|
s_tp_ree[core_id] = esp_cpu_get_threadptr();
|
|
esp_cpu_set_threadptr(&_tee_tdata_start);
|
|
}
|
|
|
|
void IRAM_ATTR syscall_exit_tee(void)
|
|
{
|
|
int core_id = esp_cpu_get_core_id();
|
|
esp_cpu_set_threadptr(s_tp_ree[core_id]);
|
|
}
|
|
#endif // CONFIG_LIBC_NEWLIB
|
|
|
|
void *pthread_getspecific(pthread_key_t key)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
int pthread_setspecific(pthread_key_t key, const void *value)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*))
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int pthread_key_delete(pthread_key_t key)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int pthread_mutex_destroy(pthread_mutex_t *mutex)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int pthread_mutex_lock(pthread_mutex_t *mutex)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int pthread_mutex_unlock(pthread_mutex_t *mutex)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
void *__cxa_get_globals(void)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
void *__cxa_get_globals_fast(void)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
int __cxa_thread_atexit(void (*func)(void *), void *arg, void *dso)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void *_sbrk(ptrdiff_t incr)
|
|
{
|
|
return (void *) -1;
|
|
}
|
|
|
|
void esp_tee_include_syscalls_impl(void)
|
|
{
|
|
|
|
}
|
|
|
|
int _unlink_r(struct _reent *r, const char *path)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|
|
|
|
int _rename_r(struct _reent *r, const char *src, const char *dst)
|
|
{
|
|
errno = ENOSYS;
|
|
return -1;
|
|
}
|