summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott@tannewt.org>2019-02-19 14:45:45 -0800
committerScott Shawcroft <scott@tannewt.org>2019-02-21 10:45:41 -0800
commit1a0596a2fbb68c1285ec59606d03a610ee94ca47 (patch)
treeca91a0b4816a7703afbc98e63f22563d17e5569a
parentb1e8c4367987944c3faaad613142fec974840044 (diff)
Add option to disable the concurrent write protection
This allows writing to the filesystem from the host computer and CircuitPython by increasing the risk of filesystem corruption.
-rw-r--r--extmod/vfs_fat.h2
-rw-r--r--extmod/vfs_fat_file.c3
m---------lib/tinyusb0
-rwxr-xr-xmain.c7
-rw-r--r--shared-bindings/storage/__init__.c23
-rw-r--r--shared-bindings/storage/__init__.h2
-rw-r--r--shared-module/storage/__init__.c5
-rw-r--r--supervisor/filesystem.h9
-rw-r--r--supervisor/flash.h1
-rw-r--r--supervisor/shared/filesystem.c32
-rw-r--r--supervisor/shared/flash.c20
-rw-r--r--supervisor/shared/usb/usb_msc_flash.c4
12 files changed, 68 insertions, 40 deletions
diff --git a/extmod/vfs_fat.h b/extmod/vfs_fat.h
index dd5e5ffcb..08b03d0d1 100644
--- a/extmod/vfs_fat.h
+++ b/extmod/vfs_fat.h
@@ -38,6 +38,8 @@
#define FSUSER_NO_FILESYSTEM (0x0008) // the block device has no filesystem on it
// Device is writable over USB and read-only to MicroPython.
#define FSUSER_USB_WRITABLE (0x0010)
+// Bit set when the above flag is checked before opening a file for write.
+#define FSUSER_CONCURRENT_WRITE_PROTECTED (0x0020)
typedef struct _fs_user_mount_t {
mp_obj_base_t base;
diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c
index 690073ce4..6aad1884c 100644
--- a/extmod/vfs_fat_file.c
+++ b/extmod/vfs_fat_file.c
@@ -34,6 +34,7 @@
#include "py/mperrno.h"
#include "lib/oofatfs/ff.h"
#include "extmod/vfs_fat.h"
+#include "supervisor/filesystem.h"
// this table converts from FRESULT to POSIX errno
const byte fresult_to_errno_table[20] = {
@@ -187,7 +188,7 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar
}
}
assert(vfs != NULL);
- if ((vfs->flags & FSUSER_USB_WRITABLE) != 0 && (mode & FA_WRITE) != 0) {
+ if ((mode & FA_WRITE) != 0 && !filesystem_is_writable_by_python(vfs)) {
mp_raise_OSError(MP_EROFS);
}
diff --git a/lib/tinyusb b/lib/tinyusb
-Subproject 29b49199beb8e9b5fead83e5cd36105f8746f1d
+Subproject 55874813f82157b7509729b1a0c66e68f86e2d0
diff --git a/main.c b/main.c
index 68ee66d02..f0913db6e 100755
--- a/main.c
+++ b/main.c
@@ -323,12 +323,12 @@ void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
mp_hal_delay_ms(1500);
// USB isn't up, so we can write the file.
- filesystem_writable_by_python(true);
+ filesystem_set_internal_writable_by_usb(false);
f_open(fs, boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS);
// Switch the filesystem back to non-writable by Python now instead of later,
// since boot.py might change it back to writable.
- filesystem_writable_by_python(false);
+ filesystem_set_internal_writable_by_usb(true);
// Write version info to boot_out.txt.
mp_hal_stdout_tx_str(MICROPY_FULL_VERSION_INFO);
@@ -416,7 +416,8 @@ int __attribute__((used)) main(void) {
// By default our internal flash is readonly to local python code and
// writable over USB. Set it here so that boot.py can change it.
- filesystem_writable_by_python(false);
+ filesystem_set_internal_concurrent_write_protection(true);
+ filesystem_set_internal_writable_by_usb(true);
run_boot_py(safe_mode);
diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c
index 3484b9af8..d7af48df0 100644
--- a/shared-bindings/storage/__init__.c
+++ b/shared-bindings/storage/__init__.c
@@ -48,16 +48,18 @@
//| directly.
//|
-//| .. function:: mount(filesystem, mount_path, \*, readonly=False)
+//| .. function:: mount(filesystem, mount_path, \*, readonly=False, disable_concurrent_write_protection=False)
//|
//| Mounts the given filesystem object at the given path.
//|
//| This is the CircuitPython analog to the UNIX ``mount`` command.
//|
+//| :param bool readonly: True when the filesystem should be readonly to CircuitPython.
+//|
mp_obj_t storage_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_readonly };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_false} },
+ { MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
};
// parse args
@@ -77,7 +79,7 @@ mp_obj_t storage_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_arg
mp_raise_ValueError(translate("filesystem must provide mount method"));
}
- common_hal_storage_mount(vfs_obj, mnt_str, mp_obj_is_true(args[ARG_readonly].u_obj));
+ common_hal_storage_mount(vfs_obj, mnt_str, args[ARG_readonly].u_bool);
return mp_const_none;
}
@@ -101,14 +103,21 @@ mp_obj_t storage_umount(mp_obj_t mnt_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(storage_umount_obj, storage_umount);
-//| .. function:: remount(mount_path, readonly=False)
+//| .. function:: remount(mount_path, readonly=False, *, disable_concurrent_write_protection=False)
//|
//| Remounts the given path with new parameters.
//|
+//| :param bool readonly: True when the filesystem should be readonly to CircuitPython.
+//| :param bool disable_concurrent_write_protection: When True, the check that makes sure the
+//| underlying filesystem data is written by one computer is disabled. Disabling the protection
+//| allows CircuitPython and a host to write to the same filesystem with the risk that the
+//| filesystem will be corrupted.
+//|
mp_obj_t storage_remount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum { ARG_readonly };
+ enum { ARG_readonly, ARG_disable_concurrent_write_protection };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_readonly, MP_ARG_BOOL | MP_ARG_REQUIRED, {.u_bool = false} },
+ { MP_QSTR_readonly, MP_ARG_BOOL, {.u_bool = false} },
+ { MP_QSTR_disable_concurrent_write_protection, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
};
// get the mount point
@@ -118,7 +127,7 @@ mp_obj_t storage_remount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
- common_hal_storage_remount(mnt_str, args[ARG_readonly].u_bool);
+ common_hal_storage_remount(mnt_str, args[ARG_readonly].u_bool, args[ARG_disable_concurrent_write_protection].u_bool);
return mp_const_none;
}
diff --git a/shared-bindings/storage/__init__.h b/shared-bindings/storage/__init__.h
index 6a0cb9fc7..7851b9e29 100644
--- a/shared-bindings/storage/__init__.h
+++ b/shared-bindings/storage/__init__.h
@@ -33,7 +33,7 @@
void common_hal_storage_mount(mp_obj_t vfs_obj, const char* path, bool readonly);
void common_hal_storage_umount_path(const char* path);
void common_hal_storage_umount_object(mp_obj_t vfs_obj);
-void common_hal_storage_remount(const char* path, bool readonly);
+void common_hal_storage_remount(const char* path, bool readonly, bool disable_concurrent_write_protection);
mp_obj_t common_hal_storage_getmount(const char* path);
void common_hal_storage_erase_filesystem(void);
diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c
index f09edd785..215e1356a 100644
--- a/shared-module/storage/__init__.c
+++ b/shared-module/storage/__init__.c
@@ -143,7 +143,7 @@ mp_obj_t common_hal_storage_getmount(const char *mount_path) {
return storage_object_from_path(mount_path);
}
-void common_hal_storage_remount(const char *mount_path, bool readonly) {
+void common_hal_storage_remount(const char *mount_path, bool readonly, bool disable_concurrent_write_protection) {
if (strcmp(mount_path, "/") != 0) {
mp_raise_OSError(MP_EINVAL);
}
@@ -156,7 +156,8 @@ void common_hal_storage_remount(const char *mount_path, bool readonly) {
}
#endif
- supervisor_flash_set_usb_writable(readonly);
+ filesystem_set_internal_writable_by_usb(readonly);
+ filesystem_set_internal_concurrent_write_protection(!disable_concurrent_write_protection);
}
void common_hal_storage_erase_filesystem(void) {
diff --git a/supervisor/filesystem.h b/supervisor/filesystem.h
index eb9e65c09..76f235f47 100644
--- a/supervisor/filesystem.h
+++ b/supervisor/filesystem.h
@@ -29,9 +29,16 @@
#include <stdbool.h>
+#include "extmod/vfs_fat.h"
+
void filesystem_init(bool create_allowed, bool force_create);
void filesystem_flush(void);
-void filesystem_writable_by_python(bool writable);
bool filesystem_present(void);
+void filesystem_set_internal_writable_by_usb(bool usb_writable);
+void filesystem_set_internal_concurrent_write_protection(bool concurrent_write_protection);
+void filesystem_set_writable_by_usb(fs_user_mount_t *vfs, bool usb_writable);
+void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concurrent_write_protection);
+bool filesystem_is_writable_by_python(fs_user_mount_t *vfs);
+bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs);
#endif // MICROPY_INCLUDED_SUPERVISOR_FILESYSTEM_H
diff --git a/supervisor/flash.h b/supervisor/flash.h
index ae6a44fd0..edf43f4b1 100644
--- a/supervisor/flash.h
+++ b/supervisor/flash.h
@@ -37,7 +37,6 @@
#include "supervisor/internal_flash.h"
#endif
-void supervisor_flash_set_usb_writable(bool usb_writable);
void supervisor_flash_init(void);
uint32_t supervisor_flash_get_block_size(void);
uint32_t supervisor_flash_get_block_count(void);
diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c
index 3382d28be..0ef978ef2 100644
--- a/supervisor/shared/filesystem.c
+++ b/supervisor/shared/filesystem.c
@@ -24,6 +24,8 @@
* THE SOFTWARE.
*/
+#include "supervisor/filesystem.h"
+
#include "extmod/vfs_fat.h"
#include "lib/oofatfs/ff.h"
#include "lib/oofatfs/diskio.h"
@@ -92,16 +94,42 @@ void filesystem_flush(void) {
supervisor_flash_flush();
}
-void filesystem_writable_by_python(bool writable) {
+void filesystem_set_internal_writable_by_usb(bool writable) {
fs_user_mount_t *vfs = &_internal_vfs;
- if (!writable) {
+ filesystem_set_writable_by_usb(vfs, writable);
+}
+
+void filesystem_set_writable_by_usb(fs_user_mount_t *vfs, bool usb_writable) {
+ if (usb_writable) {
vfs->flags |= FSUSER_USB_WRITABLE;
} else {
vfs->flags &= ~FSUSER_USB_WRITABLE;
}
}
+bool filesystem_is_writable_by_python(fs_user_mount_t *vfs) {
+ return (vfs->flags & FSUSER_CONCURRENT_WRITE_PROTECTED) == 0 ||
+ (vfs->flags & FSUSER_USB_WRITABLE) == 0;
+}
+
+bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs) {
+ return (vfs->flags & FSUSER_CONCURRENT_WRITE_PROTECTED) == 0 ||
+ (vfs->flags & FSUSER_USB_WRITABLE) != 0;
+}
+
+void filesystem_set_internal_concurrent_write_protection(bool concurrent_write_protection) {
+ filesystem_set_concurrent_write_protection(&_internal_vfs, concurrent_write_protection);
+}
+
+void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concurrent_write_protection) {
+ if (concurrent_write_protection) {
+ vfs->flags |= FSUSER_CONCURRENT_WRITE_PROTECTED;
+ } else {
+ vfs->flags &= ~FSUSER_CONCURRENT_WRITE_PROTECTED;
+ }
+}
+
bool filesystem_present(void) {
return true;
}
diff --git a/supervisor/shared/flash.c b/supervisor/shared/flash.c
index 8be21e5d0..6b1f24b4b 100644
--- a/supervisor/shared/flash.c
+++ b/supervisor/shared/flash.c
@@ -33,26 +33,6 @@
#define PART1_START_BLOCK (0x1)
-void supervisor_flash_set_usb_writable(bool usb_writable) {
- mp_vfs_mount_t* current_mount = MP_STATE_VM(vfs_mount_table);
- for (uint8_t i = 0; current_mount != NULL; i++) {
- if (i == VFS_INDEX) {
- break;
- }
- current_mount = current_mount->next;
- }
- if (current_mount == NULL) {
- return;
- }
- fs_user_mount_t *vfs = (fs_user_mount_t *) current_mount->obj;
-
- if (usb_writable) {
- vfs->flags |= FSUSER_USB_WRITABLE;
- } else {
- vfs->flags &= ~FSUSER_USB_WRITABLE;
- }
-}
-
// there is a singleton Flash object
const mp_obj_type_t supervisor_flash_type;
STATIC const mp_obj_base_t supervisor_flash_obj = {&supervisor_flash_type};
diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c
index 658aab0d8..f6f0fa9c3 100644
--- a/supervisor/shared/usb/usb_msc_flash.c
+++ b/supervisor/shared/usb/usb_msc_flash.c
@@ -34,6 +34,7 @@
#include "lib/oofatfs/ff.h"
#include "py/mpstate.h"
+#include "supervisor/filesystem.h"
#include "supervisor/shared/autoreload.h"
#define MSC_FLASH_BLOCK_SIZE 512
@@ -148,8 +149,7 @@ bool tud_msc_is_writable_cb(uint8_t lun) {
if (vfs == NULL) {
return false;
}
- if (vfs->writeblocks[0] == MP_OBJ_NULL ||
- (vfs->flags & FSUSER_USB_WRITABLE) == 0) {
+ if (vfs->writeblocks[0] == MP_OBJ_NULL || !filesystem_is_writable_by_usb(vfs)) {
return false;
}
return true;