From 9004731d431220cd86ea59e7aed3a85de528d7cb Mon Sep 17 00:00:00 2001 From: Wangchong Zhou Date: Mon, 9 Sep 2024 19:21:24 +0800 Subject: [PATCH] chore(explain_manifest): bump lief and return matched groups --- scripts/explain_manifest/expect.py | 22 +++++++++++++------ scripts/explain_manifest/explain.py | 17 ++++++++------- scripts/explain_manifest/requirements.txt | 2 +- scripts/explain_manifest/suites.py | 26 +++++++++++++++-------- 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/scripts/explain_manifest/expect.py b/scripts/explain_manifest/expect.py index c23d4f9a9d05..eb37b4da40cb 100644 --- a/scripts/explain_manifest/expect.py +++ b/scripts/explain_manifest/expect.py @@ -144,6 +144,7 @@ def _print_all_fails(self): def _compare(self, attr, fn): self._checks_count += 1 + results = [] for f in self._files: if not hasattr(f, attr): continue # accept missing attribute for now @@ -153,8 +154,10 @@ def _compare(self, attr, fn): if self._key_name not in v: return True v = v[self._key_name] - (ok, err_template) = fn(v) - if (not not ok) == self._logical_reverse: + (r, err_template) = fn(v) + if r: + results.append(r) + if (not not r) == self._logical_reverse: _not = "not" if self._logical_reverse: _not = "actually" @@ -163,7 +166,7 @@ def _compare(self, attr, fn): f.relpath, attr, err_template.format(v, NOT=_not) )) return False - return True + return results def _exist(self): self._checks_count += 1 @@ -179,7 +182,9 @@ def _equal(self, attr, expect): return self._compare(attr, lambda a: (a == expect, "'{}' does {NOT} equal to '%s'" % expect)) def _match(self, attr, expect): - return self._compare(attr, lambda a: (re.search(expect, a), "'{}' does {NOT} match '%s'" % expect)) + r = self._compare(attr, lambda a: (re.search(expect, a), "'{}' does {NOT} match '%s'" % expect)) + self.last_macthes = r + return (not not r) def _less_than(self, attr, expect): def fn(a): @@ -222,8 +227,9 @@ def fn(a): if isinstance(a, list): msg = "'%s' is {NOT} found in the list" % expect for e in a: - if re.search(expect, e): - return True, msg + r = re.search(expect, e) + if r: + return r, msg return False, msg else: return False, "'%s' is not a list" % attr @@ -331,3 +337,7 @@ def run(self, suite: ExpectSuite): s(self.expect, **suite.tests[s]) self._print_result() # cleanup the lazy buffer + + + def get_last_macthes(self): + return self.last_macthes diff --git a/scripts/explain_manifest/explain.py b/scripts/explain_manifest/explain.py index 1916401024e5..b22b2a5f4a33 100644 --- a/scripts/explain_manifest/explain.py +++ b/scripts/explain_manifest/explain.py @@ -132,15 +132,16 @@ def __init__(self, path, relpath): if not binary: # not an ELF file, malformed, etc return - self.arch = binary.header.machine_type.name + # lief._lief.ELF.ARCH.X86_64 + self.arch = str(binary.header.machine_type).split(".")[-1] for d in binary.dynamic_entries: - if d.tag == lief.ELF.DYNAMIC_TAGS.NEEDED: + if d.tag == lief._lief.ELF.DynamicEntry.TAG.NEEDED: self.needed_libraries.append(d.name) - elif d.tag == lief.ELF.DYNAMIC_TAGS.RPATH: - self.rpath = d.name - elif d.tag == lief.ELF.DYNAMIC_TAGS.RUNPATH: - self.runpath = d.name + elif d.tag == lief._lief.ELF.DynamicEntry.TAG.RPATH: + self.rpath = d.runpath + elif d.tag == lief._lief.ELF.DynamicEntry.TAG.RUNPATH: + self.runpath = d.runpath # create closures and lazily evaluated self.get_exported_symbols = lambda: sorted( @@ -203,7 +204,7 @@ def __init__(self, path, relpath): binary = lief.parse(path) for s in binary.strings: - if re.match("\s*--prefix=/", s): + if re.match(r"\s*--prefix=/", s): self.nginx_compile_flags = s for m in re.findall("add(?:-dynamic)?-module=(.*?) ", s): if m.startswith("../"): # skip bundled modules @@ -215,7 +216,7 @@ def __init__(self, path, relpath): else: self.nginx_modules.append(os.path.join(pdir, mname)) self.nginx_modules = sorted(self.nginx_modules) - elif m := re.match("^built with (.+) \(running with", s): + elif m := re.match(r"^built with (.+) \(running with", s): self.nginx_compiled_openssl = m.group(1).strip() # Fetch DWARF infos diff --git a/scripts/explain_manifest/requirements.txt b/scripts/explain_manifest/requirements.txt index 921dc8b3d14b..ca360f33b241 100644 --- a/scripts/explain_manifest/requirements.txt +++ b/scripts/explain_manifest/requirements.txt @@ -1,4 +1,4 @@ -lief==0.12.* +lief==0.15.* globmatch==2.0.* pyelftools==0.29 looseversion==1.1.2 diff --git a/scripts/explain_manifest/suites.py b/scripts/explain_manifest/suites.py index ba89e4322807..26d5c93d30d0 100644 --- a/scripts/explain_manifest/suites.py +++ b/scripts/explain_manifest/suites.py @@ -49,11 +49,11 @@ def common_suites(expect, libxcrypt_no_obsolete_api: bool = False, skip_libsimdj .exported_symbols.contain("pcre2_general_context_free_8") \ .exported_symbols.do_not().contain("pcre_free") \ .needed_libraries.do_not().contain_match("libpcre.so.+") \ - .needed_libraries.do_not().contain_match("libpcre.+.so.+") \ - .needed_libraries.do_not().contain_match("libpcre2\-(8|16|32).so.+") \ + .needed_libraries.do_not().contain_match(r"libpcre.+.so.+") \ + .needed_libraries.do_not().contain_match(r"libpcre2\-(8|16|32).so.+") \ expect("/usr/local/openresty/nginx/sbin/nginx", "nginx should not be compiled with debug flag") \ - .nginx_compile_flags.do_not().match("with\-debug") + .nginx_compile_flags.do_not().match(r"with\-debug") expect("/usr/local/openresty/nginx/sbin/nginx", "nginx should include Kong's patches") \ .functions \ @@ -96,7 +96,7 @@ def common_suites(expect, libxcrypt_no_obsolete_api: bool = False, skip_libsimdj .needed_libraries.contain("libcrypt.so.1") expect("/usr/local/openresty/nginx/sbin/nginx", "nginx compiled with OpenSSL 3.2.x") \ - .nginx_compiled_openssl.matches("OpenSSL 3.2.\d") \ + .nginx_compiled_openssl.matches(r"OpenSSL 3.2.\d") \ .version_requirement.key("libssl.so.3").less_than("OPENSSL_3.3.0") \ .version_requirement.key("libcrypto.so.3").less_than("OPENSSL_3.3.0") \ @@ -137,12 +137,20 @@ def arm64_suites(expect): expect("/usr/local/openresty/nginx/sbin/nginx", "Nginx is arm64 arch") \ .arch.equals("AARCH64") -def docker_suites(expect, kong_uid: int = 1000, kong_gid: int = 1000): - expect("/etc/passwd", "kong user exists") \ - .text_content.matches("kong:x:%d" % kong_uid) +def docker_suites(expect): - expect("/etc/group", "kong group exists") \ - .text_content.matches("kong:x:%d" % kong_gid) + m = expect("/etc/passwd", "kong user exists") \ + .text_content.matches(r"kong:x:(\d+)").get_last_macthes() + + if m: + kong_uid = int(m[0].groups()[0]) + + + m = expect("/etc/group", "kong group exists") \ + .text_content.matches(r"kong:x:(\d+)").get_last_macthes() + + if m: + kong_gid = int(m[0].groups()[0]) for path in ("/usr/local/kong/**", "/usr/local/bin/kong"): expect(path, "%s owned by kong:root" % path) \