Working ASLR implementation.
ASLR for shared libraries is controlled by "-a" in ota_from_target_files.
Binary files are self-contained (supported by apriori/soslim).
Signed-off-by: Hristo Bojinov <hristo@google.com>
Change-Id: I500e325bf4a70a8d69a2ab9b2938e83dadb4e65d
diff --git a/tools/releasetools/edify_generator.py b/tools/releasetools/edify_generator.py
index 390bd4b..328700f 100644
--- a/tools/releasetools/edify_generator.py
+++ b/tools/releasetools/edify_generator.py
@@ -235,6 +235,20 @@
",\0".join(['"' + i + '"' for i in sorted(links)]) + ");")
self.script.append(self._WordWrap(cmd))
+ def RetouchBinaries(self, file_list):
+ """Execute the retouch instructions in files listed."""
+ cmd = ('retouch_binaries(' +
+ ', '.join(['"' + i[0] + '", "' + i[1] + '"' for i in file_list]) +
+ ');')
+ self.script.append(self._WordWrap(cmd))
+
+ def UndoRetouchBinaries(self, file_list):
+ """Undo the retouching (retouch to zero offset)."""
+ cmd = ('undo_retouch_binaries(' +
+ ', '.join(['"' + i[0] + '", "' + i[1] + '"' for i in file_list]) +
+ ');')
+ self.script.append(self._WordWrap(cmd))
+
def AppendExtra(self, extra):
"""Append text verbatim to the output script."""
self.script.append(extra)
diff --git a/tools/releasetools/ota_from_target_files b/tools/releasetools/ota_from_target_files
index 8cd1941..d249214 100755
--- a/tools/releasetools/ota_from_target_files
+++ b/tools/releasetools/ota_from_target_files
@@ -44,6 +44,8 @@
-e (--extra_script) <file>
Insert the contents of file at the end of the update script.
+ -a (--use_aslr)
+ Specify whether to build the package with ASLR enabled (off by default).
"""
import sys
@@ -75,6 +77,7 @@
OPTIONS.wipe_user_data = False
OPTIONS.omit_prereq = False
OPTIONS.extra_script = None
+OPTIONS.aslr_mode = False
OPTIONS.worker_threads = 3
def MostPopularKey(d, default):
@@ -91,6 +94,10 @@
symlink."""
return (info.external_attr >> 16) == 0120777
+def IsRegular(info):
+ """Return true if the zipfile.ZipInfo object passed in represents a
+ symlink."""
+ return (info.external_attr >> 28) == 010
class Item:
@@ -246,13 +253,15 @@
substitute=None):
"""Copies files underneath system/ in the input zip to the output
zip. Populates the Item class with their metadata, and returns a
- list of symlinks. output_zip may be None, in which case the copy is
- skipped (but the other side effects still happen). substitute is an
- optional dict of {output filename: contents} to be output instead of
- certain input files.
+ list of symlinks as well as a list of files that will be retouched.
+ output_zip may be None, in which case the copy is skipped (but the
+ other side effects still happen). substitute is an optional dict
+ of {output filename: contents} to be output instead of certain input
+ files.
"""
symlinks = []
+ retouch_files = []
for info in input_zip.infolist():
if info.filename.startswith("SYSTEM/"):
@@ -270,6 +279,9 @@
data = substitute[fn]
else:
data = input_zip.read(info.filename)
+ if info.filename.startswith("SYSTEM/lib/") and IsRegular(info):
+ retouch_files.append(("/system/" + basefilename,
+ sha.sha(data).hexdigest()))
output_zip.writestr(info2, data)
if fn.endswith("/"):
Item.Get(fn[:-1], dir=True)
@@ -277,7 +289,7 @@
Item.Get(fn, dir=False)
symlinks.sort()
- return symlinks
+ return (symlinks, retouch_files)
def SignOutput(temp_zip_name, output_zip_name):
@@ -375,8 +387,12 @@
script.UnpackPackageDir("recovery", "/system")
script.UnpackPackageDir("system", "/system")
- symlinks = CopySystemFiles(input_zip, output_zip)
+ (symlinks, retouch_files) = CopySystemFiles(input_zip, output_zip)
script.MakeSymlinks(symlinks)
+ if OPTIONS.aslr_mode:
+ script.RetouchBinaries(retouch_files)
+ else:
+ script.UndoRetouchBinaries(retouch_files)
boot_img = File("boot.img", common.BuildBootableImage(
os.path.join(OPTIONS.input_tmp, "BOOT")))
@@ -432,12 +448,17 @@
"""Load all the files from SYSTEM/... in a given target-files
ZipFile, and return a dict of {filename: File object}."""
out = {}
+ retouch_files = []
for info in z.infolist():
if info.filename.startswith("SYSTEM/") and not IsSymlink(info):
- fn = "system/" + info.filename[7:]
+ basefilename = info.filename[7:]
+ fn = "system/" + basefilename
data = z.read(info.filename)
out[fn] = File(fn, data)
- return out
+ if info.filename.startswith("SYSTEM/lib/") and IsRegular(info):
+ retouch_files.append(("/system/" + basefilename,
+ out[fn].sha1))
+ return (out, retouch_files)
DIFF_PROGRAM_BY_EXT = {
@@ -600,9 +621,9 @@
metadata=metadata)
print "Loading target..."
- target_data = LoadSystemFiles(target_zip)
+ (target_data, target_retouch_files) = LoadSystemFiles(target_zip)
print "Loading source..."
- source_data = LoadSystemFiles(source_zip)
+ (source_data, source_retouch_files) = LoadSystemFiles(source_zip)
verbatim_targets = []
patch_list = []
@@ -769,7 +790,7 @@
script.ShowProgress(0.1, 10)
- target_symlinks = CopySystemFiles(target_zip, None)
+ (target_symlinks, target_retouch_dummies) = CopySystemFiles(target_zip, None)
target_symlinks_d = dict([(i[1], i[0]) for i in target_symlinks])
temp_script = script.MakeTemporary()
@@ -778,7 +799,7 @@
# Note that this call will mess up the tree of Items, so make sure
# we're done with it.
- source_symlinks = CopySystemFiles(source_zip, None)
+ (source_symlinks, source_retouch_dummies) = CopySystemFiles(source_zip, None)
source_symlinks_d = dict([(i[1], i[0]) for i in source_symlinks])
# Delete all the symlinks in source that aren't in target. This
@@ -812,6 +833,10 @@
to_create.append((dest, link))
script.DeleteFiles([i[1] for i in to_create])
script.MakeSymlinks(to_create)
+ if OPTIONS.aslr_mode:
+ script.RetouchBinaries(target_retouch_files)
+ else:
+ script.UndoRetouchBinaries(target_retouch_files)
# Now that the symlinks are created, we can set all the
# permissions.
@@ -842,6 +867,8 @@
OPTIONS.omit_prereq = True
elif o in ("-e", "--extra_script"):
OPTIONS.extra_script = a
+ elif o in ("-a", "--use_aslr"):
+ OPTIONS.aslr_mode = True
elif o in ("--worker_threads"):
OPTIONS.worker_threads = int(a)
else:
@@ -849,14 +876,15 @@
return True
args = common.ParseOptions(argv, __doc__,
- extra_opts="b:k:i:d:wne:",
+ extra_opts="b:k:i:d:wne:a",
extra_long_opts=["board_config=",
"package_key=",
"incremental_from=",
"wipe_user_data",
"no_prereq",
"extra_script=",
- "worker_threads="],
+ "worker_threads=",
+ "use_aslr"],
extra_option_handler=option_handler)
if len(args) != 2: