symbol-check: Check requested ELF interpreter

It is important that binaries request a standard interpreter location
where most distros would place the linker-loader. Otherwise, the user
would be met with a very confusing message:

    bash: <path>/<to>/bitcoind: No such file or directory

When really it's the interpreter that's not found.
pull/826/head
Carl Dong 3 years ago
parent b96adcbfae
commit 1527b7e8a1

@ -11,7 +11,7 @@ Example usage:
find ../path/to/binaries -type f -executable | xargs python3 contrib/devtools/symbol-check.py find ../path/to/binaries -type f -executable | xargs python3 contrib/devtools/symbol-check.py
''' '''
import sys import sys
from typing import List from typing import List, Dict
import lief import lief
@ -63,6 +63,30 @@ IGNORE_EXPORTS = {
'environ', '_environ', '__environ', 'environ', '_environ', '__environ',
} }
# Expected linker-loader names can be found here:
# https://sourceware.org/glibc/wiki/ABIList?action=recall&rev=16
ELF_INTERPRETER_NAMES: Dict[lief.ELF.ARCH, Dict[lief.ENDIANNESS, str]] = {
lief.ELF.ARCH.i386: {
lief.ENDIANNESS.LITTLE: "/lib/ld-linux.so.2",
},
lief.ELF.ARCH.x86_64: {
lief.ENDIANNESS.LITTLE: "/lib64/ld-linux-x86-64.so.2",
},
lief.ELF.ARCH.ARM: {
lief.ENDIANNESS.LITTLE: "/lib/ld-linux-armhf.so.3",
},
lief.ELF.ARCH.AARCH64: {
lief.ENDIANNESS.LITTLE: "/lib/ld-linux-aarch64.so.1",
},
lief.ELF.ARCH.PPC64: {
lief.ENDIANNESS.BIG: "/lib64/ld64.so.1",
lief.ENDIANNESS.LITTLE: "/lib64/ld64.so.2",
},
LIEF_ELF_ARCH_RISCV: {
lief.ENDIANNESS.LITTLE: "/lib/ld-linux-riscv64-lp64d.so.1",
},
}
# Allowed NEEDED libraries # Allowed NEEDED libraries
ELF_ALLOWED_LIBRARIES = { ELF_ALLOWED_LIBRARIES = {
# bitcoind and bitcoin-qt # bitcoind and bitcoin-qt
@ -215,11 +239,17 @@ def check_PE_subsystem_version(binary) -> bool:
return True return True
return False return False
def check_ELF_interpreter(binary) -> bool:
expected_interpreter = ELF_INTERPRETER_NAMES[binary.header.machine_type][binary.abstract.header.endianness]
return binary.concrete.interpreter == expected_interpreter
CHECKS = { CHECKS = {
'ELF': [ 'ELF': [
('IMPORTED_SYMBOLS', check_imported_symbols), ('IMPORTED_SYMBOLS', check_imported_symbols),
('EXPORTED_SYMBOLS', check_exported_symbols), ('EXPORTED_SYMBOLS', check_exported_symbols),
('LIBRARY_DEPENDENCIES', check_ELF_libraries) ('LIBRARY_DEPENDENCIES', check_ELF_libraries),
('INTERPRETER_NAME', check_ELF_interpreter),
], ],
'MACHO': [ 'MACHO': [
('DYNAMIC_LIBRARIES', check_MACHO_libraries), ('DYNAMIC_LIBRARIES', check_MACHO_libraries),

Loading…
Cancel
Save