flag to control mtp timeout kill behavior

This commit is contained in:
ed 2022-07-05 23:38:49 +02:00
parent 7998884a9d
commit 622358b172
3 changed files with 31 additions and 8 deletions

View file

@ -16,7 +16,7 @@ goes without saying, but this is HELLA DANGEROUS,
GIVES RCE TO ANYONE WHO HAVE UPLOAD PERMISSIONS GIVES RCE TO ANYONE WHO HAVE UPLOAD PERMISSIONS
example copyparty config to use this: example copyparty config to use this:
--urlform save,get -v.::w:c,e2d,e2t,mte=+a1:c,mtp=a1=ad,bin/mtag/very-bad-idea.py --urlform save,get -v.::w:c,e2d,e2t,mte=+a1:c,mtp=a1=ad,kn,bin/mtag/very-bad-idea.py
recommended deps: recommended deps:
apt install xdotool libnotify-bin apt install xdotool libnotify-bin
@ -64,7 +64,7 @@ EOF
chmod 755 /usr/local/bin/chromium-browser chmod 755 /usr/local/bin/chromium-browser
# start the server (note: replace `-v.::rw:` with `-v.::w:` to disallow retrieving uploaded stuff) # start the server (note: replace `-v.::rw:` with `-v.::w:` to disallow retrieving uploaded stuff)
cd ~/Downloads; python3 copyparty-sfx.py --urlform save,get -v.::rw:c,e2d,e2t,mte=+a1:c,mtp=a1=ad,very-bad-idea.py cd ~/Downloads; python3 copyparty-sfx.py --urlform save,get -v.::rw:c,e2d,e2t,mte=+a1:c,mtp=a1=ad,kn,very-bad-idea.py
""" """

View file

@ -10,7 +10,7 @@ import sys
from .__init__ import PY2, WINDOWS, unicode from .__init__ import PY2, WINDOWS, unicode
from .bos import bos from .bos import bos
from .util import REKOBO_LKEY, fsenc, retchk, runcmd, uncyg from .util import REKOBO_LKEY, fsenc, retchk, runcmd, uncyg, min_ex
try: try:
from typing import Any, Union from typing import Any, Union
@ -44,6 +44,7 @@ class MParser(object):
self.timeout = 30 self.timeout = 30
self.force = False self.force = False
self.kill = "t" # tree; all children recursively
self.audio = "y" self.audio = "y"
self.ext = [] self.ext = []
@ -66,6 +67,10 @@ class MParser(object):
self.audio = arg[1:] # [r]equire [n]ot [d]ontcare self.audio = arg[1:] # [r]equire [n]ot [d]ontcare
continue continue
if arg.startswith("k"):
self.kill = arg[1:] # [t]ree [m]ain [n]one
continue
if arg == "f": if arg == "f":
self.force = True self.force = True
continue continue
@ -499,7 +504,7 @@ class MTag(object):
if parser.bin.endswith(".py"): if parser.bin.endswith(".py"):
cmd = [sys.executable] + cmd cmd = [sys.executable] + cmd
args = {"env": env, "timeout": parser.timeout} args = {"env": env, "timeout": parser.timeout, "kill": parser.kill}
if WINDOWS: if WINDOWS:
args["creationflags"] = 0x4000 args["creationflags"] = 0x4000
@ -521,6 +526,8 @@ class MTag(object):
if tag and tag in zj: if tag and tag in zj:
ret[tag] = zj[tag] ret[tag] = zj[tag]
except: except:
pass if self.args.mtag_v:
t = "mtag error: tagname {}, parser {}, file {} => {}"
self.log(t.format(tagname, parser.bin, abspath, min_ex()))
return ret return ret

View file

@ -1565,6 +1565,7 @@ def killtree(root: int) -> None:
def runcmd( def runcmd(
argv: Union[list[bytes], list[str]], timeout: Optional[int] = None, **ka: Any argv: Union[list[bytes], list[str]], timeout: Optional[int] = None, **ka: Any
) -> tuple[int, str, str]: ) -> tuple[int, str, str]:
kill = ka.pop("kill", "t") # [t]ree [m]ain [n]one
p = sp.Popen(argv, stdout=sp.PIPE, stderr=sp.PIPE, **ka) p = sp.Popen(argv, stdout=sp.PIPE, stderr=sp.PIPE, **ka)
if not timeout or PY2: if not timeout or PY2:
stdout, stderr = p.communicate() stdout, stderr = p.communicate()
@ -1572,12 +1573,27 @@ def runcmd(
try: try:
stdout, stderr = p.communicate(timeout=timeout) stdout, stderr = p.communicate(timeout=timeout)
except sp.TimeoutExpired: except sp.TimeoutExpired:
killtree(p.pid) if kill == "n":
stdout, stderr = p.communicate() return -18, "", "" # SIGCONT; leave it be
elif kill == "m":
p.kill()
else:
killtree(p.pid)
try:
stdout, stderr = p.communicate(timeout=1)
except:
stdout = b""
stderr = b""
stdout = stdout.decode("utf-8", "replace") stdout = stdout.decode("utf-8", "replace")
stderr = stderr.decode("utf-8", "replace") stderr = stderr.decode("utf-8", "replace")
return p.returncode, stdout, stderr
rc = p.returncode
if rc is None:
rc = -14 # SIGALRM; failed to kill
return rc, stdout, stderr
def chkcmd(argv: Union[list[bytes], list[str]], **ka: Any) -> tuple[str, str]: def chkcmd(argv: Union[list[bytes], list[str]], **ka: Any) -> tuple[str, str]: