Skip to content

Commit

Permalink
tools/mpremote: Prevent access outside mounted dir.
Browse files Browse the repository at this point in the history
Signed-off-by: Damien George <damien@micropython.org>
  • Loading branch information
dpgeorge committed May 11, 2021
1 parent 01a1e02 commit 275d3c8
Showing 1 changed file with 27 additions and 6 deletions.
33 changes: 27 additions & 6 deletions tools/mpremote/src/mpremote/pyboardextended.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os, re, serial, struct, time
from errno import EPERM
from .console import VT_ENABLED

try:
Expand Down Expand Up @@ -262,7 +263,10 @@ def ilistdir(self, path):
c = self.cmd
c.begin(CMD_ILISTDIR_START)
c.wr_str(self.path + path)
res = c.rd_s8()
c.end()
if res < 0:
raise OSError(-res)
def next():
while True:
c.begin(CMD_ILISTDIR_NEXT)
Expand Down Expand Up @@ -350,13 +354,20 @@ def wr_str(self, s):
def log_cmd(self, msg):
print(f"[{msg}]", end="\r\n")

def path_check(self, path):
parent = os.path.realpath(self.root)
child = os.path.realpath(path)
if parent != os.path.commonpath([parent, child]):
raise OSError(EPERM, "") # File is outside mounted dir

def do_stat(self):
path = self.root + self.rd_str()
# self.log_cmd(f"stat {path}")
try:
self.path_check(path)
stat = os.stat(path)
except OSError as er:
self.wr_s8(-abs(er.args[0]))
self.wr_s8(-abs(er.errno))
else:
self.wr_s8(0)
# Note: st_ino would need to be 64-bit if added here
Expand All @@ -368,8 +379,14 @@ def do_stat(self):

def do_ilistdir_start(self):
path = self.root + self.rd_str()
self.data_ilistdir[0] = path
self.data_ilistdir[1] = os.listdir(path)
try:
self.path_check(path)
self.wr_s8(0)
except OSError as er:
self.wr_s8(-abs(er.errno))
else:
self.data_ilistdir[0] = path
self.data_ilistdir[1] = os.listdir(path)

def do_ilistdir_next(self):
if self.data_ilistdir[1]:
Expand All @@ -389,9 +406,10 @@ def do_open(self):
mode = self.rd_str()
# self.log_cmd(f"open {path} {mode}")
try:
self.path_check(path)
f = open(path, mode)
except OSError as er:
self.wr_s8(-abs(er.args[0]))
self.wr_s8(-abs(er.errno))
else:
is_text = mode.find("b") == -1
try:
Expand Down Expand Up @@ -437,21 +455,24 @@ def do_remove(self):
path = self.root + self.rd_str()
# self.log_cmd(f"remove {path}")
try:
self.path_check(path)
os.remove(path)
ret = 0
except OSError as er:
ret = -abs(er.args[0])
ret = -abs(er.errno)
self.wr_s32(ret)

def do_rename(self):
old = self.root + self.rd_str()
new = self.root + self.rd_str()
# self.log_cmd(f"rename {old} {new}")
try:
self.path_check(old)
self.path_check(new)
os.rename(old, new)
ret = 0
except OSError as er:
ret = -abs(er.args[0])
ret = -abs(er.errno)
self.wr_s32(ret)

cmd_table = {
Expand Down

0 comments on commit 275d3c8

Please sign in to comment.