From a840b02af463098743182dbe94207a3a8fffa206 Mon Sep 17 00:00:00 2001 From: Fabrice Fontaine Date: Thu, 6 Mar 2025 14:34:29 +0100 Subject: [PATCH] Handle ELF binary with no program segments Do not return False for NX and No for RELRO when there is no program segments in the ELF binary file (e.g. kernel module). This is inspired from https://github.com/slimm609/checksec/commit/29aea688e10b5c16d1cf60e3968f170b2147c150 For RELRO, a new NA value is added For NX, True is returned to avoid changing NX type from boolean to string Signed-off-by: Fabrice Fontaine --- checksec/binary.py | 7 ++++++- checksec/elf.py | 6 ++++++ tests/binaries | 2 +- tests/e2e/test_e2e_elf.py | 4 ++-- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/checksec/binary.py b/checksec/binary.py index 470b4db..1783b4c 100644 --- a/checksec/binary.py +++ b/checksec/binary.py @@ -19,7 +19,12 @@ def __init__(self, bin_path: Path): @property def has_nx(self) -> bool: - return self.bin.has_nx + # Handle ELF binary with no program segments (e.g., Kernel modules) + # In this case, return True + if isinstance(self.bin, lief.ELF.Binary) and len(self.bin.segments) == 0: + return True + else: + return self.bin.has_nx @property def checksec_state(self) -> Union["ELFChecksecData", "PEChecksecData"]: diff --git a/checksec/elf.py b/checksec/elf.py index 42b10a4..8436a97 100644 --- a/checksec/elf.py +++ b/checksec/elf.py @@ -70,6 +70,7 @@ class RelroType(Enum): No = 1 Partial = 2 Full = 3 + NA = 4 class PIEType(Enum): @@ -117,6 +118,11 @@ def set_dyn_syms(self) -> FrozenSet[str]: @property def relro(self) -> RelroType: + # Handle binary with no program segments (e.g., Kernel modules) + # In this case, return NA + if len(self.bin.segments) == 0: + return RelroType.NA + if self.bin.get(lief.ELF.Segment.TYPE.GNU_RELRO) is None: return RelroType.No diff --git a/tests/binaries b/tests/binaries index 9f7d669..e84b457 160000 --- a/tests/binaries +++ b/tests/binaries @@ -1 +1 @@ -Subproject commit 9f7d669687ac1faa105e3875e93c4447f078bc34 +Subproject commit e84b457b1c9ce97081e4777f2307ec60e19570a5 diff --git a/tests/e2e/test_e2e_elf.py b/tests/e2e/test_e2e_elf.py index 1db5d53..1e3d2f3 100644 --- a/tests/e2e/test_e2e_elf.py +++ b/tests/e2e/test_e2e_elf.py @@ -22,7 +22,7 @@ def test_bool_prop(prop: str, is_enabled: bool): @pytest.mark.parametrize("relro_type", list(RelroType)) def test_relro(relro_type: RelroType): - """Test that relro type is No/Partial/Full""" + """Test that relro type is No/Partial/Full/NA""" bin_path = ELF_BINARIES / f"relro_{relro_type.name.lower()}" chk_data = run_checksec(bin_path) assert chk_data[str(bin_path)]["relro"] == relro_type.name @@ -37,7 +37,7 @@ def test_relro_full_df1(): @pytest.mark.parametrize("pie_type", list(PIEType)) def test_pie(pie_type): - """Test that PIE is No/Partial/Full""" + """Test that PIE is No/Partial/Full/NA""" bin_path = ELF_BINARIES / f"pie_{pie_type.name.lower()}" chk_data = run_checksec(bin_path) assert chk_data[str(bin_path)]["pie"] == pie_type.name