diff --git a/pycardium/modules/fat_file.c b/pycardium/modules/fat_file.c index a5ddcd8ae7684f183b00a38ff5c3eba64568d5ca..b030466fa407de2da598fbb1f8d1e15754e21378 100644 --- a/pycardium/modules/fat_file.c +++ b/pycardium/modules/fat_file.c @@ -1,5 +1,5 @@ /* - * based on micropytohn/ports/unix/file.c + * based on micropython/ports/unix/file.c */ #include <stdio.h> @@ -12,6 +12,24 @@ #include "epicardium.h" +#include <strings.h> + +bool filename_restricted(const char *fname) +{ + // files that cannot be opened in write modes + const char *const forbidden_files[] = { + "cardio.bin", "menu.py", "main.py", "cardio.cfg" + }; + for (int i = 0; + i < sizeof(forbidden_files) / sizeof(forbidden_files[0]); + i++) { + if (strcasecmp(fname, forbidden_files[i]) == 0) { + return true; + } + } + return false; +} + extern const mp_obj_type_t mp_type_textio; #if MICROPY_PY_IO_FILEIO extern const mp_obj_type_t mp_type_fileio; @@ -120,8 +138,9 @@ STATIC const mp_arg_t file_open_args[] = { STATIC mp_obj_t file_open(const mp_obj_type_t *type, mp_arg_val_t *args) { - const char *modeString = mp_obj_str_get_str(args[1].u_obj); - const char *mode_s = modeString; + bool potentially_critical_access = false; + const char *modeString = mp_obj_str_get_str(args[1].u_obj); + const char *mode_s = modeString; // modes r w x a + are handled on epicardium side, binary / text // is relevant for python type so look for these here while (*mode_s) { @@ -134,6 +153,12 @@ STATIC mp_obj_t file_open(const mp_obj_type_t *type, mp_arg_val_t *args) case 't': type = &mp_type_textio; break; + case 'w': + case 'x': + case 'a': + case '+': + potentially_critical_access = true; + break; } } @@ -141,7 +166,12 @@ STATIC mp_obj_t file_open(const mp_obj_type_t *type, mp_arg_val_t *args) o->base.type = type; const char *fname = mp_obj_str_get_str(args[0].u_obj); - int res = epic_file_open(fname, modeString); + + if (potentially_critical_access && filename_restricted(fname)) { + mp_raise_OSError(-EPERM); + } + + int res = epic_file_open(fname, modeString); if (res < 0) { m_del_obj(fat_py_file_obj_t, o); mp_raise_OSError(-res);