summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/reference/mpremote.rst9
-rw-r--r--tools/mpremote/mpremote/main.py17
-rw-r--r--tools/mpremote/mpremote/pyboardextended.py15
3 files changed, 33 insertions, 8 deletions
diff --git a/docs/reference/mpremote.rst b/docs/reference/mpremote.rst
index 727431fcf..2bbed56b8 100644
--- a/docs/reference/mpremote.rst
+++ b/docs/reference/mpremote.rst
@@ -133,13 +133,20 @@ The full list of supported commands are:
.. code-block:: bash
- $ mpremote mount <local-dir>
+ $ mpremote mount [options] <local-dir>
During usage, Ctrl-D will soft-reboot and normally reconnect the mount automatically.
If the unit has a main.py running at startup however the remount cannot occur.
In this case a raw mode soft reboot can be used: Ctrl-A Ctrl-D to reboot,
then Ctrl-B to get back to normal repl at which point the mount will be ready.
+ Options are:
+
+ - ``-l``, ``--unsafe-links``: By default an error will be raised if the device
+ accesses a file or directory which is outside (up one or more directory levels) the
+ local directory that is mounted. This option disables this check for symbolic
+ links, allowing the device to follow symbolic links outside of the local directory.
+
- unmount the local directory from the remote device:
.. code-block:: bash
diff --git a/tools/mpremote/mpremote/main.py b/tools/mpremote/mpremote/main.py
index 50ad73cc1..ccf174bb5 100644
--- a/tools/mpremote/mpremote/main.py
+++ b/tools/mpremote/mpremote/main.py
@@ -41,7 +41,16 @@ _COMMANDS = {
"disconnect": (False, False, 0, "disconnect current device"),
"resume": (False, False, 0, "resume a previous mpremote session (will not auto soft-reset)"),
"soft-reset": (False, True, 0, "perform a soft-reset of the device"),
- "mount": (True, False, 1, "mount local directory on device"),
+ "mount": (
+ True,
+ False,
+ 1,
+ """\
+ mount local directory on device
+ options:
+ --unsafe-links, -l
+ follow symbolic links pointing outside of local directory""",
+ ),
"umount": (True, False, 0, "unmount the local directory"),
"repl": (
False,
@@ -516,8 +525,12 @@ def main():
pyb.enter_raw_repl(soft_reset=True)
auto_soft_reset = False
elif cmd == "mount":
+ unsafe_links = False
+ if args[0] == "--unsafe-links" or args[0] == "-l":
+ args.pop(0)
+ unsafe_links = True
path = args.pop(0)
- pyb.mount_local(path)
+ pyb.mount_local(path, unsafe_links=unsafe_links)
print(f"Local directory {path} is mounted at /remote")
elif cmd == "umount":
pyb.umount_local()
diff --git a/tools/mpremote/mpremote/pyboardextended.py b/tools/mpremote/mpremote/pyboardextended.py
index ccdb37a0c..d3b4cb6d8 100644
--- a/tools/mpremote/mpremote/pyboardextended.py
+++ b/tools/mpremote/mpremote/pyboardextended.py
@@ -351,12 +351,13 @@ fs_hook_code = re.sub("buf4", "b4", fs_hook_code)
class PyboardCommand:
- def __init__(self, fin, fout, path):
+ def __init__(self, fin, fout, path, unsafe_links=False):
self.fin = fin
self.fout = fout
self.root = path + "/"
self.data_ilistdir = ["", []]
self.data_files = []
+ self.unsafe_links = unsafe_links
def rd_s8(self):
return struct.unpack("<b", self.fin.read(1))[0]
@@ -397,8 +398,12 @@ class PyboardCommand:
print(f"[{msg}]", end="\r\n")
def path_check(self, path):
- parent = os.path.realpath(self.root)
- child = os.path.realpath(path)
+ if not self.unsafe_links:
+ parent = os.path.realpath(self.root)
+ child = os.path.realpath(path)
+ else:
+ parent = os.path.abspath(self.root)
+ child = os.path.abspath(path)
if parent != os.path.commonpath([parent, child]):
raise OSError(EPERM, "") # File is outside mounted dir
@@ -612,13 +617,13 @@ class PyboardExtended(Pyboard):
self.device_name = dev
self.mounted = False
- def mount_local(self, path):
+ def mount_local(self, path, unsafe_links=False):
fout = self.serial
if self.eval('"RemoteFS" in globals()') == b"False":
self.exec_(fs_hook_code)
self.exec_("__mount()")
self.mounted = True
- self.cmd = PyboardCommand(self.serial, fout, path)
+ self.cmd = PyboardCommand(self.serial, fout, path, unsafe_links=unsafe_links)
self.serial = SerialIntercept(self.serial, self.cmd)
def write_ctrl_d(self, out_callback):