From be76ea6216987eefe9e863b193657318720bca51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Br=C3=BCns?= Date: Sun, 13 Mar 2016 16:01:37 +0100 Subject: [PATCH 1/3] BinariesCheck: lower memory requirements, fix chroot/chdir detection Do not read whole output of objdump -d into memory, but read and process the output while it is created (issue #67). Also correct expression to find 'chdir@plt' in output (issue #66) --- BinariesCheck.py | 49 ++++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/BinariesCheck.py b/BinariesCheck.py index 33dfae5..ee6d00b 100644 --- a/BinariesCheck.py +++ b/BinariesCheck.py @@ -10,6 +10,7 @@ import re import stat import sys +import subprocess import rpm @@ -205,27 +206,37 @@ def __init__(self, pkg, path, file, is_ar, is_shlib): # check if chroot is near chdir (since otherwise, chroot is called # without chdir) if self.chroot and self.chdir: - # FIXME this check is too slow, because forking for objdump is - # quite slow according to a quick test and that's quite visible - # on a server like postfix - res = Pkg.getstatusoutput( - ('env', 'LC_ALL=C', 'objdump', '-d', path)) - if res[0]: + p = subprocess.Popen( + ['env', 'LC_ALL=C', 'objdump', '-d', path], + stdout=subprocess.PIPE, bufsize=1) + with p.stdout: + # we want that : + # 401eb8: e8 c3 f0 ff ff callq 400f80 + objdump_call_regex = re.compile(b'callq?\s(.*)') + index = 0 + chroot_index = -99 + chdir_index = -99 + for line in p.stdout: + r = objdump_call_regex.search(line) + if not r: + continue + if b'@plt' not in r.group(1): + pass + elif b'chroot@plt' in r.group(1): + chroot_index = index + if abs(chroot_index - chdir_index) <= 2: + self.chroot_near_chdir = True + break + elif b'chdir@plt' in r.group(1): + chdir_index = index + if abs(chroot_index - chdir_index) <= 2: + self.chroot_near_chdir = True + break + index += 1 + if p.wait(): printWarning(pkg, 'binaryinfo-objdump-failed', file) self.chroot_near_chdir = True # avoid false positive - else: - call = [] - # we want that : - # 401eb8: e8 c3 f0 ff ff callq 400f80 - for l in res[1].splitlines(): - # call is for x86 32 bits, callq for x86_64 - if l.find('callq ') >= 0 or l.find('call ') >= 0: - call.append(l.rpartition(' ')[2]) - for index, c in enumerate(call): - if c.find('chroot@plt') >= 0: - for i in call[index-2:index+2]: - if i.find('chdir@plt'): - self.chroot_near_chdir = True + else: self.readelf_error = True printWarning(pkg, 'binaryinfo-readelf-failed',