python-3.xsubprocesschrootjail

How Can I get the result of child process of a command executed in subprocess?


I want run Valgrind in a jail that created before and copyied required file in Jail. We know Valgrind generate two files XML and TXT files. I want to run python script that can cache the results of Valgrind files (XML and TXT file) and carry them to out of Jail. For example we have a function that run Valgrind in the Jail. Below code show it:

import os
def run_valgrind_in_jail(chroot_path, command):
    os.chdir(chroot_path)
    os.chroot(chroot_path)
    return subprocess.run(['valgrind', '--xml=yes','--leak-check=full', '--verbose',
                           '--xml-file={}_valgrind.xml'.format(command),
                           '--log-file={}_valgrind.txt'.format(command),command], 
                          stderr=subprocess.PIPE, stdout=subprocess.PIPE)

Valgrind generate two file XML and txt and I want to carry them to out of chroot (jail).

How can I get the output process of Valgrind and carry out to out of Jail.


Solution

  • You're putting your whole program in jail, not just the subprocess. Use a preexec_fn so only the subprocess is in the jail, not the rest of your Python program, and then you'll find your output files in the chroot_path directory:

    import os, subprocess
    
    class Jailer(object):
        def __init__(self, chroot_path):
            self.chroot_path = chroot_path
        def __call__(self):
            os.chdir(self.chroot_path)
            os.chroot(self.chroot_path)
    
    def run_valgrind_in_jail(chroot_path, command):
        proc = subprocess.run(['valgrind', '--xml=yes','--leak-check=full', '--verbose',
                               f'--xml-file={command}_valgrind.xml',
                               f'--log-file={command}_valgrind.txt',
                               command], 
                              stderr=subprocess.PIPE, stdout=subprocess.PIPE,
                              preexec_fn=Jailer(chroot_path))
        xml_file = open(os.path.join(chroot_path, f'{command}_valgrind.xml'))
        log_file = open(os.path.join(chroot_path, f'{command}_valgrind.txt'))
        return (proc, xml_file, log_file)