From c5871542684bf1439d96f2430fe4f0010070e4db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Sun, 7 Feb 2016 10:10:51 +0200 Subject: [PATCH] BinariesCheck: avoid false chroot w/o chdir when objdump fails https://bugzilla.redhat.com/show_bug.cgi?id=1305302 --- BinariesCheck.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/BinariesCheck.py b/BinariesCheck.py index b2c030e..33dfae5 100644 --- a/BinariesCheck.py +++ b/BinariesCheck.py @@ -210,7 +210,10 @@ def __init__(self, pkg, path, file, is_ar, is_shlib): # on a server like postfix res = Pkg.getstatusoutput( ('env', 'LC_ALL=C', 'objdump', '-d', path)) - if not res[0]: + if res[0]: + 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 @@ -645,6 +648,9 @@ def check_binary(self, pkg): 'binaryinfo-readelf-failed', '''Executing readelf on this file failed, all checks could not be run.''', +'binaryinfo-objdump-failed', +'''Executing objdump on this file failed, all checks could not be run.''', + 'binaryinfo-tail-failed', '''Reading trailing bytes of this file failed, all checks could not be run.''', 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', From f61aab52fdcbdc9096f2346ee4ecf9668d8a0fbc Mon Sep 17 00:00:00 2001 From: StefanBruens Date: Wed, 29 Jun 2016 18:28:55 +0200 Subject: [PATCH 2/3] Use default bufsize, move regex compile to common place --- BinariesCheck.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/BinariesCheck.py b/BinariesCheck.py index ee6d00b..f19ae29 100644 --- a/BinariesCheck.py +++ b/BinariesCheck.py @@ -54,6 +54,8 @@ class BinaryInfo(object): setuid_call_regex = create_regexp_call('set(?:res|e)?uid') setgroups_call_regex = create_regexp_call('(?:ini|se)tgroups') chroot_call_regex = create_regexp_call('chroot') + # 401eb8: e8 c3 f0 ff ff callq 400f80 + objdump_call_regex = re.compile(b'callq?\s(.*)') forbidden_functions = Config.getOption("WarnOnFunction") if forbidden_functions: @@ -208,11 +210,8 @@ def __init__(self, pkg, path, file, is_ar, is_shlib): if self.chroot and self.chdir: p = subprocess.Popen( ['env', 'LC_ALL=C', 'objdump', '-d', path], - stdout=subprocess.PIPE, bufsize=1) + 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 From 643f42c51f46ed1f377fc099cca818fba2d5a7d0 Mon Sep 17 00:00:00 2001 From: StefanBruens Date: Wed, 29 Jun 2016 18:38:51 +0200 Subject: [PATCH 3/3] Fix last commit --- BinariesCheck.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BinariesCheck.py b/BinariesCheck.py index f19ae29..89517c2 100644 --- a/BinariesCheck.py +++ b/BinariesCheck.py @@ -216,7 +216,7 @@ def __init__(self, pkg, path, file, is_ar, is_shlib): chroot_index = -99 chdir_index = -99 for line in p.stdout: - r = objdump_call_regex.search(line) + r = BinaryInfo.objdump_call_regex.search(line) if not r: continue if b'@plt' not in r.group(1):