From d23267a3f088cedb9c38f8855c7eef36f62b58c9 Mon Sep 17 00:00:00 2001 From: Gregory Guche Date: Thu, 2 Oct 2025 16:25:05 +0200 Subject: [PATCH 01/12] pkg/xipfs: add MPU memory isolation to file execution --- cpu/cortexm_common/include/cpu_conf_common.h | 6 +- cpu/cortexm_common/thread_arch.c | 27 +++++ cpu/cortexm_common/vectors_cortexm.c | 17 +++ examples/advanced/xipfs/Makefile | 6 + examples/advanced/xipfs/Makefile.ci | 25 +--- examples/advanced/xipfs/dumper.fae | Bin 0 -> 1920 bytes examples/advanced/xipfs/hello-world.fae | Bin 1056 -> 1376 bytes examples/advanced/xipfs/main.c | 121 ++++++++----------- pkg/xipfs/Makefile | 4 +- pkg/xipfs/doc.txt | 11 +- pkg/xipfs/fs/xipfs_fs.c | 32 ++++- sys/include/fs/xipfs_fs.h | 16 ++- sys/shell/cmds/xipfs.c | 33 +++-- 13 files changed, 186 insertions(+), 112 deletions(-) create mode 100644 examples/advanced/xipfs/dumper.fae diff --git a/cpu/cortexm_common/include/cpu_conf_common.h b/cpu/cortexm_common/include/cpu_conf_common.h index 8dec4e101db7..1449c6bab8e1 100644 --- a/cpu/cortexm_common/include/cpu_conf_common.h +++ b/cpu/cortexm_common/include/cpu_conf_common.h @@ -49,7 +49,11 @@ extern "C" { * @{ */ #ifndef ISR_STACKSIZE -#define ISR_STACKSIZE (512U) +# if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) +# define ISR_STACKSIZE (1024U) +#else +# define ISR_STACKSIZE (512U) +# endif #endif /** @} */ diff --git a/cpu/cortexm_common/thread_arch.c b/cpu/cortexm_common/thread_arch.c index 1e7a31095d41..e6592e26fdfc 100644 --- a/cpu/cortexm_common/thread_arch.c +++ b/cpu/cortexm_common/thread_arch.c @@ -97,6 +97,10 @@ #define ENABLE_DEBUG 0 #include "debug.h" +#if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) +#include "include/xipfs.h" +#endif + extern uint32_t _estack; extern uint32_t _sstack; @@ -274,6 +278,11 @@ void *thread_isr_stack_start(void) return (void *)&_sstack; } +void *thread_isr_stack_end(void) +{ + return (void *)&_estack; +} + void NORETURN cpu_switch_context_exit(void) { #ifdef MODULE_CORTEXM_FPU @@ -488,6 +497,11 @@ void __attribute__((naked)) __attribute__((used)) isr_svc(void) #endif } +#if (defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)) && \ + defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) +#undef XIPFS_ENABLE_SAFE_EXEC_SUPPORT +#endif + static void __attribute__((used)) _svc_dispatch(unsigned int *svc_args) { /* stack frame: @@ -513,6 +527,19 @@ static void __attribute__((used)) _svc_dispatch(unsigned int *svc_args) case 1: /* SVC number used by cpu_switch_context_exit */ SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; break; +#if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) + case XIPFS_ENTER_SVC_NUMBER: { + void *crt0_ctx = (void *)svc_args[0]; + void *entry_point = (void *)svc_args[1]; + void *stack_top = (void *)svc_args[2]; + xipfs_safe_exec_enter(crt0_ctx, entry_point, stack_top); + break; + } + case XIPFS_SYSCALL_SVC_NUMBER: { + xipfs_syscall_dispatcher(svc_args); + break; + } +#endif default: DEBUG("svc: unhandled SVC #%u\n", svc_number); break; diff --git a/cpu/cortexm_common/vectors_cortexm.c b/cpu/cortexm_common/vectors_cortexm.c index 2627815b5da5..704ac9514ce4 100644 --- a/cpu/cortexm_common/vectors_cortexm.c +++ b/cpu/cortexm_common/vectors_cortexm.c @@ -37,6 +37,9 @@ #ifdef MODULE_DBGPIN #include "dbgpin.h" #endif +#if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) +#include "include/xipfs.h" +#endif #ifndef SRAM_BASE #define SRAM_BASE 0 @@ -472,8 +475,22 @@ void hard_fault_default(void) #if defined(CPU_CORE_CORTEX_M3) || defined(CPU_CORE_CORTEX_M33) || \ defined(CPU_CORE_CORTEX_M4) || defined(CPU_CORE_CORTEX_M4F) || \ defined(CPU_CORE_CORTEX_M7) + +#if (defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)) && \ + defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) +#undef XIPFS_ENABLE_SAFE_EXEC_SUPPORT +#endif + void mem_manage_default(void) { +# if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) + uint32_t mmfar = SCB->MMFAR; + uint32_t cfsr = SCB->CFSR; + uintptr_t psp = __get_PSP(); + if (xipfs_mem_manage_handler((void *)psp, mmfar, cfsr) == 0) { + return; + } +# endif core_panic(PANIC_MEM_MANAGE, "MEM MANAGE HANDLER"); } diff --git a/examples/advanced/xipfs/Makefile b/examples/advanced/xipfs/Makefile index c380a3621523..79d1230d0616 100644 --- a/examples/advanced/xipfs/Makefile +++ b/examples/advanced/xipfs/Makefile @@ -19,14 +19,20 @@ QUIET ?= 1 TOOLCHAINS_BLACKLIST += llvm BLOBS += hello-world.fae +BLOBS += dumper.fae # Modules to include: USEMODULE += shell USEMODULE += shell_cmds_default USEMODULE += ps USEMODULE += saul_default +USEMODULE += cortexm_svc + +FEATURES_REQUIRED += cortexm_mpu # Use xipfs file system USEMODULE += xipfs +CFLAGS += -DXIPFS_ENABLE_SAFE_EXEC_SUPPORT + include $(RIOTBASE)/Makefile.include diff --git a/examples/advanced/xipfs/Makefile.ci b/examples/advanced/xipfs/Makefile.ci index 586cb3252a4c..612731aebd6e 100644 --- a/examples/advanced/xipfs/Makefile.ci +++ b/examples/advanced/xipfs/Makefile.ci @@ -1,24 +1,5 @@ BOARD_INSUFFICIENT_MEMORY := \ - blackpill-stm32f103c8 \ - bluepill-stm32f030c8 \ - bluepill-stm32f103c8 \ - i-nucleo-lrwan1 \ - nucleo-c031c6 \ - nucleo-f030r8 \ - nucleo-f031k6 \ - nucleo-f042k6 \ - nucleo-f302r8 \ - nucleo-f303k8 \ - nucleo-f334r8 \ - nucleo-l011k4 \ - nucleo-l031k6 \ - nucleo-l053r8 \ - samd10-xmini \ - slstk3400a \ - stk3200 \ - stm32f030f4-demo \ - stm32f0discovery \ - stm32g0316-disco \ - stm32l0538-disco \ - weact-g030f6 \ + e104-bt5010a-tb \ + e104-bt5011a-tb \ + im880b \ # diff --git a/examples/advanced/xipfs/dumper.fae b/examples/advanced/xipfs/dumper.fae new file mode 100644 index 0000000000000000000000000000000000000000..5a35128e2b18194de18749eeb38bb174a9dadc99 GIT binary patch literal 1920 zcmb7^e{2(F7{}lD?)qcx#%>I;YmvQMTdZuIbpt|NL*}(yi6t5E$0EPt#^`9t)@$~I zG=hfcKPJQk7$)>?MrFikh-Nb^P-J2dh~g49r%92Bh|$|1F~NUx%QW~`MT4b!eV>8K3w9sD~3}~3O_8OF}QPlh6 zBy#rI7{w?%g9WfwkW!+30&^Ri*-T2nnZR1+TMT}mQiD>yYMEAU{E~9}uQxMFh3FBv zUQT(o>gmi9(NtZP;S{d#npx6J4D%NoV5_*R8z@)x0>IUmer6Yqsg&T#AQx8pA(|EB zUiy?7x;P=M$ruzQTl;L{VUdJp)Pae=Uw$9p6kq*_s!cG?p8>P~85cs?xK56&gFn7IF(Qqt_vs!S1Y*wpd#0O;13m@yTBk+a{cn3jM%7gsCa4(KJoeN zorPs@pJxOOGkmCc%8Q}G>Efw+h!%(eh(?GTAul%leER! zBVllsHt!CpC%&_bNNsIhk!}lWZHeoNoso8_ zwWT|fU+*HZIH~EBK=!zVT@qA4`%Ne}ypuG*iRey)>8$XcXd3s1E5t37MZ*&`fV8hp zFVD}BcAk2|uyb&kh}?@QcHoukM5LXfW-lH+CEU+chTFYZwt&gm%(+K+NfoHnu^KqD&ygYjH6|FM?b}cA6_3_44uMB`0Vsp z)|M{K?V4^ZoLjw=C28xr?DYC9BEP9cbL(fa=Cn1es@A!c!7TDz8JpD4L0r(Q2k-;c zfDdQ@Rsh8(yM~M(6@@oaE{qR>x6hv3F^Jsw6OULS){5*;TcfrpGcY`nXy67CAtg#g zNAze2{>$f9gWjn32%3dyB?_4#T*>D(iIBd}pUgc~Us;k7D`6{667A4c;_Oz)H!SnPnV09fO600Pt|tW)jhb-NI; zq?*K~xc8xH{#JT)N9uT$=%1p8QXig49pHZ&Uf*-TCEz0PH828P0mgvufDEt{UPwDo e4S0Yz^FWD5M)qGre|I+kt07+>9Z>7RclaMe{-J~b literal 0 HcmV?d00001 diff --git a/examples/advanced/xipfs/hello-world.fae b/examples/advanced/xipfs/hello-world.fae index 5a92a6aa13d247e6341367617342fdafbdc8f4fd..730bca5a459dabfe03bf45119b0c7eaa389a2d1e 100644 GIT binary patch delta 611 zcmZ3$@qlZ?7e+?G$zK`IGbON2KE`BIU%ZuVC9ikj4;F96iBUh84WufPHZrI(uG4T+ zbTe{ez8{?-k-@ZK?~4KlmJJ2&vojRjq%&r?e|^rdpM!ycfz2DDM`-8l44_JPMkN8L zo&tA}yucPNunNfvCO1W(npmJcvw`ZER219njr zcaz?^IOD^f+dwV;ADDR(+%$oXvIc5Q28x1o;j%d|YEwB#?z{cZq)NG&*{|{_99EEHN%#PbY9qg!f)D!TzbQZ`G4jh&U zY!&oku8aD?9(l=V^#A*}e@Ye1Zb2LUKX5Wg0zLNc z`Gp?}ijNX5{7_MR_55)LD=0R0-mgz~BYM89b$zK`IGbyl4KE`BI&%Tx2JL(6s0n1A1jKCi(+|n706KA+HZ;1WD z@|tBsfjh%~4h9AWCa@amjOYvrcVzx-H2!TgzH}z4`e-!%?0PhT+h~00EQkRDTRA~a zaJcY8!ZbO7;cIi^ge7k-GaC@1{?-t<2?Lpo!I`@iQP$9bgY?N9e;@#9k^o{EsN`KB`v?;QgTTF0zW`S help - * 2025-01-14 09:48:42,300 # help - * 2025-01-14 09:48:42,302 # Command Description - * 2025-01-14 09:48:42,305 # --------------------------------------- - * 2025-01-14 09:48:42,309 # exec Execute Hello World - * 2025-01-14 09:48:42,314 # create_executable Create an XIPFS executable file - * 2025-01-14 09:48:42,317 # execute Execute an XIPFS file - * 2025-01-14 09:48:42,320 # ls list files - * 2025-01-14 09:48:42,325 # pm interact with layered PM subsystem - * 2025-01-14 09:48:42,331 # ps Prints information about running threads. - * 2025-01-14 09:48:42,334 # reboot Reboot the node - * 2025-01-14 09:48:42,338 # version Prints current RIOT_VERSION - * 2025-01-14 09:48:42,343 # vfs virtual file system operations - * > exec - * 2025-01-14 09:48:49,572 # exec - * 2025-01-14 09:48:49,573 # Hello World! - * > ls /dev/nvme0p0 - * 2025-01-14 09:48:59,997 # ls /dev/nvme0p0 - * 2025-01-14 09:48:59,999 # hello-world.fae 896 B - * 2025-01-14 09:49:00,000 # total 1 files - * > vfs df - * 2025-01-14 09:49:04,957 # vfs df - * 2025-01-14 09:49:04,962 # Mountpoint Total Used Available Use% - * 2025-01-14 09:49:04,968 # /dev/nvme0p0 40 KiB 4 KiB 36 KiB 10% - * 2025-01-14 09:49:04,974 # /dev/nvme0p1 60 KiB 0 B 60 KiB 0% - * execute /dev/nvme0p0/hello-world.fae ipsum dolores it - * 2025-01-14 09:49:14,223 # execute /dev/nvme0p0/hello-world.fae Lorem ipsum dolor sit amet - * 2025-01-14 09:49:14,225 # Hello World! - * 2025-01-14 09:49:14,225 # Lorem - * 2025-01-14 09:49:14,226 # ipsum - * 2025-01-14 09:49:14,226 # dolor - * 2025-01-14 09:49:14,227 # sit - * 2025-01-14 09:49:14,227 # amet - * ``` - */ -int execution_handler(int argc, char **argv) { - (void)argc; - (void)argv; +#include "blob/dumper.fae.h" + +#define FILENAME_OF_DUMPER_FAE "/nvme0p0/dumper.fae" +#define SIZEOF_DUMPER_FAE (sizeof(dumper_fae) / sizeof(dumper_fae[0])) + +typedef struct { + const char *filename; + const int bytesize; + const unsigned char *data; + const bool is_executable; +} file_to_drop_t; - int file_handle = vfs_open(FILENAME_OF_HELLO_WORLD_FAE, O_RDONLY, 0); +static const file_to_drop_t files_to_drop[2] = { + {FILENAME_OF_HELLO_WORLD_FAE, SIZEOF_HELLO_WORLD_FAE, hello_world_fae, true }, + {FILENAME_OF_DUMPER_FAE, SIZEOF_DUMPER_FAE, dumper_fae, true }, +}; + +static int drop_file(const file_to_drop_t *file_to_drop) { + if (file_to_drop == NULL) + return EXIT_FAILURE; + + int file_handle = vfs_open(file_to_drop->filename, O_RDONLY, 0); if (file_handle < 0) { /** There's no executable file yet, let's drop one */ int ret = xipfs_extended_driver_new_file( - FILENAME_OF_HELLO_WORLD_FAE, SIZEOF_HELLO_WORLD_FAE, 1 + file_to_drop->filename, file_to_drop->bytesize, file_to_drop->is_executable ); if (ret < 0) { printf("xipfs_extended_driver_new_file : failed to create '%s' : error=%d\n", - FILENAME_OF_HELLO_WORLD_FAE, ret); + file_to_drop->filename, ret); return EXIT_FAILURE; } /** - * Fill it with blob data + * Fill it with data * Take care : vfs does not support O_APPEND with vfs_write, only O_WRONLY or O_RDWR */ - file_handle = vfs_open(FILENAME_OF_HELLO_WORLD_FAE, O_WRONLY, 0); + file_handle = vfs_open(file_to_drop->filename, O_WRONLY, 0); if (file_handle < 0) { printf("vfs_open : failed to open '%s' : error =%d\n", - FILENAME_OF_HELLO_WORLD_FAE, file_handle); + file_to_drop->filename, file_handle); return EXIT_FAILURE; } - ssize_t write_ret = vfs_write(file_handle, hello_world_fae, SIZEOF_HELLO_WORLD_FAE); + ssize_t write_ret = vfs_write(file_handle, file_to_drop->data, file_to_drop->bytesize); if (write_ret < 0) { printf("vfs_write : failed to fill '%s' : error=%d\n", - FILENAME_OF_HELLO_WORLD_FAE, write_ret); + file_to_drop->filename, write_ret); vfs_close(file_handle); return EXIT_FAILURE; } } vfs_close(file_handle); + return EXIT_SUCCESS; +} - char *exec_argv[] = { - FILENAME_OF_HELLO_WORLD_FAE, - NULL - }; +/** + * @brief Execution in-place demonstrator. + * + * This shell command handler will create a file hello-world.fae on /dev/nvme0p0, + * if none exists yet from the files_to_drop array. + * + */ +int drop_files_handler(int argc, char **argv) { + (void)argc; + (void)argv; - int ret = xipfs_extended_driver_execv(FILENAME_OF_HELLO_WORLD_FAE, exec_argv); - if (ret < 0) { - printf("Failed to execute '%s' : error=%d\n", FILENAME_OF_HELLO_WORLD_FAE, ret); - return EXIT_FAILURE; + for(unsigned int i = 0; i < sizeof(files_to_drop)/sizeof(files_to_drop[0]); ++i) { + if (drop_file(&files_to_drop[i]) != EXIT_SUCCESS) + return EXIT_FAILURE; } return EXIT_SUCCESS; } static shell_command_t shell_commands[] = { - {"exec", "Execute Hello World", execution_handler}, + {"drop_files", "Drop example fae files into /nvme0p0", drop_files_handler}, {NULL, NULL, NULL}, }; diff --git a/pkg/xipfs/Makefile b/pkg/xipfs/Makefile index 2908e1733d2c..5d7cedd24494 100644 --- a/pkg/xipfs/Makefile +++ b/pkg/xipfs/Makefile @@ -1,10 +1,12 @@ PKG_NAME=xipfs PKG_URL=https://github.com/2xs/xipfs.git -PKG_VERSION=962c5edc55abb6363ff2988dc3b2c3c293362e96 +PKG_VERSION=837e15fb85bd3fc0fbc87d39a692ebf5c2cc9a5f PKG_LICENSE=CeCILL-2.1 include $(RIOTBASE)/pkg/pkg.mk +CFLAGS += -DXIPFS_ENABLE_SAFE_EXEC_SUPPORT + export RIOT_INCLUDES=$(INCLUDES) export RIOT_CFLAGS=$(CFLAGS) diff --git a/pkg/xipfs/doc.txt b/pkg/xipfs/doc.txt index 102b44801f42..8830c9d250c5 100644 --- a/pkg/xipfs/doc.txt +++ b/pkg/xipfs/doc.txt @@ -17,9 +17,14 @@ * * To prevent fragmentation, when a file is deleted, subsequent files are shifted to fill the vacant space. * - *`xipfs` is compatible with all microcontrollers featuring addressable - * flash memory and most operating systems, provided they implement the - * necessary functions to interact with the flash controller. + *`xipfs` is compatible with all ARM microcontrollers featuring addressable flash memory and + * most operating systems, provided they implement the necessary functions to interact with + * the flash controller. + * + * The filesystem is also capable to run files with memory isolation, thanks to the use of + * ARMv7-M Memory Protection Unit. + * Then, the TEXT, DATA and STACK segments of the executable are mapped to MPU regions, isolating + * the program from the rest of flash and RAM. It can only access to its legitimate contents. * * **To have a viable executable file within XiPFS**, please follow these steps : * - create a file with executable flag. diff --git a/pkg/xipfs/fs/xipfs_fs.c b/pkg/xipfs/fs/xipfs_fs.c index 2b99770f0888..6ced2767a4db 100644 --- a/pkg/xipfs/fs/xipfs_fs.c +++ b/pkg/xipfs/fs/xipfs_fs.c @@ -652,7 +652,7 @@ static int get_file_size(const char *full_path, size_t *size) { return 0; } -static ssize_t copy_file(const char *full_path, void *buf, size_t nbyte) { +static int copy_file(const char *full_path, void *buf, size_t nbyte) { xipfs_mount_t mp; const char *path; xipfs_file_desc_t desc; @@ -663,9 +663,15 @@ static ssize_t copy_file(const char *full_path, void *buf, size_t nbyte) { if (ret < 0) { return ret; } + + if ((file_size == 0) || (nbyte < file_size)) { + return -EINVAL; + } + if (nbyte > file_size) { nbyte = file_size; } + if (full_path == NULL) { return -EFAULT; } @@ -675,7 +681,6 @@ static ssize_t copy_file(const char *full_path, void *buf, size_t nbyte) { if ((path = get_rel_path(&mp, full_path)) == NULL) { return -EIO; } - ret = xipfs_open(&mp, &desc, path, O_RDONLY, 0); if (ret < 0) { return ret; @@ -724,6 +729,29 @@ int xipfs_extended_driver_execv(const char *full_path, char *const argv[]) return ret; } +int xipfs_extended_driver_safe_execv(const char *full_path, char *const argv[]) +{ + xipfs_mount_t mp; + const char *path; + int ret; + + if (full_path == NULL) { + return -EFAULT; + } + if ((ret = get_xipfs_mp(full_path, &mp)) < 0) { + return ret; + } + if ((path = get_rel_path(&mp, full_path)) == NULL) { + return -EIO; + } + + mutex_lock(mp.execution_mutex); + ret = xipfs_safe_execv(&mp, path, argv, xipfs_user_syscalls_table); + mutex_unlock(mp.execution_mutex); + + return ret; +} + /* * File system driver structures */ diff --git a/sys/include/fs/xipfs_fs.h b/sys/include/fs/xipfs_fs.h index ce3f0827adc4..f36fe3c3c58a 100644 --- a/sys/include/fs/xipfs_fs.h +++ b/sys/include/fs/xipfs_fs.h @@ -115,7 +115,7 @@ int xipfs_construct_from_flashpage(mtd_flashpage_t *flashpage, const char *path, * * Allows to create a regular or executable new file within XiPFS. * - * @param full_path A full path such as `/dev/nvme0p0/my_new_file` + * @param full_path A full path such as `/nvme0p0/my_new_file` * * @param size The file size in bytes. * @@ -129,7 +129,7 @@ int xipfs_extended_driver_new_file(const char *full_path, uint32_t size, uint32_ /** * @brief Executes an executable file with arguments. * - * @param full_path A full path such as `/dev/nvme0p0/my_executable_file` + * @param full_path A full path such as `/nvme0p0/my_executable_file` * * @param argv Executable arguments. Cannot be NULL, argv[0] contains the executable filename. * @@ -138,6 +138,18 @@ int xipfs_extended_driver_new_file(const char *full_path, uint32_t size, uint32_ */ int xipfs_extended_driver_execv(const char *full_path, char *const argv[]); +/** + * @brief Executes safely an executable file with arguments. + * + * @param full_path A full path such as `/nvme0p0/my_executable_file` + * + * @param argv Executable arguments. Cannot be NULL, argv[0] contains the executable filename. + * + * @retval Less than 0 on errors. + * @retval 0 on success. + */ +int xipfs_extended_driver_safe_execv(const char *full_path, char *const argv[]); + #ifdef __cplusplus } #endif diff --git a/sys/shell/cmds/xipfs.c b/sys/shell/cmds/xipfs.c index e4acce9e4625..5cdd0f5e654b 100644 --- a/sys/shell/cmds/xipfs.c +++ b/sys/shell/cmds/xipfs.c @@ -29,22 +29,39 @@ static char *execute_file_handler_args[XIPFS_EXEC_ARGC_MAX]; +static void print_execute_file_usage(void) { + printf("Usage : execute [-p] xipfs_executable_filename [arg0] [arg1] ... [arg%d]\n", + (XIPFS_EXEC_ARGC_MAX - 1)); + printf("OPTION:\n"); + printf("\t-p\n"); + printf("\t\tRun the file with Memory Protection Unit.\n"); +} + static int _execute_file_handler(int argc, char **argv) { + int exe_filename_arg_pos = 1; + const char *exe_filename; + if ( (argc == 1) || (argc > XIPFS_EXEC_ARGC_MAX) ) { - printf("Usage %s xipfs_executable_filename [arg0] [arg1] ... [arg%d]\n", - argv[0], (XIPFS_EXEC_ARGC_MAX - 1)); - printf("\t- xipfs_executable_filename : filename of the desired XIPFS file to execute\n"); + print_execute_file_usage(); return 1; } + if ((argv[1][0] == '-') && argv[1][1] == 'p') + exe_filename_arg_pos = 2; + + exe_filename = argv[exe_filename_arg_pos]; + memset(execute_file_handler_args, 0, sizeof(execute_file_handler_args)); - for (int i = 1; i Date: Fri, 3 Oct 2025 14:54:06 +0200 Subject: [PATCH 02/12] fixup! pkg/xipfs: add MPU memory isolation to file execution --- examples/advanced/xipfs/main.c | 8 +++++--- sys/shell/cmds/xipfs.c | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/advanced/xipfs/main.c b/examples/advanced/xipfs/main.c index c66259a318d3..27948f2ca66c 100644 --- a/examples/advanced/xipfs/main.c +++ b/examples/advanced/xipfs/main.c @@ -92,8 +92,9 @@ static const file_to_drop_t files_to_drop[2] = { }; static int drop_file(const file_to_drop_t *file_to_drop) { - if (file_to_drop == NULL) + if (file_to_drop == NULL) { return EXIT_FAILURE; + } int file_handle = vfs_open(file_to_drop->filename, O_RDONLY, 0); if (file_handle < 0) { @@ -143,9 +144,10 @@ int drop_files_handler(int argc, char **argv) { (void)argc; (void)argv; - for(unsigned int i = 0; i < sizeof(files_to_drop)/sizeof(files_to_drop[0]); ++i) { - if (drop_file(&files_to_drop[i]) != EXIT_SUCCESS) + for (unsigned int i = 0; i < ARRAY_SIZE(files_to_drop); ++i) { + if (drop_file(&files_to_drop[i]) != EXIT_SUCCESS) { return EXIT_FAILURE; + } } return EXIT_SUCCESS; diff --git a/sys/shell/cmds/xipfs.c b/sys/shell/cmds/xipfs.c index 5cdd0f5e654b..15fcc41cf33b 100644 --- a/sys/shell/cmds/xipfs.c +++ b/sys/shell/cmds/xipfs.c @@ -46,8 +46,9 @@ static int _execute_file_handler(int argc, char **argv) { return 1; } - if ((argv[1][0] == '-') && argv[1][1] == 'p') + if ((argv[1][0] == '-') && argv[1][1] == 'p') { exe_filename_arg_pos = 2; + } exe_filename = argv[exe_filename_arg_pos]; From 4c0d1cad8b65b36ad30b4ca618525610501431a2 Mon Sep 17 00:00:00 2001 From: Gregory Guche Date: Mon, 6 Oct 2025 11:39:57 +0200 Subject: [PATCH 03/12] fixup! pkg/xipfs: add MPU memory isolation to file execution --- cpu/cortexm_common/vectors_cortexm.c | 4 ++-- pkg/xipfs/Makefile.dep | 3 +++ sys/include/fs/xipfs_fs.h | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cpu/cortexm_common/vectors_cortexm.c b/cpu/cortexm_common/vectors_cortexm.c index 704ac9514ce4..76aa39c39315 100644 --- a/cpu/cortexm_common/vectors_cortexm.c +++ b/cpu/cortexm_common/vectors_cortexm.c @@ -483,14 +483,14 @@ void hard_fault_default(void) void mem_manage_default(void) { -# if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) +#if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) uint32_t mmfar = SCB->MMFAR; uint32_t cfsr = SCB->CFSR; uintptr_t psp = __get_PSP(); if (xipfs_mem_manage_handler((void *)psp, mmfar, cfsr) == 0) { return; } -# endif +#endif core_panic(PANIC_MEM_MANAGE, "MEM MANAGE HANDLER"); } diff --git a/pkg/xipfs/Makefile.dep b/pkg/xipfs/Makefile.dep index 556ac3748d2f..e3f44d05362b 100644 --- a/pkg/xipfs/Makefile.dep +++ b/pkg/xipfs/Makefile.dep @@ -5,9 +5,12 @@ ifeq (,$(filter xipfs_fs,$(DISABLE_MODULE))) # xipfs only makes sense if the flash memory is addressable FEATURES_REQUIRED += periph_flashpage_in_address_space FEATURES_REQUIRED += arch_32bit arch_arm + # xipfs safe execution feature relies on MPU. + FEATURES_REQUIRED += cortexm_mpu FEATURES_OPTIONAL += periph_flashpage_aux USEMODULE += periph_flashpage USEMODULE += mtd_flashpage USEMODULE += vfs USEMODULE += shell_cmd_xipfs + USE_MODULE += cortexm_svc endif diff --git a/sys/include/fs/xipfs_fs.h b/sys/include/fs/xipfs_fs.h index f36fe3c3c58a..9504c87751cb 100644 --- a/sys/include/fs/xipfs_fs.h +++ b/sys/include/fs/xipfs_fs.h @@ -139,7 +139,7 @@ int xipfs_extended_driver_new_file(const char *full_path, uint32_t size, uint32_ int xipfs_extended_driver_execv(const char *full_path, char *const argv[]); /** - * @brief Executes safely an executable file with arguments. + * @brief Runs an executable file according to arguments with MPU-based memory isolation. * * @param full_path A full path such as `/nvme0p0/my_executable_file` * From b6aba1effb70f9b38af61e45925a22654bb91f16 Mon Sep 17 00:00:00 2001 From: Gregory Guche Date: Mon, 6 Oct 2025 16:40:21 +0200 Subject: [PATCH 04/12] fixup! pkg/xipfs: add MPU memory isolation to file execution --- cpu/cortexm_common/include/cpu_conf_common.h | 6 +----- examples/advanced/xipfs/Makefile | 3 +++ pkg/xipfs/Makefile | 2 +- pkg/xipfs/Makefile.dep | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cpu/cortexm_common/include/cpu_conf_common.h b/cpu/cortexm_common/include/cpu_conf_common.h index 1449c6bab8e1..8dec4e101db7 100644 --- a/cpu/cortexm_common/include/cpu_conf_common.h +++ b/cpu/cortexm_common/include/cpu_conf_common.h @@ -49,11 +49,7 @@ extern "C" { * @{ */ #ifndef ISR_STACKSIZE -# if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) -# define ISR_STACKSIZE (1024U) -#else -# define ISR_STACKSIZE (512U) -# endif +#define ISR_STACKSIZE (512U) #endif /** @} */ diff --git a/examples/advanced/xipfs/Makefile b/examples/advanced/xipfs/Makefile index 79d1230d0616..23fb42695cab 100644 --- a/examples/advanced/xipfs/Makefile +++ b/examples/advanced/xipfs/Makefile @@ -33,6 +33,9 @@ FEATURES_REQUIRED += cortexm_mpu # Use xipfs file system USEMODULE += xipfs +# XIPFS MPU support CFLAGS += -DXIPFS_ENABLE_SAFE_EXEC_SUPPORT +# XIPFS MPU ISR stack requirement +CFLAGS += -DISR_STACKSIZE=1024 include $(RIOTBASE)/Makefile.include diff --git a/pkg/xipfs/Makefile b/pkg/xipfs/Makefile index 5d7cedd24494..3a015f6c43b1 100644 --- a/pkg/xipfs/Makefile +++ b/pkg/xipfs/Makefile @@ -1,6 +1,6 @@ PKG_NAME=xipfs PKG_URL=https://github.com/2xs/xipfs.git -PKG_VERSION=837e15fb85bd3fc0fbc87d39a692ebf5c2cc9a5f +PKG_VERSION=22ff164f1fb9097f272540836c3f111ecf8cde10 PKG_LICENSE=CeCILL-2.1 include $(RIOTBASE)/pkg/pkg.mk diff --git a/pkg/xipfs/Makefile.dep b/pkg/xipfs/Makefile.dep index e3f44d05362b..04ce2dc6e86f 100644 --- a/pkg/xipfs/Makefile.dep +++ b/pkg/xipfs/Makefile.dep @@ -12,5 +12,5 @@ ifeq (,$(filter xipfs_fs,$(DISABLE_MODULE))) USEMODULE += mtd_flashpage USEMODULE += vfs USEMODULE += shell_cmd_xipfs - USE_MODULE += cortexm_svc + USEMODULE += cortexm_svc endif From 664951fb10a5b95736e2bf700ef565123f63ae57 Mon Sep 17 00:00:00 2001 From: Gregory Guche Date: Mon, 6 Oct 2025 16:53:31 +0200 Subject: [PATCH 05/12] fixup! pkg/xipfs: add MPU memory isolation to file execution --- cpu/cortexm_common/thread_arch.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cpu/cortexm_common/thread_arch.c b/cpu/cortexm_common/thread_arch.c index e6592e26fdfc..b44b468d0238 100644 --- a/cpu/cortexm_common/thread_arch.c +++ b/cpu/cortexm_common/thread_arch.c @@ -497,11 +497,6 @@ void __attribute__((naked)) __attribute__((used)) isr_svc(void) #endif } -#if (defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)) && \ - defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) -#undef XIPFS_ENABLE_SAFE_EXEC_SUPPORT -#endif - static void __attribute__((used)) _svc_dispatch(unsigned int *svc_args) { /* stack frame: From bbb41690da6c75fcdb737ba3a1ba76aeed02a91a Mon Sep 17 00:00:00 2001 From: Gregory Guche Date: Wed, 8 Oct 2025 10:59:00 +0200 Subject: [PATCH 06/12] fixup! pkg/xipfs: add MPU memory isolation to file execution --- cpu/cortexm_common/vectors_cortexm.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cpu/cortexm_common/vectors_cortexm.c b/cpu/cortexm_common/vectors_cortexm.c index 76aa39c39315..b48787fdfd82 100644 --- a/cpu/cortexm_common/vectors_cortexm.c +++ b/cpu/cortexm_common/vectors_cortexm.c @@ -476,11 +476,6 @@ void hard_fault_default(void) defined(CPU_CORE_CORTEX_M4) || defined(CPU_CORE_CORTEX_M4F) || \ defined(CPU_CORE_CORTEX_M7) -#if (defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)) && \ - defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) -#undef XIPFS_ENABLE_SAFE_EXEC_SUPPORT -#endif - void mem_manage_default(void) { #if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) From b94cafef1e6a20432dc18dc85f2f0d3e5d5217d7 Mon Sep 17 00:00:00 2001 From: Gregory Guche Date: Wed, 8 Oct 2025 17:09:18 +0200 Subject: [PATCH 07/12] fixup! pkg/xipfs: add MPU memory isolation to file execution --- cpu/cortexm_common/include/thread_arch.h | 49 +++++++++++++++++ cpu/cortexm_common/include/vectors_cortexm.h | 49 +++++++++++++++++ cpu/cortexm_common/thread_arch.c | 57 ++++++++++++++------ cpu/cortexm_common/vectors_cortexm.c | 47 ++++++++++++---- pkg/xipfs/fs/xipfs_fs.c | 42 +++++++++++++++ 5 files changed, 217 insertions(+), 27 deletions(-) diff --git a/cpu/cortexm_common/include/thread_arch.h b/cpu/cortexm_common/include/thread_arch.h index 987189387597..e611b1d0f337 100644 --- a/cpu/cortexm_common/include/thread_arch.h +++ b/cpu/cortexm_common/include/thread_arch.h @@ -38,6 +38,55 @@ static inline __attribute__((always_inline)) void thread_yield_higher(void) #endif /* DOXYGEN */ +/** + * @brief All svc dispatch handlers have this type. + */ +typedef int (*svc_dispatch_handler_t)( + unsigned int svc_number, unsigned int *svc_args); + +#ifdef NDEBUG + +# define assert_svc_dispatch_manage_handler() do {} while(0) + +#else + +/** + * @brief Last file that asserted svc dispatch handler was free. + */ +extern const char *_free_svc_dispatch_handler_last_file; + +/** + * @brief Asserts that SVC dispatch handler is free. + * + * @param file Calling file. + * @param line Line in calling file. + */ +void assert_free_svc_dispatch_handler_ex(const char *file, int line); + +/** + * + */ +#define assert_free_svc_dispatch_handler() \ + assert_free_svc_dispatch_handler_ex(__FILE__, __LINE__); \ + _free_svc_dispatch_handler_last_file = __FILE__ + +#endif /* NDEBUG */ + +/** + * @brief SVC dispatch handler setter. + * + * @param handler Handler to set + * + * @retval < 0 on NULL handler or if a handler has already been set + * @retval >= 0 otherwise + */ +int set_svc_dispatch_handler(svc_dispatch_handler_t handler); + +/** + * @brief SVC dispatch handler cleaner. + */ +void remove_svc_dispatch_handler(void); + #ifdef __cplusplus } #endif diff --git a/cpu/cortexm_common/include/vectors_cortexm.h b/cpu/cortexm_common/include/vectors_cortexm.h index f6a2fb2704c7..8cde1c4c5791 100644 --- a/cpu/cortexm_common/include/vectors_cortexm.h +++ b/cpu/cortexm_common/include/vectors_cortexm.h @@ -90,6 +90,55 @@ void hard_fault_default(void); /* The following four exceptions are only present for Cortex-M3 and -M4 CPUs */ #if defined(CPU_CORE_CORTEX_M3) || defined(CPU_CORE_CORTEX_M4) || \ defined(CPU_CORE_CORTEX_M4F) || defined(CPU_CORE_CORTEX_M7) + +/** + * @brief All mem manage handlers have this type. + */ +typedef int (*mem_manage_handler_t)(void); + +#ifdef NDEBUG + +# define assert_free_mem_manage_handler() do {} while(0) + +#else + +/** + * @brief Last file that asserted mem manage handler was free. + */ +extern const char *_free_mem_manage_handler_last_file; + +/** + * @brief Asserts that mem manage handler is free. + * + * @param file Calling file. + * @param line Line in calling file. + */ +void assert_free_mem_manage_handler_ex(const char *file, int line); + +/** + * + */ +#define assert_free_mem_manage_handler() \ + assert_free_mem_manage_handler_ex(__FILE__, __LINE__); \ + _free_mem_manage_handler_last_file = __FILE__ + +#endif /* NDEBUG */ + +/** + * @brief Memory manage handler setter. + * + * @param handler Handler to set + * + * @retval < 0 on NULL handler or if a handler has already been set + * @retval >= 0 otherwise + */ +int set_memory_manage_handler(mem_manage_handler_t handler); + +/** + * @brief Memory manage handler cleaner. + */ +void remove_memory_manage_handler(void); + /** * @brief Memory management exception handler * diff --git a/cpu/cortexm_common/thread_arch.c b/cpu/cortexm_common/thread_arch.c index b44b468d0238..9418b4871c1b 100644 --- a/cpu/cortexm_common/thread_arch.c +++ b/cpu/cortexm_common/thread_arch.c @@ -97,10 +97,6 @@ #define ENABLE_DEBUG 0 #include "debug.h" -#if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) -#include "include/xipfs.h" -#endif - extern uint32_t _estack; extern uint32_t _sstack; @@ -497,6 +493,41 @@ void __attribute__((naked)) __attribute__((used)) isr_svc(void) #endif } +static svc_dispatch_handler_t _svc_dispatch_handler = NULL; + +#ifndef NDEBUG +const char *_free_svc_dispatch_handler_last_file = NULL; + +void assert_free_svc_dispatch_handler_ex(const char *file, int line) { + if (_svc_dispatch_handler != NULL) { + printf( "SVC dispatch handler is not free : assertion from " + "file %s at line %d, previously from file %s\n", + file, line, + _free_svc_dispatch_handler_last_file); + + for(;;); + } +} + +#endif + +int set_svc_dispatch_handler(svc_dispatch_handler_t handler) { + if (handler == NULL) + return -1; + if (_svc_dispatch_handler != NULL) + return -1; + _svc_dispatch_handler = handler; + return 0; +} + +void remove_svc_dispatch_handler(void) { + _svc_dispatch_handler = NULL; +#ifndef NDEBUG + _free_svc_dispatch_handler_last_file = NULL; +#endif +} + + static void __attribute__((used)) _svc_dispatch(unsigned int *svc_args) { /* stack frame: @@ -522,20 +553,12 @@ static void __attribute__((used)) _svc_dispatch(unsigned int *svc_args) case 1: /* SVC number used by cpu_switch_context_exit */ SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; break; -#if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) - case XIPFS_ENTER_SVC_NUMBER: { - void *crt0_ctx = (void *)svc_args[0]; - void *entry_point = (void *)svc_args[1]; - void *stack_top = (void *)svc_args[2]; - xipfs_safe_exec_enter(crt0_ctx, entry_point, stack_top); - break; - } - case XIPFS_SYSCALL_SVC_NUMBER: { - xipfs_syscall_dispatcher(svc_args); - break; - } -#endif default: + if (_svc_dispatch_handler != NULL) { + if (_svc_dispatch_handler(svc_number, svc_args) >= 0) { + return; + } + } DEBUG("svc: unhandled SVC #%u\n", svc_number); break; } diff --git a/cpu/cortexm_common/vectors_cortexm.c b/cpu/cortexm_common/vectors_cortexm.c index b48787fdfd82..6d49e6604009 100644 --- a/cpu/cortexm_common/vectors_cortexm.c +++ b/cpu/cortexm_common/vectors_cortexm.c @@ -37,9 +37,6 @@ #ifdef MODULE_DBGPIN #include "dbgpin.h" #endif -#if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) -#include "include/xipfs.h" -#endif #ifndef SRAM_BASE #define SRAM_BASE 0 @@ -476,16 +473,46 @@ void hard_fault_default(void) defined(CPU_CORE_CORTEX_M4) || defined(CPU_CORE_CORTEX_M4F) || \ defined(CPU_CORE_CORTEX_M7) +static mem_manage_handler_t _mem_manage_handler = NULL; + +#ifndef NDEBUG +const char *_free_mem_manage_handler_last_file = NULL; + +void assert_free_mem_manage_handler_ex(const char *file, int line) { + if (_mem_manage_handler != NULL) { + printf( "Memory manage handler is not free : assertion from " + "file %s at line %d, previously from file %s\n", + file, line, + _free_mem_manage_handler_last_file); + + for(;;); + } +} + +#endif + +int set_memory_manage_handler(mem_manage_handler_t handler) { + if (handler == NULL) + return -1; + if (_mem_manage_handler != NULL) + return -1; + _mem_manage_handler = handler; + return 0; +} + +void remove_memory_manage_handler(void) { + _mem_manage_handler = NULL; +#ifndef NDEBUG + _free_mem_manage_handler_last_file = NULL; +#endif +} + void mem_manage_default(void) { -#if defined(MODULE_XIPFS) && defined(XIPFS_ENABLE_SAFE_EXEC_SUPPORT) - uint32_t mmfar = SCB->MMFAR; - uint32_t cfsr = SCB->CFSR; - uintptr_t psp = __get_PSP(); - if (xipfs_mem_manage_handler((void *)psp, mmfar, cfsr) == 0) { - return; + if (_mem_manage_handler != NULL) { + if (_mem_manage_handler() == 1) + return; } -#endif core_panic(PANIC_MEM_MANAGE, "MEM MANAGE HANDLER"); } diff --git a/pkg/xipfs/fs/xipfs_fs.c b/pkg/xipfs/fs/xipfs_fs.c index 6ced2767a4db..af6a9318f09b 100644 --- a/pkg/xipfs/fs/xipfs_fs.c +++ b/pkg/xipfs/fs/xipfs_fs.c @@ -47,6 +47,8 @@ #include "debug.h" #include "fs/xipfs_fs.h" #include "periph/flashpage.h" +#include "vectors_cortexm.h" +#include "thread_arch.h" #include "saul_reg.h" @@ -729,6 +731,35 @@ int xipfs_extended_driver_execv(const char *full_path, char *const argv[]) return ret; } +int xipfs_memory_manage_handler(void) { + uint32_t mmfar = SCB->MMFAR; + uint32_t cfsr = SCB->CFSR; + uintptr_t psp = __get_PSP(); + if (xipfs_mem_manage_handler((void *)psp, mmfar, cfsr) == 0) { + return 1; + } + + return 0; +} + +int xipfs_svc_dispatch_handler(unsigned int svc_number, unsigned int *svc_args) { + switch (svc_number) { + case XIPFS_ENTER_SVC_NUMBER: { + void *crt0_ctx = (void *)svc_args[0]; + void *entry_point = (void *)svc_args[1]; + void *stack_top = (void *)svc_args[2]; + xipfs_safe_exec_enter(crt0_ctx, entry_point, stack_top); + return 0; + } + case XIPFS_SYSCALL_SVC_NUMBER: { + xipfs_syscall_dispatcher(svc_args); + return 0; + } + default: + return -ENOTSUP; + } +} + int xipfs_extended_driver_safe_execv(const char *full_path, char *const argv[]) { xipfs_mount_t mp; @@ -746,7 +777,18 @@ int xipfs_extended_driver_safe_execv(const char *full_path, char *const argv[]) } mutex_lock(mp.execution_mutex); + + assert_free_mem_manage_handler(); + set_memory_manage_handler(xipfs_memory_manage_handler); + + assert_free_svc_dispatch_handler(); + set_svc_dispatch_handler(xipfs_svc_dispatch_handler); + ret = xipfs_safe_execv(&mp, path, argv, xipfs_user_syscalls_table); + + remove_memory_manage_handler(); + remove_svc_dispatch_handler(); + mutex_unlock(mp.execution_mutex); return ret; From 06a9a6e86e83e67d512f62398aafc6d088b79be0 Mon Sep 17 00:00:00 2001 From: Gregory Guche Date: Thu, 9 Oct 2025 09:43:25 +0200 Subject: [PATCH 08/12] fixup! pkg/xipfs: add MPU memory isolation to file execution --- cpu/cortexm_common/include/thread_arch.h | 7 +++++++ cpu/cortexm_common/include/vectors_cortexm.h | 11 +++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/cpu/cortexm_common/include/thread_arch.h b/cpu/cortexm_common/include/thread_arch.h index e611b1d0f337..393f6ede7920 100644 --- a/cpu/cortexm_common/include/thread_arch.h +++ b/cpu/cortexm_common/include/thread_arch.h @@ -60,11 +60,18 @@ extern const char *_free_svc_dispatch_handler_last_file; * * @param file Calling file. * @param line Line in calling file. + * + * @see assert_free_svc_dispatch_handler */ void assert_free_svc_dispatch_handler_ex(const char *file, int line); /** + * @brief Asserts that SVC dispatch handler is free. + * + * To be used in files using set_memory_manage_handler. * + * @see set_svc_dispatch_handler + * @see assert_free_svc_dispatch_handler_ex */ #define assert_free_svc_dispatch_handler() \ assert_free_svc_dispatch_handler_ex(__FILE__, __LINE__); \ diff --git a/cpu/cortexm_common/include/vectors_cortexm.h b/cpu/cortexm_common/include/vectors_cortexm.h index 8cde1c4c5791..735e12a9108a 100644 --- a/cpu/cortexm_common/include/vectors_cortexm.h +++ b/cpu/cortexm_common/include/vectors_cortexm.h @@ -103,20 +103,27 @@ typedef int (*mem_manage_handler_t)(void); #else /** - * @brief Last file that asserted mem manage handler was free. + * @brief Last file that asserted memory manage handler was free. */ extern const char *_free_mem_manage_handler_last_file; /** - * @brief Asserts that mem manage handler is free. + * @brief Asserts that memory manage handler is free. * * @param file Calling file. * @param line Line in calling file. + * + * @see assert_free_mem_manage_handler */ void assert_free_mem_manage_handler_ex(const char *file, int line); /** + * @brief Asserts that memory manage handler is free. + * + * To be used in files using set_memory_manage_handler. * + * @see set_memory_manage_handler + * @see assert_free_mem_manage_handler_ex */ #define assert_free_mem_manage_handler() \ assert_free_mem_manage_handler_ex(__FILE__, __LINE__); \ From b2512ed9eb01a5fb56e0f0925f80e7447dbab678 Mon Sep 17 00:00:00 2001 From: Gregory Guche Date: Thu, 9 Oct 2025 11:39:18 +0200 Subject: [PATCH 09/12] fixup! pkg/xipfs: add MPU memory isolation to file execution --- cpu/cortexm_common/include/thread_arch.h | 2 +- cpu/cortexm_common/include/vectors_cortexm.h | 2 +- cpu/cortexm_common/thread_arch.c | 9 +++++---- cpu/cortexm_common/vectors_cortexm.c | 8 +++++--- pkg/xipfs/fs/xipfs_fs.c | 4 ++++ sys/include/fs/xipfs_fs.h | 4 ++++ sys/shell/cmds/xipfs.c | 12 ++++++++++++ 7 files changed, 32 insertions(+), 9 deletions(-) diff --git a/cpu/cortexm_common/include/thread_arch.h b/cpu/cortexm_common/include/thread_arch.h index 393f6ede7920..a9138088e35d 100644 --- a/cpu/cortexm_common/include/thread_arch.h +++ b/cpu/cortexm_common/include/thread_arch.h @@ -46,7 +46,7 @@ typedef int (*svc_dispatch_handler_t)( #ifdef NDEBUG -# define assert_svc_dispatch_manage_handler() do {} while(0) +# define assert_svc_dispatch_manage_handler() do {} while (0) #else diff --git a/cpu/cortexm_common/include/vectors_cortexm.h b/cpu/cortexm_common/include/vectors_cortexm.h index 735e12a9108a..374ffda25189 100644 --- a/cpu/cortexm_common/include/vectors_cortexm.h +++ b/cpu/cortexm_common/include/vectors_cortexm.h @@ -98,7 +98,7 @@ typedef int (*mem_manage_handler_t)(void); #ifdef NDEBUG -# define assert_free_mem_manage_handler() do {} while(0) +# define assert_free_mem_manage_handler() do {} while (0) #else diff --git a/cpu/cortexm_common/thread_arch.c b/cpu/cortexm_common/thread_arch.c index 9418b4871c1b..fb959def0b53 100644 --- a/cpu/cortexm_common/thread_arch.c +++ b/cpu/cortexm_common/thread_arch.c @@ -505,17 +505,19 @@ void assert_free_svc_dispatch_handler_ex(const char *file, int line) { file, line, _free_svc_dispatch_handler_last_file); - for(;;); + for (;;) {} } } #endif int set_svc_dispatch_handler(svc_dispatch_handler_t handler) { - if (handler == NULL) + if (handler == NULL) { return -1; - if (_svc_dispatch_handler != NULL) + } + if (_svc_dispatch_handler != NULL) { return -1; + } _svc_dispatch_handler = handler; return 0; } @@ -527,7 +529,6 @@ void remove_svc_dispatch_handler(void) { #endif } - static void __attribute__((used)) _svc_dispatch(unsigned int *svc_args) { /* stack frame: diff --git a/cpu/cortexm_common/vectors_cortexm.c b/cpu/cortexm_common/vectors_cortexm.c index 6d49e6604009..06d17648709d 100644 --- a/cpu/cortexm_common/vectors_cortexm.c +++ b/cpu/cortexm_common/vectors_cortexm.c @@ -485,17 +485,19 @@ void assert_free_mem_manage_handler_ex(const char *file, int line) { file, line, _free_mem_manage_handler_last_file); - for(;;); + for (;;) {} } } #endif int set_memory_manage_handler(mem_manage_handler_t handler) { - if (handler == NULL) + if (handler == NULL) { return -1; - if (_mem_manage_handler != NULL) + } + if (_mem_manage_handler != NULL) { return -1; + } _mem_manage_handler = handler; return 0; } diff --git a/pkg/xipfs/fs/xipfs_fs.c b/pkg/xipfs/fs/xipfs_fs.c index af6a9318f09b..6934034b6248 100644 --- a/pkg/xipfs/fs/xipfs_fs.c +++ b/pkg/xipfs/fs/xipfs_fs.c @@ -731,6 +731,8 @@ int xipfs_extended_driver_execv(const char *full_path, char *const argv[]) return ret; } +#ifdef XIPFS_ENABLE_SAFE_EXEC_SUPPORT + int xipfs_memory_manage_handler(void) { uint32_t mmfar = SCB->MMFAR; uint32_t cfsr = SCB->CFSR; @@ -794,6 +796,8 @@ int xipfs_extended_driver_safe_execv(const char *full_path, char *const argv[]) return ret; } +#endif /* XIPFS_ENABLE_SAFE_EXEC_SUPPORT */ + /* * File system driver structures */ diff --git a/sys/include/fs/xipfs_fs.h b/sys/include/fs/xipfs_fs.h index 9504c87751cb..652358fef234 100644 --- a/sys/include/fs/xipfs_fs.h +++ b/sys/include/fs/xipfs_fs.h @@ -138,6 +138,8 @@ int xipfs_extended_driver_new_file(const char *full_path, uint32_t size, uint32_ */ int xipfs_extended_driver_execv(const char *full_path, char *const argv[]); +#ifdef XIPFS_ENABLE_SAFE_EXEC_SUPPORT + /** * @brief Runs an executable file according to arguments with MPU-based memory isolation. * @@ -150,6 +152,8 @@ int xipfs_extended_driver_execv(const char *full_path, char *const argv[]); */ int xipfs_extended_driver_safe_execv(const char *full_path, char *const argv[]); +#endif /* XIPFS_ENABLE_SAFE_EXEC_SUPPORT */ + #ifdef __cplusplus } #endif diff --git a/sys/shell/cmds/xipfs.c b/sys/shell/cmds/xipfs.c index 15fcc41cf33b..15d53614ccb7 100644 --- a/sys/shell/cmds/xipfs.c +++ b/sys/shell/cmds/xipfs.c @@ -30,11 +30,16 @@ static char *execute_file_handler_args[XIPFS_EXEC_ARGC_MAX]; static void print_execute_file_usage(void) { +#ifdef XIPFS_ENABLE_SAFE_EXEC_SUPPORT printf("Usage : execute [-p] xipfs_executable_filename [arg0] [arg1] ... [arg%d]\n", (XIPFS_EXEC_ARGC_MAX - 1)); printf("OPTION:\n"); printf("\t-p\n"); printf("\t\tRun the file with Memory Protection Unit.\n"); +#else + printf("Usage : execute xipfs_executable_filename [arg0] [arg1] ... [arg%d]\n", + (XIPFS_EXEC_ARGC_MAX - 1)); +#endif /* XIPFS_ENABLE_SAFE_EXEC_SUPPORT */ } static int _execute_file_handler(int argc, char **argv) { @@ -46,9 +51,11 @@ static int _execute_file_handler(int argc, char **argv) { return 1; } +#ifdef XIPFS_ENABLE_SAFE_EXEC_SUPPORT if ((argv[1][0] == '-') && argv[1][1] == 'p') { exe_filename_arg_pos = 2; } +#endif exe_filename = argv[exe_filename_arg_pos]; @@ -57,9 +64,14 @@ static int _execute_file_handler(int argc, char **argv) { execute_file_handler_args[i - exe_filename_arg_pos] = argv[i]; } +#ifdef XIPFS_ENABLE_SAFE_EXEC_SUPPORT int ret = (exe_filename_arg_pos == 2) ? xipfs_extended_driver_safe_execv(exe_filename, execute_file_handler_args) : xipfs_extended_driver_execv(exe_filename, execute_file_handler_args); +#else + int ret = xipfs_extended_driver_execv(exe_filename, execute_file_handler_args); +#endif + if (ret < 0) { printf("Failed to execute '%s', error=%d (%s)\n", argv[exe_filename_arg_pos], ret, strerror(-ret)); From 9a78b70bfccf72c2bf0442367f02b3e8ef771369 Mon Sep 17 00:00:00 2001 From: Gregory Guche Date: Thu, 9 Oct 2025 14:44:17 +0200 Subject: [PATCH 10/12] fixup! pkg/xipfs: add MPU memory isolation to file execution --- cpu/cortexm_common/include/thread_arch.h | 8 +++----- cpu/cortexm_common/include/vectors_cortexm.h | 8 +++----- cpu/cortexm_common/thread_arch.c | 9 ++++++--- cpu/cortexm_common/vectors_cortexm.c | 12 ++++++++---- pkg/xipfs/fs/xipfs_fs.c | 6 ++++-- sys/include/fs/xipfs_fs.h | 4 ++-- 6 files changed, 26 insertions(+), 21 deletions(-) diff --git a/cpu/cortexm_common/include/thread_arch.h b/cpu/cortexm_common/include/thread_arch.h index a9138088e35d..f323b7380d2f 100644 --- a/cpu/cortexm_common/include/thread_arch.h +++ b/cpu/cortexm_common/include/thread_arch.h @@ -45,9 +45,7 @@ typedef int (*svc_dispatch_handler_t)( unsigned int svc_number, unsigned int *svc_args); #ifdef NDEBUG - -# define assert_svc_dispatch_manage_handler() do {} while (0) - +# define assert_svc_dispatch_manage_handler() do {} while (0) #else /** @@ -58,8 +56,8 @@ extern const char *_free_svc_dispatch_handler_last_file; /** * @brief Asserts that SVC dispatch handler is free. * - * @param file Calling file. - * @param line Line in calling file. + * @param file[in] Calling file. + * @param line[in] Line in calling file. * * @see assert_free_svc_dispatch_handler */ diff --git a/cpu/cortexm_common/include/vectors_cortexm.h b/cpu/cortexm_common/include/vectors_cortexm.h index 374ffda25189..1f0dc58e30a9 100644 --- a/cpu/cortexm_common/include/vectors_cortexm.h +++ b/cpu/cortexm_common/include/vectors_cortexm.h @@ -97,9 +97,7 @@ void hard_fault_default(void); typedef int (*mem_manage_handler_t)(void); #ifdef NDEBUG - -# define assert_free_mem_manage_handler() do {} while (0) - +# define assert_free_mem_manage_handler() do {} while (0) #else /** @@ -110,8 +108,8 @@ extern const char *_free_mem_manage_handler_last_file; /** * @brief Asserts that memory manage handler is free. * - * @param file Calling file. - * @param line Line in calling file. + * @param[in] file Calling file. + * @param[in] line Line in calling file. * * @see assert_free_mem_manage_handler */ diff --git a/cpu/cortexm_common/thread_arch.c b/cpu/cortexm_common/thread_arch.c index fb959def0b53..12dd014db106 100644 --- a/cpu/cortexm_common/thread_arch.c +++ b/cpu/cortexm_common/thread_arch.c @@ -498,7 +498,8 @@ static svc_dispatch_handler_t _svc_dispatch_handler = NULL; #ifndef NDEBUG const char *_free_svc_dispatch_handler_last_file = NULL; -void assert_free_svc_dispatch_handler_ex(const char *file, int line) { +void assert_free_svc_dispatch_handler_ex(const char *file, int line) +{ if (_svc_dispatch_handler != NULL) { printf( "SVC dispatch handler is not free : assertion from " "file %s at line %d, previously from file %s\n", @@ -511,7 +512,8 @@ void assert_free_svc_dispatch_handler_ex(const char *file, int line) { #endif -int set_svc_dispatch_handler(svc_dispatch_handler_t handler) { +int set_svc_dispatch_handler(svc_dispatch_handler_t handler) +{ if (handler == NULL) { return -1; } @@ -522,7 +524,8 @@ int set_svc_dispatch_handler(svc_dispatch_handler_t handler) { return 0; } -void remove_svc_dispatch_handler(void) { +void remove_svc_dispatch_handler(void) +{ _svc_dispatch_handler = NULL; #ifndef NDEBUG _free_svc_dispatch_handler_last_file = NULL; diff --git a/cpu/cortexm_common/vectors_cortexm.c b/cpu/cortexm_common/vectors_cortexm.c index 06d17648709d..8346ab7d22b5 100644 --- a/cpu/cortexm_common/vectors_cortexm.c +++ b/cpu/cortexm_common/vectors_cortexm.c @@ -478,7 +478,8 @@ static mem_manage_handler_t _mem_manage_handler = NULL; #ifndef NDEBUG const char *_free_mem_manage_handler_last_file = NULL; -void assert_free_mem_manage_handler_ex(const char *file, int line) { +void assert_free_mem_manage_handler_ex(const char *file, int line) +{ if (_mem_manage_handler != NULL) { printf( "Memory manage handler is not free : assertion from " "file %s at line %d, previously from file %s\n", @@ -491,7 +492,8 @@ void assert_free_mem_manage_handler_ex(const char *file, int line) { #endif -int set_memory_manage_handler(mem_manage_handler_t handler) { +int set_memory_manage_handler(mem_manage_handler_t handler) +{ if (handler == NULL) { return -1; } @@ -502,7 +504,8 @@ int set_memory_manage_handler(mem_manage_handler_t handler) { return 0; } -void remove_memory_manage_handler(void) { +void remove_memory_manage_handler(void) +{ _mem_manage_handler = NULL; #ifndef NDEBUG _free_mem_manage_handler_last_file = NULL; @@ -512,8 +515,9 @@ void remove_memory_manage_handler(void) { void mem_manage_default(void) { if (_mem_manage_handler != NULL) { - if (_mem_manage_handler() == 1) + if (_mem_manage_handler() == 1) { return; + } } core_panic(PANIC_MEM_MANAGE, "MEM MANAGE HANDLER"); } diff --git a/pkg/xipfs/fs/xipfs_fs.c b/pkg/xipfs/fs/xipfs_fs.c index 6934034b6248..888e43e9fef8 100644 --- a/pkg/xipfs/fs/xipfs_fs.c +++ b/pkg/xipfs/fs/xipfs_fs.c @@ -733,7 +733,8 @@ int xipfs_extended_driver_execv(const char *full_path, char *const argv[]) #ifdef XIPFS_ENABLE_SAFE_EXEC_SUPPORT -int xipfs_memory_manage_handler(void) { +int xipfs_memory_manage_handler(void) +{ uint32_t mmfar = SCB->MMFAR; uint32_t cfsr = SCB->CFSR; uintptr_t psp = __get_PSP(); @@ -744,7 +745,8 @@ int xipfs_memory_manage_handler(void) { return 0; } -int xipfs_svc_dispatch_handler(unsigned int svc_number, unsigned int *svc_args) { +int xipfs_svc_dispatch_handler(unsigned int svc_number, unsigned int *svc_args) +{ switch (svc_number) { case XIPFS_ENTER_SVC_NUMBER: { void *crt0_ctx = (void *)svc_args[0]; diff --git a/sys/include/fs/xipfs_fs.h b/sys/include/fs/xipfs_fs.h index 652358fef234..b0257212b6ba 100644 --- a/sys/include/fs/xipfs_fs.h +++ b/sys/include/fs/xipfs_fs.h @@ -143,9 +143,9 @@ int xipfs_extended_driver_execv(const char *full_path, char *const argv[]); /** * @brief Runs an executable file according to arguments with MPU-based memory isolation. * - * @param full_path A full path such as `/nvme0p0/my_executable_file` + * @param[in] full_path A full path such as `/nvme0p0/my_executable_file` * - * @param argv Executable arguments. Cannot be NULL, argv[0] contains the executable filename. + * @param[in] argv Executable arguments. Cannot be NULL, argv[0] contains the executable filename. * * @retval Less than 0 on errors. * @retval 0 on success. From 451bd5a910566547575673184feb42a066ead884 Mon Sep 17 00:00:00 2001 From: Gregory Guche Date: Fri, 10 Oct 2025 10:29:45 +0200 Subject: [PATCH 11/12] fixup! pkg/xipfs: add MPU memory isolation to file execution --- cpu/cortexm_common/include/thread_arch.h | 55 +++----------------- cpu/cortexm_common/include/vectors_cortexm.h | 53 ++----------------- cpu/cortexm_common/thread_arch.c | 45 +++------------- cpu/cortexm_common/vectors_cortexm.c | 42 ++------------- pkg/xipfs/fs/xipfs_fs.c | 15 +----- 5 files changed, 22 insertions(+), 188 deletions(-) diff --git a/cpu/cortexm_common/include/thread_arch.h b/cpu/cortexm_common/include/thread_arch.h index f323b7380d2f..200734c1888f 100644 --- a/cpu/cortexm_common/include/thread_arch.h +++ b/cpu/cortexm_common/include/thread_arch.h @@ -39,58 +39,17 @@ static inline __attribute__((always_inline)) void thread_yield_higher(void) #endif /* DOXYGEN */ /** - * @brief All svc dispatch handlers have this type. - */ -typedef int (*svc_dispatch_handler_t)( - unsigned int svc_number, unsigned int *svc_args); - -#ifdef NDEBUG -# define assert_svc_dispatch_manage_handler() do {} while (0) -#else - -/** - * @brief Last file that asserted svc dispatch handler was free. - */ -extern const char *_free_svc_dispatch_handler_last_file; - -/** - * @brief Asserts that SVC dispatch handler is free. - * - * @param file[in] Calling file. - * @param line[in] Line in calling file. - * - * @see assert_free_svc_dispatch_handler - */ -void assert_free_svc_dispatch_handler_ex(const char *file, int line); - -/** - * @brief Asserts that SVC dispatch handler is free. - * - * To be used in files using set_memory_manage_handler. + * @brief Default SVC dispatch handler (weak function). * - * @see set_svc_dispatch_handler - * @see assert_free_svc_dispatch_handler_ex - */ -#define assert_free_svc_dispatch_handler() \ - assert_free_svc_dispatch_handler_ex(__FILE__, __LINE__); \ - _free_svc_dispatch_handler_last_file = __FILE__ - -#endif /* NDEBUG */ - -/** - * @brief SVC dispatch handler setter. + * @param[in] svc_number The svc number to handle. + * @param[in] svc_args Supervisor call arguments. * - * @param handler Handler to set + * @retval >= 0 when svc_number has been handled. + * @retval < 0 otherwise. * - * @retval < 0 on NULL handler or if a handler has already been set - * @retval >= 0 otherwise - */ -int set_svc_dispatch_handler(svc_dispatch_handler_t handler); - -/** - * @brief SVC dispatch handler cleaner. + * @see _svc_dispatch */ -void remove_svc_dispatch_handler(void); +int svc_dispatch_handler(unsigned int svc_number, unsigned int *svc_args); #ifdef __cplusplus } diff --git a/cpu/cortexm_common/include/vectors_cortexm.h b/cpu/cortexm_common/include/vectors_cortexm.h index 1f0dc58e30a9..52afe45a55ca 100644 --- a/cpu/cortexm_common/include/vectors_cortexm.h +++ b/cpu/cortexm_common/include/vectors_cortexm.h @@ -92,57 +92,12 @@ void hard_fault_default(void); defined(CPU_CORE_CORTEX_M4F) || defined(CPU_CORE_CORTEX_M7) /** - * @brief All mem manage handlers have this type. - */ -typedef int (*mem_manage_handler_t)(void); - -#ifdef NDEBUG -# define assert_free_mem_manage_handler() do {} while (0) -#else - -/** - * @brief Last file that asserted memory manage handler was free. - */ -extern const char *_free_mem_manage_handler_last_file; - -/** - * @brief Asserts that memory manage handler is free. - * - * @param[in] file Calling file. - * @param[in] line Line in calling file. - * - * @see assert_free_mem_manage_handler - */ -void assert_free_mem_manage_handler_ex(const char *file, int line); - -/** - * @brief Asserts that memory manage handler is free. - * - * To be used in files using set_memory_manage_handler. + * @brief Default memory manager behavior callback (weak function) * - * @see set_memory_manage_handler - * @see assert_free_mem_manage_handler_ex - */ -#define assert_free_mem_manage_handler() \ - assert_free_mem_manage_handler_ex(__FILE__, __LINE__); \ - _free_mem_manage_handler_last_file = __FILE__ - -#endif /* NDEBUG */ - -/** - * @brief Memory manage handler setter. - * - * @param handler Handler to set - * - * @retval < 0 on NULL handler or if a handler has already been set - * @retval >= 0 otherwise - */ -int set_memory_manage_handler(mem_manage_handler_t handler); - -/** - * @brief Memory manage handler cleaner. + * @retval 1 when the memory fault has been handled, + * @retval 0 otherwise. */ -void remove_memory_manage_handler(void); +int mem_manage_handler(void); /** * @brief Memory management exception handler diff --git a/cpu/cortexm_common/thread_arch.c b/cpu/cortexm_common/thread_arch.c index 12dd014db106..c6731326f52f 100644 --- a/cpu/cortexm_common/thread_arch.c +++ b/cpu/cortexm_common/thread_arch.c @@ -493,45 +493,14 @@ void __attribute__((naked)) __attribute__((used)) isr_svc(void) #endif } -static svc_dispatch_handler_t _svc_dispatch_handler = NULL; - -#ifndef NDEBUG -const char *_free_svc_dispatch_handler_last_file = NULL; - -void assert_free_svc_dispatch_handler_ex(const char *file, int line) +__attribute__((weak))int +svc_dispatch_handler(unsigned int svc_number, unsigned int *svc_args) { - if (_svc_dispatch_handler != NULL) { - printf( "SVC dispatch handler is not free : assertion from " - "file %s at line %d, previously from file %s\n", - file, line, - _free_svc_dispatch_handler_last_file); - - for (;;) {} - } -} - -#endif - -int set_svc_dispatch_handler(svc_dispatch_handler_t handler) -{ - if (handler == NULL) { - return -1; - } - if (_svc_dispatch_handler != NULL) { - return -1; - } - _svc_dispatch_handler = handler; + (void)svc_number; + (void)svc_args; return 0; } -void remove_svc_dispatch_handler(void) -{ - _svc_dispatch_handler = NULL; -#ifndef NDEBUG - _free_svc_dispatch_handler_last_file = NULL; -#endif -} - static void __attribute__((used)) _svc_dispatch(unsigned int *svc_args) { /* stack frame: @@ -558,10 +527,8 @@ static void __attribute__((used)) _svc_dispatch(unsigned int *svc_args) SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; break; default: - if (_svc_dispatch_handler != NULL) { - if (_svc_dispatch_handler(svc_number, svc_args) >= 0) { - return; - } + if (svc_dispatch_handler(svc_number, svc_args) >= 0) { + return; } DEBUG("svc: unhandled SVC #%u\n", svc_number); break; diff --git a/cpu/cortexm_common/vectors_cortexm.c b/cpu/cortexm_common/vectors_cortexm.c index 8346ab7d22b5..dc03e4844ab3 100644 --- a/cpu/cortexm_common/vectors_cortexm.c +++ b/cpu/cortexm_common/vectors_cortexm.c @@ -473,51 +473,15 @@ void hard_fault_default(void) defined(CPU_CORE_CORTEX_M4) || defined(CPU_CORE_CORTEX_M4F) || \ defined(CPU_CORE_CORTEX_M7) -static mem_manage_handler_t _mem_manage_handler = NULL; - -#ifndef NDEBUG -const char *_free_mem_manage_handler_last_file = NULL; - -void assert_free_mem_manage_handler_ex(const char *file, int line) -{ - if (_mem_manage_handler != NULL) { - printf( "Memory manage handler is not free : assertion from " - "file %s at line %d, previously from file %s\n", - file, line, - _free_mem_manage_handler_last_file); - - for (;;) {} - } -} - -#endif - -int set_memory_manage_handler(mem_manage_handler_t handler) +__attribute__((weak))int mem_manage_handler(void) { - if (handler == NULL) { - return -1; - } - if (_mem_manage_handler != NULL) { - return -1; - } - _mem_manage_handler = handler; return 0; } -void remove_memory_manage_handler(void) -{ - _mem_manage_handler = NULL; -#ifndef NDEBUG - _free_mem_manage_handler_last_file = NULL; -#endif -} - void mem_manage_default(void) { - if (_mem_manage_handler != NULL) { - if (_mem_manage_handler() == 1) { - return; - } + if (mem_manage_handler() == 1) { + return; } core_panic(PANIC_MEM_MANAGE, "MEM MANAGE HANDLER"); } diff --git a/pkg/xipfs/fs/xipfs_fs.c b/pkg/xipfs/fs/xipfs_fs.c index 888e43e9fef8..6de68226e9f0 100644 --- a/pkg/xipfs/fs/xipfs_fs.c +++ b/pkg/xipfs/fs/xipfs_fs.c @@ -733,7 +733,7 @@ int xipfs_extended_driver_execv(const char *full_path, char *const argv[]) #ifdef XIPFS_ENABLE_SAFE_EXEC_SUPPORT -int xipfs_memory_manage_handler(void) +int mem_manage_handler(void) { uint32_t mmfar = SCB->MMFAR; uint32_t cfsr = SCB->CFSR; @@ -745,7 +745,7 @@ int xipfs_memory_manage_handler(void) return 0; } -int xipfs_svc_dispatch_handler(unsigned int svc_number, unsigned int *svc_args) +int svc_dispatch_handler(unsigned int svc_number, unsigned int *svc_args) { switch (svc_number) { case XIPFS_ENTER_SVC_NUMBER: { @@ -781,18 +781,7 @@ int xipfs_extended_driver_safe_execv(const char *full_path, char *const argv[]) } mutex_lock(mp.execution_mutex); - - assert_free_mem_manage_handler(); - set_memory_manage_handler(xipfs_memory_manage_handler); - - assert_free_svc_dispatch_handler(); - set_svc_dispatch_handler(xipfs_svc_dispatch_handler); - ret = xipfs_safe_execv(&mp, path, argv, xipfs_user_syscalls_table); - - remove_memory_manage_handler(); - remove_svc_dispatch_handler(); - mutex_unlock(mp.execution_mutex); return ret; From 5b861379f362556b17f8797a04a8de2a1e8441a3 Mon Sep 17 00:00:00 2001 From: Gregory Guche Date: Thu, 16 Oct 2025 14:55:30 +0200 Subject: [PATCH 12/12] fixup! pkg/xipfs: add MPU memory isolation to file execution --- cpu/cortexm_common/include/vectors_cortexm.h | 4 +-- cpu/cortexm_common/thread_arch.c | 5 ++-- cpu/cortexm_common/vectors_cortexm.c | 7 +++-- examples/advanced/xipfs/main.c | 6 ++-- pkg/xipfs/fs/xipfs_fs.c | 30 ++++++++++---------- 5 files changed, 27 insertions(+), 25 deletions(-) diff --git a/cpu/cortexm_common/include/vectors_cortexm.h b/cpu/cortexm_common/include/vectors_cortexm.h index 52afe45a55ca..f84ce0030505 100644 --- a/cpu/cortexm_common/include/vectors_cortexm.h +++ b/cpu/cortexm_common/include/vectors_cortexm.h @@ -94,8 +94,8 @@ void hard_fault_default(void); /** * @brief Default memory manager behavior callback (weak function) * - * @retval 1 when the memory fault has been handled, - * @retval 0 otherwise. + * @retval >=0 when the memory fault has been handled, + * @retval < 0 otherwise. */ int mem_manage_handler(void); diff --git a/cpu/cortexm_common/thread_arch.c b/cpu/cortexm_common/thread_arch.c index c6731326f52f..faff4deab03a 100644 --- a/cpu/cortexm_common/thread_arch.c +++ b/cpu/cortexm_common/thread_arch.c @@ -88,6 +88,7 @@ */ #include +#include #include "sched.h" #include "thread.h" @@ -493,12 +494,12 @@ void __attribute__((naked)) __attribute__((used)) isr_svc(void) #endif } -__attribute__((weak))int +__attribute__((weak)) int svc_dispatch_handler(unsigned int svc_number, unsigned int *svc_args) { (void)svc_number; (void)svc_args; - return 0; + return -ENOTSUP; } static void __attribute__((used)) _svc_dispatch(unsigned int *svc_args) diff --git a/cpu/cortexm_common/vectors_cortexm.c b/cpu/cortexm_common/vectors_cortexm.c index dc03e4844ab3..c07ef8c41720 100644 --- a/cpu/cortexm_common/vectors_cortexm.c +++ b/cpu/cortexm_common/vectors_cortexm.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "cpu.h" #include "periph_cpu.h" @@ -473,14 +474,14 @@ void hard_fault_default(void) defined(CPU_CORE_CORTEX_M4) || defined(CPU_CORE_CORTEX_M4F) || \ defined(CPU_CORE_CORTEX_M7) -__attribute__((weak))int mem_manage_handler(void) +__attribute__((weak)) int mem_manage_handler(void) { - return 0; + return -ENOTSUP; } void mem_manage_default(void) { - if (mem_manage_handler() == 1) { + if (mem_manage_handler() >= 0) { return; } core_panic(PANIC_MEM_MANAGE, "MEM MANAGE HANDLER"); diff --git a/examples/advanced/xipfs/main.c b/examples/advanced/xipfs/main.c index 27948f2ca66c..5aea240c786f 100644 --- a/examples/advanced/xipfs/main.c +++ b/examples/advanced/xipfs/main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2025 Université de Lille + * Copyright (C) 2024-2025 Université de Lille * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -99,7 +99,7 @@ static int drop_file(const file_to_drop_t *file_to_drop) { int file_handle = vfs_open(file_to_drop->filename, O_RDONLY, 0); if (file_handle < 0) { - /** There's no executable file yet, let's drop one */ + /* There's no executable file yet, let's drop one */ int ret = xipfs_extended_driver_new_file( file_to_drop->filename, file_to_drop->bytesize, file_to_drop->is_executable ); @@ -109,7 +109,7 @@ static int drop_file(const file_to_drop_t *file_to_drop) { return EXIT_FAILURE; } - /** + /* * Fill it with data * Take care : vfs does not support O_APPEND with vfs_write, only O_WRONLY or O_RDWR */ diff --git a/pkg/xipfs/fs/xipfs_fs.c b/pkg/xipfs/fs/xipfs_fs.c index 6de68226e9f0..275ff16e8a14 100644 --- a/pkg/xipfs/fs/xipfs_fs.c +++ b/pkg/xipfs/fs/xipfs_fs.c @@ -739,28 +739,28 @@ int mem_manage_handler(void) uint32_t cfsr = SCB->CFSR; uintptr_t psp = __get_PSP(); if (xipfs_mem_manage_handler((void *)psp, mmfar, cfsr) == 0) { - return 1; + return 0; } - return 0; + return -EINVAL; } int svc_dispatch_handler(unsigned int svc_number, unsigned int *svc_args) { switch (svc_number) { - case XIPFS_ENTER_SVC_NUMBER: { - void *crt0_ctx = (void *)svc_args[0]; - void *entry_point = (void *)svc_args[1]; - void *stack_top = (void *)svc_args[2]; - xipfs_safe_exec_enter(crt0_ctx, entry_point, stack_top); - return 0; - } - case XIPFS_SYSCALL_SVC_NUMBER: { - xipfs_syscall_dispatcher(svc_args); - return 0; - } - default: - return -ENOTSUP; + case XIPFS_ENTER_SVC_NUMBER: { + void *crt0_ctx = (void *)svc_args[0]; + void *entry_point = (void *)svc_args[1]; + void *stack_top = (void *)svc_args[2]; + xipfs_safe_exec_enter(crt0_ctx, entry_point, stack_top); + return 0; + } + case XIPFS_SYSCALL_SVC_NUMBER: { + xipfs_syscall_dispatcher(svc_args); + return 0; + } + default: + return -ENOTSUP; } }