diff options
Diffstat (limited to 'scripts/klee-chroot-env')
-rwxr-xr-x | scripts/klee-chroot-env | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/scripts/klee-chroot-env b/scripts/klee-chroot-env new file mode 100755 index 00000000..3b524d8e --- /dev/null +++ b/scripts/klee-chroot-env @@ -0,0 +1,87 @@ +#!/usr/bin/env python2 +#-*- coding: utf-8 -*- +# +# Buiding chroot environment for the program under test. +# +# This script uses `ldd' to get the shared libraries required by a program, +# and copies those libraries to the directory for chroot'ing, maintaining +# each library's relative path against root directory. +# +# Usage example: +# $ ./klee-chroot-env /tmp/sandbox `which rm` # build env for 'rm' +# $ cp `which rm` /tm/sandbox/rm # copy the binary into the jail +# $ sudo setcap SYS_CAP_CHROOT+ep `which klee-replay` +# # give klee-replay the capability to call 'chroot' system call +# $ klee-replay --chroot-to-dir=/tmp/sandbox /tmp/sandbox/rm /path/to/ktest +# # replay some ktest in chroot jail rooted at /tmp/sandbox + +import sys +import os +import shutil +import re + +from subprocess import Popen, PIPE + + +def get_shared_library_dependency(program): + """Calls `ldd' to get the shared library dependency of a `program'.""" + + cmd = "ldd %s" % program + prog = Popen(cmd.split(), stdout=PIPE, stderr=PIPE, shell=False) + out, err = prog.communicate(None) + prog.stdout.close() + prog.stderr.close() + + regexp = re.compile(r"\s*\(\S+\)\s*") + + dep = out.splitlines() + dep = [e.strip() for e in dep] + dep = [regexp.sub("", e) for e in dep] + dep = [e for e in dep if not e.startswith("linux-vdso.so")] + libs = [] + for e in dep: + if (" => " in e): + libs.append(e.split(" => ")) + else: + libs.append((os.path.basename(e), e)) + + # Outputs a list of (link-name, original-path) pairs. + return libs + + +def build_environment(root, libs): + """Copies all library dependencies to the specified `root' dir.""" + + if not os.path.exists(root): + os.makedirs(root) + os.chdir(root) + + for e in libs: + link_name = e[0] + original_path = e[1] + relative_dir = os.path.dirname(e[1]).lstrip("/") + chrooted_path = root + os.path.dirname(e[1]) + "/" + link_name + if not os.path.exists(relative_dir): + os.makedirs(relative_dir) + shutil.copyfile(original_path, chrooted_path) + shutil.copymode(original_path, chrooted_path) + + +def usage(): + print("Usage: %s /path/to/root/dir /path/to/program" % sys.argv[0]) + + +if __name__ == "__main__": + if (len(sys.argv) != 3): + usage() + exit(1) + + rootdir = sys.argv[1] + program = sys.argv[2] + + if not os.path.isfile(program) or not os.access(program, os.X_OK): + print("Error: executable not existing or not executable") + exit(1) + + libs = get_shared_library_dependency(program) + build_environment(rootdir, libs) |