deps: bump lief to 0.16.6
Some of the primary changes are:
- lief.EXE_FORMATS became lief.Binary.FORMATS IN 0.14.0
- https://github.com/lief-project/LIEF/blob/494f116c6b8c9163fc4b5f6497233f18424981ee/doc/sphinx/changelog.rst?plain=1#L702
- lief.ARCHITECTURES became lief.Header.ARCHITECTURES in 0.16.0
- https://github.com/lief-project/LIEF/blob/494f116c6b8c9163fc4b5f6497233f18424981ee/doc/sphinx/changelog.rst?plain=1#L226C18-L227C18
- lief.ELF.ARCH.x86_64 became lief.ELF.ARCH.X86_64
This commit includes a workaround for the bug fixed in
https://github.com/lief-project/LIEF/pull/1218, but the workaround can
be kept, since it makes `has_nx` checks stricter by enforcing both heap
and stack are non-executable.
This change also requires a patch to partially revert a commit to LIEF
(https://github.com/lief-project/LIEF/commit/f23ced2f4ffc170d0a6f40ff4a1bee575e3447cf)
which broke compatibility with versions of scikit-build-core <= 0.10.x.
This patch can be dropped once the guix time machine advances to or
beyond https://codeberg.org/guix/guix/commit/35c5f07e967155d2276c7ec58e5108e4da02c974,
which bumps the scikit-build-core version in guix from 0.9.3 to 0.10.7.
Co-authored-by: willcl-ark <will8clark@gmail.com>
Co-authored-by: fanquake <fanquake@gmail.com>
Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
This commit is contained in:
1 parent
e872a566f2
commit
765922d802
5 files changed
+96
-68
No files matched your search
@@ -30,13 +30,13 @@ def check_ELF_RELRO(binary) -> bool:
|
||||
# However, the dynamic linker need to write to this area so these are RW.
|
||||
# Glibc itself takes care of mprotecting this area R after relocations are finished.
|
||||
# See also https://marc.info/?l=binutils&m=1498883354122353
|
||||
if segment.type == lief.ELF.SEGMENT_TYPES.GNU_RELRO:
|
||||
if segment.type == lief.ELF.Segment.TYPE.GNU_RELRO:
|
||||
have_gnu_relro = True
|
||||
|
||||
have_bindnow = False
|
||||
try:
|
||||
flags = binary.get(lief.ELF.DYNAMIC_TAGS.FLAGS)
|
||||
if flags.value & lief.ELF.DYNAMIC_FLAGS.BIND_NOW:
|
||||
flags = binary.get(lief.ELF.DynamicEntry.TAG.FLAGS)
|
||||
if flags.has(lief.ELF.DynamicEntryFlags.FLAG.BIND_NOW):
|
||||
have_bindnow = True
|
||||
except Exception:
|
||||
have_bindnow = False
|
||||
@@ -55,9 +55,9 @@ def check_ELF_SEPARATE_CODE(binary):
|
||||
based on their permissions. This checks for missing -Wl,-z,separate-code
|
||||
and potentially other problems.
|
||||
'''
|
||||
R = lief.ELF.SEGMENT_FLAGS.R
|
||||
W = lief.ELF.SEGMENT_FLAGS.W
|
||||
E = lief.ELF.SEGMENT_FLAGS.X
|
||||
R = lief.ELF.Segment.FLAGS.R
|
||||
W = lief.ELF.Segment.FLAGS.W
|
||||
E = lief.ELF.Segment.FLAGS.X
|
||||
EXPECTED_FLAGS = {
|
||||
# Read + execute
|
||||
'.init': R | E,
|
||||
@@ -99,7 +99,7 @@ def check_ELF_SEPARATE_CODE(binary):
|
||||
# and for each section, remember the flags of the associated program header.
|
||||
flags_per_section = {}
|
||||
for segment in binary.segments:
|
||||
if segment.type == lief.ELF.SEGMENT_TYPES.LOAD:
|
||||
if segment.type == lief.ELF.Segment.TYPE.LOAD:
|
||||
for section in segment.sections:
|
||||
flags_per_section[section.name] = segment.flags
|
||||
# Spot-check ELF LOAD program header flags per section
|
||||
@@ -144,13 +144,13 @@ def check_ELF_FORTIFY(binary) -> bool:
|
||||
|
||||
def check_PE_DYNAMIC_BASE(binary) -> bool:
|
||||
'''PIE: DllCharacteristics bit 0x40 signifies dynamicbase (ASLR)'''
|
||||
return lief.PE.DLL_CHARACTERISTICS.DYNAMIC_BASE in binary.optional_header.dll_characteristics_lists
|
||||
return lief.PE.OptionalHeader.DLL_CHARACTERISTICS.DYNAMIC_BASE in binary.optional_header.dll_characteristics_lists
|
||||
|
||||
# Must support high-entropy 64-bit address space layout randomization
|
||||
# in addition to DYNAMIC_BASE to have secure ASLR.
|
||||
def check_PE_HIGH_ENTROPY_VA(binary) -> bool:
|
||||
'''PIE: DllCharacteristics bit 0x20 signifies high-entropy ASLR'''
|
||||
return lief.PE.DLL_CHARACTERISTICS.HIGH_ENTROPY_VA in binary.optional_header.dll_characteristics_lists
|
||||
return lief.PE.OptionalHeader.DLL_CHARACTERISTICS.HIGH_ENTROPY_VA in binary.optional_header.dll_characteristics_lists
|
||||
|
||||
def check_PE_RELOC_SECTION(binary) -> bool:
|
||||
'''Check for a reloc section. This is required for functional ASLR.'''
|
||||
@@ -181,7 +181,7 @@ def check_MACHO_NOUNDEFS(binary) -> bool:
|
||||
'''
|
||||
Check for no undefined references.
|
||||
'''
|
||||
return binary.header.has(lief.MachO.HEADER_FLAGS.NOUNDEFS)
|
||||
return binary.header.has(lief.MachO.Header.FLAGS.NOUNDEFS)
|
||||
|
||||
def check_MACHO_FIXUP_CHAINS(binary) -> bool:
|
||||
'''
|
||||
@@ -206,7 +206,13 @@ def check_NX(binary) -> bool:
|
||||
'''
|
||||
Check for no stack execution
|
||||
'''
|
||||
return binary.has_nx
|
||||
|
||||
# binary.has_nx checks are only for the stack, but MachO binaries might
|
||||
# have executable heaps.
|
||||
if binary.format == lief.Binary.FORMATS.MACHO:
|
||||
return binary.concrete.has_nx_stack and binary.concrete.has_nx_heap
|
||||
else:
|
||||
return binary.has_nx
|
||||
|
||||
def check_MACHO_CONTROL_FLOW(binary) -> bool:
|
||||
'''
|
||||
@@ -253,21 +259,21 @@ BASE_MACHO = [
|
||||
]
|
||||
|
||||
CHECKS = {
|
||||
lief.EXE_FORMATS.ELF: {
|
||||
lief.ARCHITECTURES.X86: BASE_ELF + [('CONTROL_FLOW', check_ELF_CONTROL_FLOW), ('FORTIFY', check_ELF_FORTIFY)],
|
||||
lief.ARCHITECTURES.ARM: BASE_ELF + [('FORTIFY', check_ELF_FORTIFY)],
|
||||
lief.ARCHITECTURES.ARM64: BASE_ELF + [('FORTIFY', check_ELF_FORTIFY)],
|
||||
lief.ARCHITECTURES.PPC: BASE_ELF + [('FORTIFY', check_ELF_FORTIFY)],
|
||||
lief.ARCHITECTURES.RISCV: BASE_ELF, # Skip FORTIFY. See https://github.com/lief-project/LIEF/issues/1082.
|
||||
lief.Binary.FORMATS.ELF: {
|
||||
lief.Header.ARCHITECTURES.X86_64: BASE_ELF + [('CONTROL_FLOW', check_ELF_CONTROL_FLOW), ('FORTIFY', check_ELF_FORTIFY)],
|
||||
lief.Header.ARCHITECTURES.ARM: BASE_ELF + [('FORTIFY', check_ELF_FORTIFY)],
|
||||
lief.Header.ARCHITECTURES.ARM64: BASE_ELF + [('FORTIFY', check_ELF_FORTIFY)],
|
||||
lief.Header.ARCHITECTURES.PPC64: BASE_ELF + [('FORTIFY', check_ELF_FORTIFY)],
|
||||
lief.Header.ARCHITECTURES.RISCV: BASE_ELF, # Skip FORTIFY. See https://github.com/lief-project/LIEF/issues/1082.
|
||||
},
|
||||
lief.EXE_FORMATS.PE: {
|
||||
lief.ARCHITECTURES.X86: BASE_PE,
|
||||
lief.Binary.FORMATS.PE: {
|
||||
lief.Header.ARCHITECTURES.X86_64: BASE_PE,
|
||||
},
|
||||
lief.EXE_FORMATS.MACHO: {
|
||||
lief.ARCHITECTURES.X86: BASE_MACHO + [('PIE', check_PIE),
|
||||
lief.Binary.FORMATS.MACHO: {
|
||||
lief.Header.ARCHITECTURES.X86_64: BASE_MACHO + [('PIE', check_PIE),
|
||||
('NX', check_NX),
|
||||
('CONTROL_FLOW', check_MACHO_CONTROL_FLOW)],
|
||||
lief.ARCHITECTURES.ARM64: BASE_MACHO + [('BRANCH_PROTECTION', check_MACHO_BRANCH_PROTECTION)],
|
||||
lief.Header.ARCHITECTURES.ARM64: BASE_MACHO + [('BRANCH_PROTECTION', check_MACHO_BRANCH_PROTECTION)],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,9 +281,9 @@ if __name__ == '__main__':
|
||||
retval: int = 0
|
||||
for filename in sys.argv[1:]:
|
||||
binary = lief.parse(filename)
|
||||
|
||||
etype = binary.format
|
||||
arch = binary.abstract.header.architecture
|
||||
binary.concrete
|
||||
|
||||
failed: list[str] = []
|
||||
for (name, func) in CHECKS[etype][arch]:
|
||||
|
||||
Reference in new issue
Block a user