Поведение execveat(2) / fexecve(3) с подпроцессом Python
Как я могу получить модуль подпроцесса Python для принятия fd вместо пути (== execveat () с AT_EMPTY_PATH
)? Пример:
subprocess.Popen (["argv0", "argv1"], shell=False,
executable=os.open ("/proc/self/exe",
os.O_RDONLY
| os.O_CLOEXEC))
В Python 3.6.5 это не удается из-за TypeError.
Целью, конечно, является избежание TOCTTOU между проверкой двоичного файла и вызовом execve (2).
Я знаю, что os.execve() можно использовать и с fds, но я бы предпочел не переопределять модуль подпроцесса поверх этого.
1 ответ
CPython-х _posixsubprocess
внутренняя реализация subprocess
для POSIX, не поддерживает ни fexecve(3)
ни execveat(2)
, Если вы можете предположить, /proc
монтируется, тогда просто укажите /proc/self/fd/N
(где N - желаемый fd) в качестве исполняемого файла. Это также то, что fexecve(3)
возвращается к более старым ядрам. Смотрите страницу руководства Linux proc(5)
для деталей о /proc/self/fd
,
РЕДАКТИРОВАТЬ Пример:
def spawn_exefd(args, fd, bufsize=-1, *args, **kwargs):
return subprocess.Popen(args, bufsize, "/proc/self/fd/%d" % (fd,), *args, **kwargs)
#import fcntl # py2
import os
fd = os.open("/bin/sh", os.O_RDONLY | os.O_CLOEXEC)
#fcntl.fcntl(fd, fcntl.F_SETFD, fcntl.fcntl(fd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC) # py2
spawn_exefd(["sh", "-i"], fd)