Поведение 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)
Другие вопросы по тегам