[PATCH 1/2] image-with-hardened-binaries: add class
Maximilian Blenk <Maximilian.Blenk@...>
Add class to analyze binaries with checksec.py. checksec.py is a tool
that checks if security features of a compiler have been used. To do so, it analyses the resulting binaries: * NX Proctection is enabled * Full RELRO is enabled * RPATH and RUNPATH are not set * Executables are compiled to be position independent * FORTIFY_SOURCE is set (false-positives possible) * Stack Canaries are enabled (false-positives possible) Signed-off-by: Maximilian Blenk <Maximilian.Blenk@...> --- classes/image-with-hardened-binaries.bbclass | 338 ++++++++++++++++++ ...1-main-Add-option-to-ignore-symlinks.patch | 81 +++++ .../0002-Elf-Fix-relro-detection.patch | 51 +++ ...heck-Treat-binaries-with-0-fortifiab.patch | 33 ++ ...o-use-pre-compiled-version-of-spdlog.patch | 154 ++++++++ .../python/python3-asttokens_2.0.5.bb | 15 + .../python3-checksec.py-native_0.6.1.bb | 31 ++ .../python/python3-colorama_%.bbappend | 1 + .../python/python3-commonmark_0.9.1.bb | 14 + .../python/python3-docopt_0.6.2.bb | 18 + .../python/python3-icontract_2.5.3.bb | 14 + .../python/python3-lief_0.11.5.bb | 36 ++ .../python/python3-pylddwrap_1.0.1.bb | 21 ++ recipes-devtools/python/python3-rich_7.1.0.bb | 16 + .../python/python3-setuptools-scm_6.0.1.bb | 17 + .../python/python3-toml_%.bbappend | 1 + 16 files changed, 841 insertions(+) create mode 100644 classes/image-with-hardened-binaries.bbclass create mode 100644 recipes-devtools/python/files/python3-checksec.py/0001-main-Add-option-to-ignore-symlinks.patch create mode 100644 recipes-devtools/python/files/python3-checksec.py/0002-Elf-Fix-relro-detection.patch create mode 100644 recipes-devtools/python/files/python3-checksec.py/0003-fortify-source-check-Treat-binaries-with-0-fortifiab.patch create mode 100644 recipes-devtools/python/files/python3-lief/0001-Enable-to-use-pre-compiled-version-of-spdlog.patch create mode 100644 recipes-devtools/python/python3-asttokens_2.0.5.bb create mode 100644 recipes-devtools/python/python3-checksec.py-native_0.6.1.bb create mode 100644 recipes-devtools/python/python3-colorama_%.bbappend create mode 100644 recipes-devtools/python/python3-commonmark_0.9.1.bb create mode 100644 recipes-devtools/python/python3-docopt_0.6.2.bb create mode 100644 recipes-devtools/python/python3-icontract_2.5.3.bb create mode 100644 recipes-devtools/python/python3-lief_0.11.5.bb create mode 100644 recipes-devtools/python/python3-pylddwrap_1.0.1.bb create mode 100644 recipes-devtools/python/python3-rich_7.1.0.bb create mode 100644 recipes-devtools/python/python3-setuptools-scm_6.0.1.bb create mode 100644 recipes-devtools/python/python3-toml_%.bbappend diff --git a/classes/image-with-hardened-binaries.bbclass b/classes/image-with-hardened-binaries.bbclass new file mode 100644 index 0000000..d7d3908 --- /dev/null +++ b/classes/image-with-hardened-binaries.bbclass @@ -0,0 +1,338 @@ +# Provide qa checks to ensure all applications and libraries shipped with the image +# have common compiler security features enabled. In particular there are checks that: +# * nx protection is enabled +# * relro is enabled +# * executables (except for static linked ones) are position independent +# * rpath and runpath are not set + +IMAGE_QA_COMMANDS += "image_check_binary_hardening" + +DEPENDS += "python3-checksec.py-native" + +inherit python3native + +# Add mappings to the path mappers (which determines if a binary is a application or +# shared library). To add a mapping append " /path/from/the/root/to/bin:{application,library,ignore}" +# to the list +HARDENED_BINARIES_EXTRA_MAPPING ?= "" + +# Config file in TOML format: +# [check] +# enabled = true +# whitelist = [ +# "path to some binary", +# "path to some other binary" +# ] +# supported checks are: nx, relro, pie, rpath, runpath +HARDENED_BINARIES_CONFIG_FILE ?= "" + +# Custom message to show in case of a detected violation +# For instace if you want to add whom to contact for support +HARDENED_BINARIES_CUSTOM_ERROR_MESSAGE ?= "" + +# Path to libc used for foritfy source analysis. If fortify_source check is +# not enabled, this variable can be ignored. +HARDENED_BINARIES_LIBC_PATH ?= "${IMAGE_ROOTFS}${baselib}/libc.so.6" + +python image_check_binary_hardening () { + import fnmatch + import json + import os + import subprocess + import toml + from collections import defaultdict, OrderedDict + from enum import Enum, auto + + from oe.utils import ImageQAFailed + + rootfs = d.getVar("IMAGE_ROOTFS") + + ################################# + ## Data about supported checks ## + ################################# + + class BinType(Enum): + IGNORE = "ignore" + APPLICATION = "application" + LIBRARY = "library" + + # Dict of checks to perform on the analysis result of checksec.py + # Each entry needs to contain the following attributes: + # - allowed_value: Value in the analysis result that should be accepted + # - bintypes: List of types on which the check shall be enforced (e.g. PIE check on libraries + # doesn't make much sense because PIE is only for executables) + # - errormsg: Message that should be prompted in case violators have been found + # - ignore_static: Indicates if statically linked applications should be ignored for that check + # Notes specific checks: + # - NX: Needs to be enforced on applications and libraries. This is because if only a single shared + # library doesn't use that, the whole process needs to have a executable stack. + # - RELRO: Statically linked applications do not make use of relocation, so this check would always + # fail for statically linked applications. + # - PIE: This check is only valid for applications (as in "position independent executable" for + # applications vs. "position independent code" (PIC) for shared libraries) + CHECK_DATA = { + "nx" : { + "allowed_value": True, + "bintypes": [BinType.APPLICATION, BinType.LIBRARY], + "errormsg": + "The following {} binaries do not use nx (not executable) protection. This mechanism is used " \ + "to separate data from executable code. Disabling this mechanism is a security issue because " \ + "this enables attackers to put code onto the stack. Please also note, if the nx protection is " \ + "disabled in a shared library, all binary objects that link against this library will not be " \ + "protected. This message usually appears if your binary is linked using the \"-z execstack\" " \ + "flag.", + "ignore_static": False, + }, + "relro": { + "allowed_value": "Full", + "bintypes": [BinType.APPLICATION, BinType.LIBRARY], + "errormsg": + "The following {} binaries do not make use of the relro (relocation read-only). This feature " \ + "prevents attackers from modifying addresses of functions that are located in shared libraries " \ + "(which is a common technique to exploit vulnerabilities). Due to this, not making use of this " \ + "feature is a security issue. Please make sure your application is linked using " \ + "\"-Wl,-z,relro,-z,now\". ", + "ignore_static": True, + }, + "rpath": { + "allowed_value": False, + "bintypes": [BinType.APPLICATION, BinType.LIBRARY], + "errormsg": + "The following {} binaries are making use of the rpath feature. This can easily enable an attacker " \ + "to get malicious code executed if there is some issue with the file permissions at the specified " \ + "location. Due to this, the usage of this feature is generally discouraged and needs approval " \ + "by the security team.", + "ignore_static": False, + }, + "runpath": { + "allowed_value": False, + "bintypes": [BinType.APPLICATION, BinType.LIBRARY], + "errormsg": + "The following {} binaries are making use of the runpath feature. This can easily enable an attacker" \ + " to get malicious code executed if there is some issue with the file permissions at the specified " \ + "location. Due to this, the usage of this feature is generally discouraged and needs approval " \ + "by the security team.", + "ignore_static": False, + }, + "pie": { + "allowed_value": "PIE", + "bintypes": [BinType.APPLICATION], + "errormsg": + "The following {} applications are not compiled to be position independent executables (pie). This " \ + "compiler feature compiles the code in a way that it can be mapped to any location in the virtual " \ + "memory. Compiling the application this way is required to make use of the Address Space Layout " \ + "Randomization (ASLR). This feature maps executable code to a random location, which means an " \ + "attacker can not rely on the fact that a specific portion of code is mapped to a specific address. " \ + "Please ensure that you application is compiled using \"-fPIE\".", + "ignore_static": True, + }, + "canary": { + "allowed_value": True, + "bintypes": [BinType.APPLICATION, BinType.LIBRARY], + "errormsg": + "The following {} binaries seem to be not using stack canaries. These canaries are used to mitigate " \ + "stack buffer overflows attacks. To do so the compiler adds checks to the end of a function to " \ + "ensure that this function did not overwrite the stack frames of another function. Not using " \ + "canaries may allow an attacker to exploit stack based buffer overflows by modifying the stack frame " \ + "of other function calls (which simplifies exploiting such vulnerabilities a lot). Please make sure " \ + "your components are compiled with the \"-fstack-protector-strong\" compile flag. Please note that " \ + "there is a slight possibility for false-positives in this check: The compiler checks if a function " \ + "needs canary protection or not. If there is no function that needs proctedtion in your binary, this " \ + "check will fail anyway and the binary needs to be whitelisted.", + "ignore_static": False, + }, + "fortify_source": { + "allowed_value": True, + "bintypes": [BinType.APPLICATION, BinType.LIBRARY], + "errormsg": + "The following {} binaries seem to be not using the fortify source feature. This feature protects " \ + "(some, not all) calls to memory manipulations function like memcpy, strcpy or strcat by adding " \ + "checks that prevent buffer overflows. These checks can prevent attackers from exploiting such a " \ + "buffer overflow. Please make sure your component is compiled with \"-D_FORTIFY_SOURCE=2\". In " \ + "addition the compiler optimizations need to be enabled with \"-O1\" or higher. Please note that " \ + "there is a slight possibility for false positives here: Not all occurences of these mentioned " \ + "memory calls that can not be protected they will appear as if_FORTIFY_SOURCE has not been set. " \ + "In such a case the binary needs to be whitelisted.", + "ignore_static": False, + } + } + + ################################# + ## Parse data from config file ## + ################################# + + config_file = d.getVar("HARDENED_BINARIES_CONFIG_FILE", True) + if not config_file: + msg = "Hardend Binary Check: No config file specifed. Please create a config file and set " \ + "the variable \"HARDENED_BINARIES_CONFIG_FILE\" accordingly" + raise ImageQAFailed(msg, image_check_binary_hardening) + + CHECK_CONFIG_DATA = defaultdict(lambda: {"enabled": False}) + CHECK_CONFIG_DATA.update(toml.load(config_file)) + + # Expand whitelisted paths with rootfs + for check, values in CHECK_CONFIG_DATA.items(): + values["whitelist"] = [rootfs + x for x in values["whitelist"]] + + ############################################### + ## Classes and functions to perform analysis ## + ############################################### + + class PathMapping: + """ Class to map paths to BinTypes """ + def __init__(self, rootfs): + self.rootfs = rootfs + self.mapping = OrderedDict() + + self.add("/bin/*", BinType.APPLICATION) + self.add("/lib/firmware/*", BinType.IGNORE) + self.add("/lib/modules/*", BinType.IGNORE) + self.add("/lib/systemd/*.so", BinType.LIBRARY) + self.add("/lib/systemd/*", BinType.APPLICATION) + self.add("/lib/*", BinType.LIBRARY) + self.add("/sbin/*", BinType.APPLICATION) + self.add("/usr/bin/*", BinType.APPLICATION) + self.add("/usr/libexec/*", BinType.APPLICATION) + self.add("/usr/lib/firmware/*", BinType.IGNORE) + self.add("/usr/lib/modules/*", BinType.IGNORE) + self.add("/usr/lib/systemd/*.so", BinType.LIBRARY) + self.add("/usr/lib/systemd/*", BinType.APPLICATION) + self.add("/usr/lib/*", BinType.LIBRARY) + self.add("/usr/sbin/*", BinType.APPLICATION) + + + def add(self, path, bin_type): + """ Add mapping of a path to a FileyType """ + self.mapping[self.rootfs + path] = bin_type + + def map(self, path): + """ Map a path to a FilesType. Returns None if path can not be mapped. """ + for match_path, bin_type in self.mapping.items(): + if fnmatch.fnmatch(path, match_path): + return bin_type + else: + return None + + def call_checksec(rootfs): + """ Wrapper to call the checksec.py script + + This function returns a list of result dicts, e.g.: + [ + ..., + "/bin/systemd-hwdb": { + "relro": "No", + "canary": true, + "nx": true, + "pie": "PIE", + "rpath": false, + "runpath": false, + "symbols": false, + "fortify_source": true, + "fortified": 5, + "fortify-able": 16, + "fortify_score": 31 + } + ] + + """ + parallel_make = d.getVar("PARALLEL_MAKE") + + cmd = ["python3", "-m", "checksec", "--json", "--recursive", "--ignore-symlinks"] + if parallel_make: + cmd.append(parallel_make.replace("-j", "--workers=")) + if CHECK_CONFIG_DATA["foritfy_source"]["enabled"]: + libc_path = d.getVar("HARDENED_BINARIES_LIBC_PATH", True) + cmd.append("--set-libc={}".format(libc_path)) + cmd.append(rootfs) + + return json.loads(subprocess.check_output(cmd).decode('utf-8')) + + + class ResultAnalyzer: + """ Class to evaluate the results produced by checksec.py """ + def __init__(self, rootfs): + self.rootfs = rootfs + self.violators = defaultdict(list) + + @staticmethod + def __is_static(path): + """ Checks if binary at given path is statically linked """ + return "statically linked" in subprocess.check_output(["file", path], stderr=subprocess.STDOUT).decode('utf-8') + + def check_result(self, path, result, bintype): + """ Perfom checks specified in CHECK_DATA on the given analysis result (of a specific binary) """ + + for check, values in CHECK_DATA.items(): + if CHECK_CONFIG_DATA[check]["enabled"] and bintype in values["bintypes"]: + for whitelisted in CHECK_CONFIG_DATA[check]["whitelist"]: + if fnmatch.fnmatch(path, whitelisted): + break + else: + if result[check] != values["allowed_value"] and \ + (not values["ignore_static"] or not self.__is_static(path)): + self.violators[check].append(path) + + + def perform_analysis(rootfs): + """ Analyze all binaries in a given rootfs. In case a container shall be analyzed the absolute path to the container_path + rootfs needs to be passed. + """ + + # Add custom path mapping (for bins in non-standard locations) + path_mapping = PathMapping(rootfs) + extra_mapping = d.getVar("HARDENED_BINARIES_EXTRA_MAPPING") + if extra_mapping: + for mapping in extra_mapping.split(): + try: + path, type = mapping.split(':') + except: + bb.error("Hardened Binary Checks: Got misformated extra mapping {}. Mapping needs to be " \ + "in form: \"<path regex>:{application,library,ignore}\"".format(mapping)) + raise + path_mapping.add(path, BinType(type)) + + # Perform analysis of complete rootfs + analysis_result = call_checksec(rootfs) + + # Check analysis results and ensure that all we can actually map all binaries to a BinType + result_analyzer = ResultAnalyzer(rootfs) + unmapped_binaries = [] + for path, result in analysis_result.items(): + bintype = path_mapping.map(path) + if bintype in [BinType.APPLICATION, BinType.LIBRARY]: + result_analyzer.check_result(path, result, bintype) + elif bintype != BinType.IGNORE: + unmapped_binaries.append(path) + + # To ensure that we analyze all the binaries lets break the build if we can not map binaries + if unmapped_binaries: + msg = "Hardend Binary Check: Couldn't figure out if the following files are applications " \ + "or libraries. This is probably due to a non standard location for applications or " \ + "libraries. If you think this is required add the mapping to " \ + "HARDENED_BINARIES_EXTRA_MAPPING and/or contact mgu-security-frontdesk@..." \ + "\nUnmapped:\n{}".format("\n".join(unmapped_binaries), + image_check_binary_hardening) + raise ImageQAFailed(msg, image_check_binary_hardening) + + custom_error_message = d.getVar('HARDENED_BINARIES_CUSTOM_ERROR_MESSAGE') + + # Break the build and show error message if we detected violators that are not whitelisted + errors = [] + for check, violators in result_analyzer.violators.items(): + if violators: + errormsg = CHECK_DATA[check]["errormsg"].format(len(violators)) + errormsg += "\n{}".format("\n".join(violators)) + if custom_error_message: + errormsg += "\n" + custom_error_message + errors.append(errormsg) + + if errors: + raise ImageQAFailed("\n".join(errors), image_check_binary_hardening) + + ############################## + ## Start analysis on rootfs ## + ############################## + + perform_analysis(rootfs) + +} diff --git a/recipes-devtools/python/files/python3-checksec.py/0001-main-Add-option-to-ignore-symlinks.patch b/recipes-devtools/python/files/python3-checksec.py/0001-main-Add-option-to-ignore-symlinks.patch new file mode 100644 index 0000000..ae434bc --- /dev/null +++ b/recipes-devtools/python/files/python3-checksec.py/0001-main-Add-option-to-ignore-symlinks.patch @@ -0,0 +1,81 @@ +From 182268203951750dcfb2c134354e801dea472e4c Mon Sep 17 00:00:00 2001 +From: Maximilian Blenk <Maximilian.Blenk@...> +Date: Fri, 2 Jul 2021 14:42:25 +0200 +Subject: [PATCH 1/2] main: Add option to ignore symlinks + +When analyzing a complete rootfs (which might not be the rootfs of the +analyzing system) symlinks within that rootfs might be broken. In +particular absolute symlinks. However, if by chance such a symlink +currently points to a valid binary in your system, this binary pointed +to is analyzed. This commit adds the possibility to ignore symlinks to +files (symlinks to dirs are already ignored by default). This allows to +solve the issue described above, and if the whole rootfs is analyzed +there shouldn't be a loss of information (because all the binaries will +be analyzed anyway). Additionally, this also saves some time when +performing the analysis. + +Upstream-Status: Submitted https://github.com/Wenzel/checksec.py/pull/106 +--- + checksec/__main__.py | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/checksec/__main__.py b/checksec/__main__.py +index 856d0b3..f1a3445 100644 +--- a/checksec/__main__.py ++++ b/checksec/__main__.py +@@ -8,6 +8,7 @@ Options: + -w WORKERS --workers=WORKERS Specify the number of process pool workers [default: 4] + -j --json Display results as JSON + -s LIBC --set-libc=LIBC Specify LIBC library to use to check for fortify scores (ELF) ++ -i --ignore-symlinks Ignore symlinks to files + -d --debug Enable debug output + -h --help Display this message + """ +@@ -27,15 +28,15 @@ from .pe import PEChecksecData, PESecurity, is_pe + from .utils import lief_set_logging + + +-def walk_filepath_list(filepath_list: List[Path], recursive: bool = False) -> Iterator[Path]: ++def walk_filepath_list(filepath_list: List[Path], recursive: bool = False, ignore_symlinks: bool = False) -> Iterator[Path]: + for path in filepath_list: + if path.is_dir() and not path.is_symlink(): + if recursive: + for f in os.scandir(path): +- yield from walk_filepath_list([Path(f)], recursive) ++ yield from walk_filepath_list([Path(f)], recursive, ignore_symlinks) + else: + yield from (Path(f) for f in os.scandir(path)) +- elif path.is_file(): ++ elif path.is_file() and (not ignore_symlinks or not path.is_symlink()): + yield path + + +@@ -72,6 +73,7 @@ def main(args): + json = args["--json"] + recursive = args["--recursive"] + libc_path = args["--set-libc"] ++ ignore_symlinks = args["--ignore-symlinks"] + + # logging + formatter = "%(asctime)s %(levelname)s:%(name)s:%(message)s" +@@ -107,7 +109,7 @@ def main(args): + # we need to consume the iterator once to get the total + # for the progress bar + check_output.enumerating_tasks_start() +- count = sum(1 for i in walk_filepath_list(filepath_list, recursive)) ++ count = sum(1 for i in walk_filepath_list(filepath_list, recursive, ignore_symlinks)) + check_output.enumerating_tasks_stop(count) + with ProcessPoolExecutor( + max_workers=workers, initializer=worker_initializer, initargs=(libc_path,) +@@ -116,7 +118,7 @@ def main(args): + check_output.processing_tasks_start() + future_to_checksec = { + pool.submit(checksec_file, filepath): filepath +- for filepath in walk_filepath_list(filepath_list, recursive) ++ for filepath in walk_filepath_list(filepath_list, recursive, ignore_symlinks) + } + for future in as_completed(future_to_checksec): + filepath = future_to_checksec[future] +-- +2.31.1 + diff --git a/recipes-devtools/python/files/python3-checksec.py/0002-Elf-Fix-relro-detection.patch b/recipes-devtools/python/files/python3-checksec.py/0002-Elf-Fix-relro-detection.patch new file mode 100644 index 0000000..a891c2b --- /dev/null +++ b/recipes-devtools/python/files/python3-checksec.py/0002-Elf-Fix-relro-detection.patch @@ -0,0 +1,51 @@ +From f550777f35e178bc16a2ec612b2b39aa2c3946f2 Mon Sep 17 00:00:00 2001 +From: Maximilian Blenk <Maximilian.Blenk@...> +Date: Fri, 2 Jul 2021 16:16:47 +0200 +Subject: [PATCH 2/2] Elf: Fix relro detection + +Currently, relro is only detected when the BIND_NOW is set. If however +the NOW flag in the FLAGS_1 section is set, relro is not detected (it +does not even tell that relro is enabled partially). With this commit +relro is detected correctly. + +Upstream-Status: Submitted https://github.com/Wenzel/checksec.py/pull/107 +--- + checksec/elf.py | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/checksec/elf.py b/checksec/elf.py +index 78ecacc..ef1850c 100644 +--- a/checksec/elf.py ++++ b/checksec/elf.py +@@ -118,13 +118,24 @@ class ELFSecurity(BinarySecurity): + def relro(self) -> RelroType: + try: + self.bin.get(lief.ELF.SEGMENT_TYPES.GNU_RELRO) +- if lief.ELF.DYNAMIC_FLAGS.BIND_NOW in self.bin.get(lief.ELF.DYNAMIC_TAGS.FLAGS): +- return RelroType.Full +- else: +- return RelroType.Partial + except lief.not_found: + return RelroType.No + ++ try: ++ bind_now = lief.ELF.DYNAMIC_FLAGS.BIND_NOW in self.bin.get(lief.ELF.DYNAMIC_TAGS.FLAGS) ++ except lief.not_found: ++ bind_now = False ++ ++ try: ++ now = lief.ELF.DYNAMIC_FLAGS_1.NOW in self.bin.get(lief.ELF.DYNAMIC_TAGS.FLAGS_1) ++ except lief.not_found: ++ now = False ++ ++ if bind_now or now: ++ return RelroType.Full ++ else: ++ return RelroType.Partial ++ + @property + def has_canary(self) -> bool: + canary_sections = ["__stack_chk_fail", "__intel_security_cookie"] +-- +2.31.1 + diff --git a/recipes-devtools/python/files/python3-checksec.py/0003-fortify-source-check-Treat-binaries-with-0-fortifiab.patch b/recipes-devtools/python/files/python3-checksec.py/0003-fortify-source-check-Treat-binaries-with-0-fortifiab.patch new file mode 100644 index 0000000..0351f84 --- /dev/null +++ b/recipes-devtools/python/files/python3-checksec.py/0003-fortify-source-check-Treat-binaries-with-0-fortifiab.patch @@ -0,0 +1,33 @@ +From 8de048c0065f8c5890d9e04ef2b32306e2ac4f8c Mon Sep 17 00:00:00 2001 +From: Maximilian Blenk <Maximilian.Blenk@...> +Date: Thu, 5 Aug 2021 15:21:58 +0200 +Subject: [PATCH] fortify source check: Treat binaries with 0 fortifiable as + fortified + +Currently, if checksec.py detects 0 fortifiable instances it still +treats the binary as not fortified. Semtically it would make sense to +treat these binaries as fortified (because there is no evidence that it +is not) + +Upstream-Status: Submitted https://github.com/Wenzel/checksec.py/pull/109 +--- + checksec/elf.py | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/checksec/elf.py b/checksec/elf.py +index ef1850c..5914135 100644 +--- a/checksec/elf.py ++++ b/checksec/elf.py +@@ -229,8 +229,7 @@ class ELFSecurity(BinarySecurity): + else: + score = (fortified_count * 100) / fortifiable_count + score = round(score) +- +- fortify_source = True if fortified_count != 0 else False ++ fortify_source = True if fortified_count != 0 or fortifiable_count == 0 else False + return ELFChecksecData( + relro=self.relro, + canary=self.has_canary, +-- +2.31.1 + diff --git a/recipes-devtools/python/files/python3-lief/0001-Enable-to-use-pre-compiled-version-of-spdlog.patch b/recipes-devtools/python/files/python3-lief/0001-Enable-to-use-pre-compiled-version-of-spdlog.patch new file mode 100644 index 0000000..af94cfa --- /dev/null +++ b/recipes-devtools/python/files/python3-lief/0001-Enable-to-use-pre-compiled-version-of-spdlog.patch @@ -0,0 +1,154 @@ +From d2ad8f6108c750c3dbd33ee6d4e4c94ada748b8a Mon Sep 17 00:00:00 2001 +From: Romain Thomas <me@...> +Date: Mon, 3 May 2021 11:25:49 +0200 +Subject: [PATCH] Enable to use pre-compiled version of spdlog + +--- + CMakeLists.txt | 8 ++++---- + cmake/LIEFDependencies.cmake | 36 +++++++++++++++++++++++------------- + cmake/LIEFOptions.cmake | 4 ++++ + setup.py | 17 +++++++++++++++++ + 4 files changed, 48 insertions(+), 17 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index d1665cd..b92519a 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -307,8 +307,7 @@ source_group("mbedtls\\tls" FILES ${mbedtls_src_tls}) + # Library definition + # ================== + target_include_directories( +- LIB_LIEF SYSTEM PRIVATE "${SPDLOG_SOURCE_DIR}/include" +- "${MBEDTLS_INCLUDE_DIRS}") ++ LIB_LIEF SYSTEM PRIVATE "${MBEDTLS_INCLUDE_DIRS}") + + target_include_directories( + LIB_LIEF +@@ -355,7 +354,8 @@ target_sources(LIB_LIEF PRIVATE + ${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/third-party/utfcpp/utf8.h) + + +-add_dependencies(LIB_LIEF lief_spdlog lief_mbed_tls) ++add_dependencies(LIB_LIEF lief_mbed_tls) ++target_link_libraries(LIB_LIEF PRIVATE lief_spdlog) + + # Flags definition + # ---------------- +@@ -626,7 +626,7 @@ install( + DESTINATION lib/pkgconfig + COMPONENT libraries) + +-export(TARGETS LIB_LIEF FILE LIEFExport.cmake) ++export(TARGETS LIB_LIEF lief_spdlog FILE LIEFExport.cmake) + + # Package + # ====================== +diff --git a/cmake/LIEFDependencies.cmake b/cmake/LIEFDependencies.cmake +index e75326f..37e6987 100644 +--- a/cmake/LIEFDependencies.cmake ++++ b/cmake/LIEFDependencies.cmake +@@ -144,21 +144,31 @@ set(mbedtls_src_tls + "${MBEDTLS_SOURCE_DIR}/library/ssl_tls13_keys.c" + ) + +-#set_source_files_properties("${MBEDTLS_SOURCE_DIR}/library/bignum.c" PROPERTIES COMPILE_FLAGS -Wno-overlength-strings) ++add_library(lief_spdlog INTERFACE) + +-set(SPDLOG_VERSION 1.8.2) +-set(SPDLOG_SHA256 SHA256=f0410b12b526065802b40db01304783550d3d20b4b6fe2f8da55f9d08ed2035d) +-set(SPDLOG_URL "${THIRD_PARTY_DIRECTORY}/spdlog-${SPDLOG_VERSION}.zip" CACHE STRING "URL to the spdlog lib repo") +-ExternalProject_Add(lief_spdlog +- URL ${SPDLOG_URL} +- URL_HASH ${SPDLOG_SHA256} +- CONFIGURE_COMMAND "" +- BUILD_COMMAND "" +- UPDATE_COMMAND "" +- INSTALL_COMMAND "") ++if(LIEF_EXTERNAL_SPDLOG) ++ find_package(spdlog REQUIRED) ++ list(APPEND CMAKE_MODULE_PATH "${SPDLOG_DIR}/cmake") ++ target_link_libraries(lief_spdlog INTERFACE spdlog::spdlog) ++ get_target_property(SPDLOG_INC_DIR spdlog::spdlog INTERFACE_INCLUDE_DIRECTORIES) ++ target_include_directories(lief_spdlog SYSTEM INTERFACE ${SPDLOG_INC_DIR}) ++else() ++ set(SPDLOG_VERSION 1.8.2) ++ set(SPDLOG_SHA256 SHA256=f0410b12b526065802b40db01304783550d3d20b4b6fe2f8da55f9d08ed2035d) ++ set(SPDLOG_URL "${THIRD_PARTY_DIRECTORY}/spdlog-${SPDLOG_VERSION}.zip" CACHE STRING "URL to the spdlog source") ++ ExternalProject_Add(lief_spdlog_project ++ URL ${SPDLOG_URL} ++ URL_HASH ${SPDLOG_SHA256} ++ CONFIGURE_COMMAND "" ++ BUILD_COMMAND "" ++ UPDATE_COMMAND "" ++ INSTALL_COMMAND "") + +-ExternalProject_get_property(lief_spdlog SOURCE_DIR) +-set(SPDLOG_SOURCE_DIR "${SOURCE_DIR}") ++ ExternalProject_get_property(lief_spdlog_project SOURCE_DIR) ++ set(SPDLOG_SOURCE_DIR "${SOURCE_DIR}") ++ add_dependencies(lief_spdlog lief_spdlog_project) ++ target_include_directories(lief_spdlog SYSTEM INTERFACE ${SPDLOG_SOURCE_DIR}/include) ++endif() + + # Fuzzing + # ~~~~~~~ +diff --git a/cmake/LIEFOptions.cmake b/cmake/LIEFOptions.cmake +index fd6df6c..3bb92c3 100644 +--- a/cmake/LIEFOptions.cmake ++++ b/cmake/LIEFOptions.cmake +@@ -45,6 +45,10 @@ option(LIEF_PROFILING "Enable performance profiling" OFF) + cmake_dependent_option(LIEF_INSTALL_COMPILED_EXAMPLES "Install LIEF Compiled examples" OFF + "LIEF_EXAMPLES" OFF) + ++# Use a user-provided version of spdlog ++# It can be useful to reduce compile time ++option(LIEF_EXTERNAL_SPDLOG OFF) ++ + set(LIEF_ELF_SUPPORT 0) + set(LIEF_PE_SUPPORT 0) + set(LIEF_MACHO_SUPPORT 0) +diff --git a/setup.py b/setup.py +index b915180..ad70bd8 100644 +--- a/setup.py ++++ b/setup.py +@@ -45,6 +45,10 @@ class LiefDistribution(setuptools.Distribution): + ('lief-no-vdex', None, 'Disable VDEX module'), + ('lief-no-oat', None, 'Disable OAT module'), + ('lief-no-dex', None, 'Disable DEX module'), ++ ++ ('lief-no-cache', None, 'Do not use compiler cache (ccache)'), ++ ++ ('spdlog-dir=', None, 'Path to the directory that contains spdlogConfig.cmake'), + ] + + def __init__(self, attrs=None): +@@ -66,6 +70,10 @@ class LiefDistribution(setuptools.Distribution): + + self.lief_no_android = False + self.doc = False ++ ++ self.lief_no_cache = False ++ ++ self.spdlog_dir = None + super().__init__(attrs) + + +@@ -154,6 +162,15 @@ class BuildLibrary(build_ext): + else: + cmake_args += ["-DLIEF_LOGGING_DEBUG=off"] + ++ if self.distribution.lief_no_cache: ++ cmake_args += ["-DLIEF_USE_CCACHE=off"] ++ ++ # Setup spdlog configuration flags if ++ # the user provides --spdlog-dir ++ if self.distribution.spdlog_dir is not None: ++ cmake_args.append("-DLIEF_EXTERNAL_SPDLOG=ON") ++ cmake_args.append("-Dspdlog_DIR={}".format(self.distribution.spdlog_dir)) ++ + # Main formats + # ============ + if self.distribution.lief_no_elf: +-- +2.31.1 + diff --git a/recipes-devtools/python/python3-asttokens_2.0.5.bb b/recipes-devtools/python/python3-asttokens_2.0.5.bb new file mode 100644 index 0000000..7ac2052 --- /dev/null +++ b/recipes-devtools/python/python3-asttokens_2.0.5.bb @@ -0,0 +1,15 @@ +SUMMARY = "Annotate AST trees with source code positions" +HOMEPAGE = "https://github.com/gristlabs/asttokens" +AUTHOR = "Dmitry Sagalovskiy, Grist Labs <dmitry@...>" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" + +SRC_URI[md5sum] = "0a2a057b9c9a220bffdb3e7512062f17" +SRC_URI[sha256sum] = "9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5" + +RDEPENDS_${PN} = "python3-six" +DEPENDS += "python3-setuptools-scm python3-toml" + +inherit pypi setuptools3 + +BBCLASSEXTEND += "native" diff --git a/recipes-devtools/python/python3-checksec.py-native_0.6.1.bb b/recipes-devtools/python/python3-checksec.py-native_0.6.1.bb new file mode 100644 index 0000000..edce0a6 --- /dev/null +++ b/recipes-devtools/python/python3-checksec.py-native_0.6.1.bb @@ -0,0 +1,31 @@ +SUMMARY = "Tool to verify the security properties of binaries" +DESCRIPTION = "checksec.py is a tool verify if certain compiler flags \ + have been enabled on compield applications and libraries." +HOMEPAGE = "https://github.com/Wenzel/checksec.py" +BUGTRACKER = "https://github.com/Wenzel/checksec.py/issues" +SECTION = "devel/python" + +LICENSE = "GPL-3.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=1ebbd3e34237af26da5dc08a4e440464" + +RDEPENDS_${PN} += " \ + python3-docopt-native \ + python3-lief-native \ + python3-pylddwrap-native \ + python3-rich-native \ + " + +# Needs to be pulled from github becuase pypi package is currently broken +SRC_URI = " \ + git://github.com/Wenzel/checksec.py.git;protocol=https;branch=master \ + file://python3-checksec.py/0001-main-Add-option-to-ignore-symlinks.patch \ + file://python3-checksec.py/0002-Elf-Fix-relro-detection.patch \ + file://python3-checksec.py/0003-fortify-source-check-Treat-binaries-with-0-fortifiab.patch \ + " + +SRCREV = "4335ecd08f6ee13ff4ca9b01e83857ae6a8074e9" + +S="${WORKDIR}/git" + +inherit setuptools3 native + diff --git a/recipes-devtools/python/python3-colorama_%.bbappend b/recipes-devtools/python/python3-colorama_%.bbappend new file mode 100644 index 0000000..d6f5869 --- /dev/null +++ b/recipes-devtools/python/python3-colorama_%.bbappend @@ -0,0 +1 @@ +BBCLASSEXTEND += "native" diff --git a/recipes-devtools/python/python3-commonmark_0.9.1.bb b/recipes-devtools/python/python3-commonmark_0.9.1.bb new file mode 100644 index 0000000..a35abc3 --- /dev/null +++ b/recipes-devtools/python/python3-commonmark_0.9.1.bb @@ -0,0 +1,14 @@ +SUMMARY = "Python parser for the CommonMark Markdown spec" +HOMEPAGE = "https://github.com/rtfd/commonmark.py" +AUTHOR = "Bibek Kafle <bkafle662@...>, Roland Shoemaker <rolandshoemaker@...>" +LICENSE = "BSD-3-Clause" +LIC_FILES_CHKSUM = "file://LICENSE;md5=37e127eb75a030780aefcfc584e78523" + +SRC_URI[md5sum] = "cd1dc70c4714d9ed4117a40490c25e00" +SRC_URI[sha256sum] = "452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60" + +S = "${WORKDIR}/commonmark-0.9.1" + +inherit pypi setuptools3 + +BBCLASSEXTEND += "native" diff --git a/recipes-devtools/python/python3-docopt_0.6.2.bb b/recipes-devtools/python/python3-docopt_0.6.2.bb new file mode 100644 index 0000000..c1b111a --- /dev/null +++ b/recipes-devtools/python/python3-docopt_0.6.2.bb @@ -0,0 +1,18 @@ + +SUMMARY = "Pythonic argument parser, that will make you smile" +HOMEPAGE = "http://docopt.org" +AUTHOR = "Vladimir Keleshev <vladimir@...>" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE-MIT;md5=09b77fb74986791a3d4a0e746a37d88f" + +SRC_URI = "https://github.com/docopt/docopt/archive/refs/tags/${PV}.tar.gz" +SRC_URI[md5sum] = "a6c44155426fd0f7def8b2551d02fef6" +SRC_URI[sha256sum] = "2113eed1e7fbbcd43fb7ee6a977fb02d0b482753586c9dc1a8e3b7d541426e99" + +S = "${WORKDIR}/docopt-0.6.2" + +RDEPENDS_${PN} = "" + +inherit setuptools3 + +BBCLASSEXTEND += "native" diff --git a/recipes-devtools/python/python3-icontract_2.5.3.bb b/recipes-devtools/python/python3-icontract_2.5.3.bb new file mode 100644 index 0000000..88ac2ef --- /dev/null +++ b/recipes-devtools/python/python3-icontract_2.5.3.bb @@ -0,0 +1,14 @@ +SUMMARY = "Provide design-by-contract with informative violation messages." +HOMEPAGE = "https://github.com/Parquery/icontract" +AUTHOR = "Marko Ristin <marko.ristin@...>" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=1d4a9b1f6b84bedf7a38843931e0dd57" + +SRC_URI[md5sum] = "6f41b9b84e4405374c160836587b3235" +SRC_URI[sha256sum] = "b790101c8cc0d9df0105d852a645373c4d90d5049391b6e54db32a0acb4bccd7" + +inherit pypi setuptools3 + +RDEPENDS_${PN} += "python3-asttokens" + +BBCLASSEXTEND += "native" diff --git a/recipes-devtools/python/python3-lief_0.11.5.bb b/recipes-devtools/python/python3-lief_0.11.5.bb new file mode 100644 index 0000000..5e4b422 --- /dev/null +++ b/recipes-devtools/python/python3-lief_0.11.5.bb @@ -0,0 +1,36 @@ +SUMMARY = "Library to instrument executable formats" +DESCRIPTION = " \ + This project provides a cross platform library which can parse, modify \ + and abstract ELF, PE and MachO formats. \ + " +SECTION = "devel/python" +HOMEPAGE = "https://github.com/lief-project/LIEF" +LICENSE = "APACHE-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=1809bd489c3dae63aa0cb70070dc308e" + +SRC_URI = " \ + https://github.com/lief-project/LIEF/releases/download/${PV}/lief-${PV}.zip \ + file://python3-lief/0001-Enable-to-use-pre-compiled-version-of-spdlog.patch \ + " +SRC_URI[sha256sum] = "947825134d5dab91df218bb201fa4551814f1da0a47e4a890283716b800c8e8f" + +S = "${WORKDIR}/lief-${PV}" + +inherit setuptools3 + +DEPENDS += "cmake-native" + +BBCLASSEXTEND += "native" + +DISTUTILS_BUILD_ARGS += " ${PARALLEL_MAKE} " + +do_compile() { + # From distutils3.bbclass (needs to be modified here to avoid usage of ccache) + cd ${DISTUTILS_SETUP_PATH} + NO_FETCH_BUILD=1 \ + STAGING_INCDIR=${STAGING_INCDIR} \ + STAGING_LIBDIR=${STAGING_LIBDIR} \ + ${STAGING_BINDIR_NATIVE}/${PYTHON_PN}-native/${PYTHON_PN} setup.py \ + --lief-no-cache build --build-base=${B} ${DISTUTILS_BUILD_ARGS} || \ + bbfatal_log "'${PYTHON_PN} setup.py --lief-no-cache build ${DISTUTILS_BUILD_ARGS}' execution failed." +} diff --git a/recipes-devtools/python/python3-pylddwrap_1.0.1.bb b/recipes-devtools/python/python3-pylddwrap_1.0.1.bb new file mode 100644 index 0000000..985c424 --- /dev/null +++ b/recipes-devtools/python/python3-pylddwrap_1.0.1.bb @@ -0,0 +1,21 @@ +SUMMARY = "Python wrapper for ldd" +DESCRIPTION = " \ + Pylddwrap wraps ldd *nix utility to determine shared libraries required by a program. \ + " +SECTION = "devel/python" +HOMEPAGE = "https://github.com/Parquery/pylddwrap" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=48fd6c978d39a38b3a04f45a1456d0fa" + +SRC_URI[sha256sum] = "171a39fc7feb33e607706c57c08373ceb2f6fd4362af9241ccc65e80c948ccdf" + +inherit pypi setuptools3 + +RDEPENDS_${PN} += "python3-icontract" + +do_install_append() { + rm -f "${D}/${datadir}/requirements.txt" + rm -f "${D}/${datadir}/README.rst" +} + +BBCLASSEXTEND += "native" diff --git a/recipes-devtools/python/python3-rich_7.1.0.bb b/recipes-devtools/python/python3-rich_7.1.0.bb new file mode 100644 index 0000000..59c26a4 --- /dev/null +++ b/recipes-devtools/python/python3-rich_7.1.0.bb @@ -0,0 +1,16 @@ +SUMMARY = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +HOMEPAGE = "https://github.com/willmcgugan/rich" +AUTHOR = "Will McGugan <willmcgugan@...>" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=d0d35d5357392e5bfeb0d0a7e6ba4d83" + +SRC_URI[md5sum] = "25daeefa226770a84b98c591069b419c" +SRC_URI[sha256sum] = "ff701be541be32bcf46e821487c00bf4fa560aa814fc3cc9b3d514fd9b19a6f6" + +S = "${WORKDIR}/rich-7.1.0" + +RDEPENDS_${PN} = "python3-typing-extensions python3-pygments python3-commonmark python3-colorama" + +inherit pypi setuptools3 + +BBCLASSEXTEND += "native" diff --git a/recipes-devtools/python/python3-setuptools-scm_6.0.1.bb b/recipes-devtools/python/python3-setuptools-scm_6.0.1.bb new file mode 100644 index 0000000..234694e --- /dev/null +++ b/recipes-devtools/python/python3-setuptools-scm_6.0.1.bb @@ -0,0 +1,17 @@ +SUMMARY = "the blessed package to manage your versions by scm tags" +HOMEPAGE = "https://github.com/pypa/setuptools_scm/" +AUTHOR = "Ronny Pfannschmidt <opensource@...>" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://LICENSE;md5=838c366f69b72c5df05c96dff79b35f2" + +SRC_URI = "git://github.com/pypa/setuptools_scm.git;protocol=https;branch=main;tag=v${PV}" + +SRC_URI[sha256sum] = "8f85bfc7272fb5c04df28f00bde9db8f862c586d25fa155eea90fe62ea6a3302" + +RDEPENDS_${PN} = "python3-setuptools" + +inherit setuptools3 + +S = "${WORKDIR}/git" + +BBCLASSEXTEND += "native" diff --git a/recipes-devtools/python/python3-toml_%.bbappend b/recipes-devtools/python/python3-toml_%.bbappend new file mode 100644 index 0000000..d6f5869 --- /dev/null +++ b/recipes-devtools/python/python3-toml_%.bbappend @@ -0,0 +1 @@ +BBCLASSEXTEND += "native" -- 2.31.1
|
|