1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#!/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)
|