#!/usr/bin/env python2 #-*- coding: utf-8 -*- # # ===-- klee-chroot-env ---------------------------------------------------===## # # The KLEE Symbolic Virtual Machine # # This file is distributed under the University of Illinois Open Source # License. See LICENSE.TXT for details. # # ===----------------------------------------------------------------------===## # # 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)