diff options
author | Kyle Keen <keenerd@gmail.com> | 2016-07-21 13:02:10 -0400 |
---|---|---|
committer | Kyle Keen <keenerd@gmail.com> | 2016-07-21 13:02:10 -0400 |
commit | 795bc4f410ec3312f6958b7ff37072a8705e8919 (patch) | |
tree | a800e7e374a9d3cf685f3230b840ad4700ea8df6 | |
parent | 2746b1ded157f89a50dd1be59932f5b5a044e8f4 (diff) | |
download | namcap-795bc4f410ec3312f6958b7ff37072a8705e8919.tar.gz namcap-795bc4f410ec3312f6958b7ff37072a8705e8919.zip |
Use elftools in rpath
Signed-off-by: Kyle Keen <keenerd@gmail.com>
-rw-r--r-- | Namcap/rules/rpath.py | 55 |
1 files changed, 19 insertions, 36 deletions
diff --git a/Namcap/rules/rpath.py b/Namcap/rules/rpath.py index f8e918f..51b2a15 100644 --- a/Namcap/rules/rpath.py +++ b/Namcap/rules/rpath.py @@ -17,37 +17,28 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -import os, subprocess, re -import tempfile -from Namcap.util import is_elf, clean_filename +from Namcap.util import is_elf from Namcap.ruleclass import * +from elftools.elf.elffile import ELFFile +from elftools.elf.dynamic import DynamicSection + allowed = ['/usr/lib', '/usr/lib32', '/lib', '$ORIGIN', '${ORIGIN}'] allowed_toplevels = [s + '/' for s in allowed] warn = ['/usr/local/lib'] -libpath = re.compile('Library rpath: \[(.*)\]') - -def get_rpaths(filename): - p = subprocess.Popen(["readelf", "-d", filename], - env={'LANG': 'C'}, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - var = p.communicate() - if p.returncode != 0: - raise IOError("unable to read ELF file") - for j in var[0].decode('ascii').splitlines(): - n = libpath.search(j) - # Is this a Library rpath: line? - if n is None: +def get_rpaths(fileobj): + elffile = ELFFile(fileobj) + for section in elffile.iter_sections(): + if not isinstance(section, DynamicSection): continue - - if ":" in n.group(1): - rpaths = n.group(1).split(':') - else: - rpaths = [n.group(1)] - for path in rpaths: - yield path + for tag in section.iter_tags(): + if tag.entry.d_tag != 'DT_RPATH': + continue + rpaths = tag.rpath.decode('ascii') + rpaths = rpaths.split(':') + for path in rpaths: + yield path class package(TarballRule): name = "rpath" @@ -58,18 +49,11 @@ class package(TarballRule): continue # is it an ELF file ? - if not is_elf(tar.extractfile(entry)): - continue # not an ELF file - f = tar.extractfile(entry) - elf = f.read() - f.close() - - # write it to a temporary file - f = tempfile.NamedTemporaryFile(delete = False) - f.write(elf) - f.close() + fileobj = tar.extractfile(entry) + if not is_elf(fileobj): + continue - for path in get_rpaths(f.name): + for path in get_rpaths(fileobj): path_ok = path in allowed for allowed_toplevel in allowed_toplevels: if path.startswith(allowed_toplevel): @@ -83,6 +67,5 @@ class package(TarballRule): self.warnings.append(("insecure-rpath %s %s", (path, entry.name))) - os.unlink(f.name) # vim: set ts=4 sw=4 noet: |