arch: add BR2_READELF_ARCH_NAME hidden config option
Subsystems (2)
PATCH 1/2 arch: add BR2_READELF_ARCH_NAME hidden config option
This config option corresponds to the string returned by readelf for the "Machine" field of the ELF header. It will be used to check if the architecture of binaries built by Buildroot match the target architecture.
--- arch/Config.in | 4 ++++ arch/Config.in.arc | 3 +++ arch/Config.in.arm | 4 ++++ arch/Config.in.bfin | 3 +++ arch/Config.in.csky | 2 ++ arch/Config.in.m68k | 3 +++ arch/Config.in.microblaze | 3 +++ arch/Config.in.mips | 3 +++ arch/Config.in.nios2 | 3 +++ arch/Config.in.or1k | 3 +++ arch/Config.in.powerpc | 4 ++++ arch/Config.in.sh | 3 +++ arch/Config.in.sparc | 4 ++++ arch/Config.in.x86 | 4 ++++ arch/Config.in.xtensa | 3 +++ 15 files changed, 49 insertions(+)
arch/Config.in +4 -0
@@ -292,6 +292,10 @@ config BR2_GCC_TARGET_MODE config BR2_BINFMT_SUPPORTS_SHARED bool +# Must match the name of the architecture from readelf point of view +config BR2_READELF_ARCH_NAME + string + # Set up target binary format choice prompt "Target Binary Format"
arch/Config.in.arc +3 -0
@@ -38,6 +38,9 @@ config BR2_GCC_TARGET_CPU default "arc700" if BR2_arc770d default "archs" if BR2_archs38 +config BR2_READELF_ARCH_NAME + default "ARCv2" + choice prompt "MMU Page Size" default BR2_ARC_PAGE_SIZE_8K
arch/Config.in.arm +4 -0
@@ -568,3 +568,7 @@ config BR2_GCC_TARGET_FLOAT_ABI config BR2_GCC_TARGET_MODE default "arm" if BR2_ARM_INSTRUCTIONS_ARM default "thumb" if BR2_ARM_INSTRUCTIONS_THUMB || BR2_ARM_INSTRUCTIONS_THUMB2 + +config BR2_READELF_ARCH_NAME + default "ARM" if BR2_arm || BR2_armeb + default "AArch64" if BR2_aarch64 || BR2_aarch64_be
arch/Config.in.bfin +3 -0
@@ -105,3 +105,6 @@ config BR2_GCC_TARGET_CPU_REVISION value of the -mcpu option. For example, if the selected CPU is bf609, and then selected CPU revision is "0.0", then gcc will receive the -mcpu=bf609-0.0 option. + +config BR2_READELF_ARCH_NAME + default "Analog Devices Blackfin"
arch/Config.in.csky +2 -0
@@ -44,3 +44,5 @@ config BR2_GCC_TARGET_CPU default "ck810f" if (BR2_ck810 && BR2_CSKY_FPU && !BR2_CSKY_DSP) default "ck810ef" if (BR2_ck810 && BR2_CSKY_FPU && BR2_CSKY_DSP) +config BR2_READELF_ARCH_NAME + default "CSKY"
arch/Config.in.m68k +3 -0
@@ -35,3 +35,6 @@ endchoice config BR2_GCC_TARGET_CPU default "68040" if BR2_m68k_68040 default "5208" if BR2_m68k_cf5208 + +config BR2_READELF_ARCH_NAME + default "MC68000"
arch/Config.in.microblaze +3 -0
@@ -6,6 +6,9 @@ config BR2_ENDIAN default "LITTLE" if BR2_microblazeel default "BIG" if BR2_microblazebe +config BR2_READELF_ARCH_NAME + default "Xilinx MicroBlaze" + config BR2_microblaze bool default y if BR2_microblazeel || BR2_microblazebe
arch/Config.in.mips +3 -0
@@ -161,3 +161,6 @@ config BR2_GCC_TARGET_ABI default "32" if BR2_MIPS_OABI32 default "n32" if BR2_MIPS_NABI32 default "64" if BR2_MIPS_NABI64 + +config BR2_READELF_ARCH_NAME + default "MIPS R3000"
arch/Config.in.nios2 +3 -0
@@ -3,3 +3,6 @@ config BR2_ARCH config BR2_ENDIAN default "LITTLE" + +config BR2_READELF_ARCH_NAME + default "Altera Nios II"
arch/Config.in.or1k +3 -0
@@ -3,3 +3,6 @@ config BR2_ARCH config BR2_ENDIAN default "BIG" + +config BR2_READELF_ARCH_NAME + default "OpenRISC 1000"
arch/Config.in.powerpc +4 -0
@@ -212,3 +212,7 @@ config BR2_GCC_TARGET_ABI default "no-spe" if BR2_PPC_ABI_no-spe default "ibmlongdouble" if BR2_PPC_ABI_ibmlongdouble default "ieeelongdouble" if BR2_PPC_ABI_ieeelongdouble + +config BR2_READELF_ARCH_NAME + default "PowerPC" if BR2_powerpc + default "PowerPC64" if BR2_powerpc64 || BR2_powerpc64le
arch/Config.in.sh +3 -0
@@ -27,3 +27,6 @@ config BR2_ARCH config BR2_ENDIAN default "LITTLE" if BR2_sh4 || BR2_sh4a default "BIG" if BR2_sh2a || BR2_sh4eb || BR2_sh4aeb + +config BR2_READELF_ARCH_NAME + default "Renesas / SuperH SH"
arch/Config.in.sparc +4 -0
@@ -28,3 +28,7 @@ config BR2_GCC_TARGET_CPU default "leon3" if BR2_sparc_leon3 default "v8" if BR2_sparc_v8 default "ultrasparc" if BR2_sparc_v9 + +config BR2_READELF_ARCH_NAME + default "Sparc" if BR2_sparc + default "Sparc v9" if BR2_sparc64
arch/Config.in.x86 +4 -0
@@ -275,3 +275,7 @@ config BR2_GCC_TARGET_ARCH default "c3" if BR2_x86_c3 default "c3-2" if BR2_x86_c32 default "geode" if BR2_x86_geode + +config BR2_READELF_ARCH_NAME + default "Intel 80386" if BR2_i386 + default "Advanced Micro Devices X86-64" if BR2_x86_64
arch/Config.in.xtensa +3 -0
@@ -54,3 +54,6 @@ config BR2_ENDIAN config BR2_ARCH default "xtensa" if BR2_xtensa + +config BR2_READELF_ARCH_NAME + default "Tensilica Xtensa Processor"
Signature · 1 line
2.7.4
PATCH 2/2 Makefile: add check of binaries architecture
As shown recently by the firejail example, it is easy to miss that a package builds and installs binaries without actually cross-compiling
them: they are built for the host architecture instead of the target architecture.
This commit adds a small helper script, check-bin-arch, called from the main Makefile as a TARGET_FINALIZE_HOOKS, to verify that all ELF binaries have been built for the correct CPU architecture.
Example output with the firejail package enabled, when building for an ARM target:
support/scripts/check-bin-arch .../buildroot/output/target .../buildroot/output/host/usr/bin/arm-linux-gnueabihf- "ARM"
ERROR: .../buildroot/output/target/usr/bin/firemon architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/bin/firejail architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/bin/firecfg architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/lib/firejail/libconnect.so architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/lib/firejail/faudit architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/lib/firejail/ftee architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/lib/firejail/libtrace.so architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/lib/firejail/libtracelog.so architecture is 'Advanced Micro Devices X86-64', should be 'ARM' Makefile:665: recipe for target 'target-finalize' failed
make[1]: *** [target-finalize] Error 1
--- Makefile | 10 ++++++++++ support/scripts/check-bin-arch | 30 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100755 support/scripts/check-bin-arch
Makefile +10 -0
@@ -649,6 +649,16 @@ endef TARGET_FINALIZE_HOOKS += PURGE_LOCALES endif +READELF_ARCH_NAME = $(call qstrip,$(BR2_READELF_ARCH_NAME)) + +ifneq ($(READELF_ARCH_NAME),) +define CHECK_BIN_ARCH + support/scripts/check-bin-arch $(TARGET_DIR) \ + $(TARGET_CROSS) "$(READELF_ARCH_NAME)" +endef +TARGET_FINALIZE_HOOKS += CHECK_BIN_ARCH +endif + $(TARGETS_ROOTFS): target-finalize target-finalize: $(PACKAGES)
support/scripts/check-bin-arch new file +30 -0
@@ -0,0 +1,30 @@ +#!/bin/sh + +# This script looks at all files in the target filesystem, and for +# those that are ELF files, verifies that they have been built for the +# correct architecture. + +TARGET_DIR=$1 +TARGET_CROSS=$2 +READELF_ARCH_NAME=$3 + +exitcode=0 + +for f in $(find ${TARGET_DIR} -type f) ; do + # Skip non-ELF files + if ! file -b ${f} | grep -q "ELF " ; then + continue + fi + + # Get architecture using readelf + farchname=$(${TARGET_CROSS}readelf -h ${f} | \ + grep '^ Machine:' | \ + sed 's/^ Machine: *\(.*\)/\1/') + + if test "${farchname}" != "${READELF_ARCH_NAME}" ; then + echo "ERROR: ${f} architecture is '${farchname}', should be '${READELF_ARCH_NAME}'" + exitcode=1 + fi +done + +exit ${exitcode}
Signature · 1 line
2.7.4
PATCH 2/2 Makefile: add check of binaries architecture
Thomas, All,
On 2017-03-12 16:06 +0100, Thomas Petazzoni spake thusly:
Quoted 8 lines
As shown recently by the firejail example, it is easy to miss that a package builds and installs binaries without actually cross-compiling
them: they are built for the host architecture instead of the target architecture.This commit adds a small helper script, check-bin-arch, called from the main
Makefileas aTARGET_FINALIZE_HOOKS, to verify that all ELF binaries have been built for the correct CPU architecture.
That is not possible in all situations.
For example, I have a board here with a kind of co-processor of a different architecture; the firmware for that co-processor is loaded at runtime. It is an ELF file, and it is in target/.
So I don't think it is possible to check that all ELF files are for the Buildroot-known target.
We already discussed this a while ago and came to the same conclusiong back then.
Regards,
Yann E. MORIN.
Quoted 82 lines
Example output with the firejail package enabled, when building for an ARM target:
support/scripts/check-bin-arch .../buildroot/output/target .../buildroot/output/host/usr/bin/arm-linux-gnueabihf- "ARM"
ERROR: .../buildroot/output/target/usr/bin/firemon architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/bin/firejail architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/bin/firecfg architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/lib/firejail/libconnect.so architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/lib/firejail/faudit architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/lib/firejail/ftee architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/lib/firejail/libtrace.so architecture is 'Advanced Micro Devices X86-64', should be 'ARM'
ERROR: .../buildroot/output/target/usr/lib/firejail/libtracelog.so architecture is 'Advanced Micro Devices X86-64', should be 'ARM' Makefile:665: recipe for target 'target-finalize' failed
make[1]: *** [target-finalize] Error 1Signed-off-by Thomas Petazzoni <[email protected]>--- Makefile | 10 ++++++++++ support/scripts/check-bin-arch | 30 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100755 support/scripts/check-bin-archMakefile +10
-0@@ -649,6 +649,16 @@ endef TARGET_FINALIZE_HOOKS += PURGE_LOCALES endif +READELF_ARCH_NAME = $(call qstrip,$(BR2_READELF_ARCH_NAME)) + +ifneq ($(READELF_ARCH_NAME),) +define CHECK_BIN_ARCH + support/scripts/check-bin-arch $(TARGET_DIR) \ + $(TARGET_CROSS) "$(READELF_ARCH_NAME)" +endef +TARGET_FINALIZE_HOOKS += CHECK_BIN_ARCH +endif + $(TARGETS_ROOTFS): target-finalize target-finalize: $(PACKAGES)support/scripts/check-bin-arch new file +30
-0@@ -0,0 +1,30 @@ +#!/bin/sh + +# This script looks at all files in the target filesystem, and for +# those that are ELF files, verifies that they have been built for the +# correct architecture. + +TARGET_DIR=$1 +TARGET_CROSS=$2 +READELF_ARCH_NAME=$3 + +exitcode=0 + +for f in $(find ${TARGET_DIR} -type f) ; do + # Skip non-ELF files + if ! file -b ${f} | grep -q "ELF " ; then + continue + fi + + # Get architecture using readelf + farchname=$(${TARGET_CROSS}readelf -h ${f} | \ + grep '^ Machine:' | \ + sed 's/^ Machine: *\(.*\)/\1/') + + if test "${farchname}" != "${READELF_ARCH_NAME}" ; then + echo "ERROR: ${f} architecture is '${farchname}', should be '${READELF_ARCH_NAME}'" + exitcode=1 + fi +done + +exit ${exitcode}Signature · 1 line
2.7.4
Signature · 6 lines
.-----------------.--------------------.------------------.--------------------. | Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: | | +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ | | +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no | | http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. | '------------------------------^-------^------------------^--------------------'
PATCH 2/2 Makefile: add check of binaries architecture
Hello,
Quoted 11 lines · Yann E. MORIN
That is not possible in all situations.
For example, I have a board here with a kind of co-processor of a different architecture; the firmware for that co-processor is loaded at runtime. It is an ELF file, and it is in target/.
So I don't think it is possible to check that all ELF files are for the Buildroot-known target.
We already discussed this a while ago and came to the same conclusiong back then.
I don't think I want to give up that easily on this, especially considering how many times we get submission for packages that are not actually cross-compiled.
Could you be more specific about these firmware files? Where are they located?
Perhaps with a test restricted to {usr,}/{bin,sbin,lib}, we can avoid testing those firmware files.
Best regards,
Thomas
Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com
PATCH 2/2 Makefile: add check of binaries architecture
Thomas, All,
On 2017-03-12 18:29 +0100, Thomas Petazzoni spake thusly:
Quoted 11 lines · Yann E. MORIN
Quoted 10 lines
That is not possible in all situations.
For example, I have a board here with a kind of co-processor of a different architecture; the firmware for that co-processor is loaded at runtime. It is an ELF file, and it is in target/.
So I don't think it is possible to check that all ELF files are for the Buildroot-known target.
Quoted 6 lines
Quoted 2 lines
We already discussed this a while ago and came to the same conclusiong back then.
I don't think I want to give up that easily on this, especially considering how many times we get submission for packages that are not actually cross-compiled.
I agree.
Quoted 2 lines
Could you be more specific about these firmware files? Where are they located?
In theory, those kind of files may be located anywhere, but in this specific case, it is in /lib/firmware.
The firmware files could be moved elsewhere, of course, but:
1) /lib/firmware is the "standard" location for firmware files;
2) a binary-only tool can be used to load the firmware and could expect it to be located there.
Quoted 2 lines
Perhaps with a test restricted to {usr,}/{bin,sbin,lib}, we can avoid testing those firmware files.
I think this would be sensible, as long as /lib/firmware is excluded, as well as /usr/lib/firmware (in case of merged /usr).
Regards,
Yann E. MORIN.
Signature · 6 lines
.-----------------.--------------------.------------------.--------------------. | Yann E. MORIN | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: | | +33 662 376 056 | Software Designer | \ / CAMPAIGN | ___ | | +33 223 225 172 `------------.-------: X AGAINST | \e/ There is no | | http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL | v conspiracy. | '------------------------------^-------^------------------^--------------------'
PATCH 2/2 Makefile: add check of binaries architecture
In reply to Yann E. MORINHi Yann,
Quoted 16 lines · Yann E. MORIN
On 2017-03-12 16:06 +0100, Thomas Petazzoni spake thusly:
Quoted 8 lines
As shown recently by the firejail example, it is easy to miss that a package builds and installs binaries without actually cross-compiling
them: they are built for the host architecture instead of the target architecture.This commit adds a small helper script, check-bin-arch, called from the main
Makefileas aTARGET_FINALIZE_HOOKS, to verify that all ELF binaries have been built for the correct CPU architecture.That is not possible in all situations.
For example, I have a board here with a kind of co-processor of a different architecture; the firmware for that co-processor is loaded at runtime. It is an ELF file, and it is in target/.
Quoted 5 lines
So I don't think it is possible to check that all ELF files are for the Buildroot-known target.
We already discussed this a while ago and came to the same conclusiong back then.
Maybe limiting the check to well knows target binary directories like target/{bin,sbin,usr/bin,usr/sbin,...} would help. This check won't catch all possible locations of target ELF binaries, but it's still a significant improvement over the current situation.
baruch
Signature · 3 lines
http://baruch.siach.name/blog/ ~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -PATCH 2/2 Makefile: add check of binaries architecture
Hello *,
Quoted 22 lines · Baruch Siach
Hi Yann,
Quoted 19 lines · Yann E. MORIN
On 2017-03-12 16:06 +0100, Thomas Petazzoni spake thusly:
Quoted 8 lines
As shown recently by the firejail example, it is easy to miss that a package builds and installs binaries without actually cross-compiling
them: they are built for the host architecture instead of the target architecture.This commit adds a small helper script, check-bin-arch, called from the main
Makefileas aTARGET_FINALIZE_HOOKS, to verify that all ELF binaries have been built for the correct CPU architecture.That is not possible in all situations.
For example, I have a board here with a kind of co-processor of a different architecture; the firmware for that co-processor is loaded at runtime. It is an ELF file, and it is in target/.
So I don't think it is possible to check that all ELF files are for the Buildroot-known target.
Quoted 7 lines
Quoted 2 lines
We already discussed this a while ago and came to the same conclusiong back then.
Maybe limiting the check to well knows target binary directories like target/{bin,sbin,usr/bin,usr/sbin,...} would help. This check won't catch all possible locations of target ELF binaries, but it's still a significant improvement over the current situation.
...or limit to executable binary files (for firmware files read rights should be enough)?
Regards,
Peter
Quoted 3 lines
baruch
PATCH 2/2 Makefile: add check of binaries architecture
Quoted 29 lines · Peter Seiderer
Hello *,
Quoted 25 lines · Baruch Siach
Hi Yann,
Quoted 21 lines · Yann E. MORIN
On 2017-03-12 16:06 +0100, Thomas Petazzoni spake thusly:
Quoted 8 lines
As shown recently by the firejail example, it is easy to miss that a package builds and installs binaries without actually cross-compiling
them: they are built for the host architecture instead of the target architecture.This commit adds a small helper script, check-bin-arch, called from the main
Makefileas aTARGET_FINALIZE_HOOKS, to verify that all ELF binaries have been built for the correct CPU architecture.That is not possible in all situations.
For example, I have a board here with a kind of co-processor of a different architecture; the firmware for that co-processor is loaded at runtime. It is an ELF file, and it is in target/.
So I don't think it is possible to check that all ELF files are for the Buildroot-known target.
We already discussed this a while ago and came to the same conclusiong back then.
Quoted 6 lines
Quoted 4 lines
Maybe limiting the check to well knows target binary directories like target/{bin,sbin,usr/bin,usr/sbin,...} would help. This check won't catch all possible locations of target ELF binaries, but it's still a significant improvement over the current situation.
...or limit to executable binary files (for firmware files read rights should be enough)?
The problem is that not all binaries are executable. .so files don't need to be
executable, some of them are not, and we probably still want to check them.
Regards,
Arnout
Signature · 6 lines
Arnout Vandecappelle arnout at mind be Senior Embedded Software Architect +32-16-286500 Essensium/Mind http://www.mind.be G.Geenslaan 9, 3001 Leuven, Belgium BE 872 984 063 RPR Leuven LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle GPG fingerprint: 7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF
PATCH 2/2 Makefile: add check of binaries architecture
In reply to Baruch SiachQuoted 22 lines · Baruch Siach
Hi Yann,
Quoted 19 lines · Yann E. MORIN
On 2017-03-12 16:06 +0100, Thomas Petazzoni spake thusly:
Quoted 8 lines
As shown recently by the firejail example, it is easy to miss that a package builds and installs binaries without actually cross-compiling
them: they are built for the host architecture instead of the target architecture.This commit adds a small helper script, check-bin-arch, called from the main
Makefileas aTARGET_FINALIZE_HOOKS, to verify that all ELF binaries have been built for the correct CPU architecture.That is not possible in all situations.
For example, I have a board here with a kind of co-processor of a different architecture; the firmware for that co-processor is loaded at runtime. It is an ELF file, and it is in target/.
So I don't think it is possible to check that all ELF files are for the Buildroot-known target.
Quoted 7 lines
Quoted 2 lines
We already discussed this a while ago and came to the same conclusiong back then.
Maybe limiting the check to well knows target binary directories like target/{bin,sbin,usr/bin,usr/sbin,...} would help. This check won't catch all possible locations of target ELF binaries, but it's still a significant improvement over the current situation.
Since the problematic files are in /lib/firmware, we'd have to do it
non-recursively then, and thereby miss quite a lot of libraries (which are often installed in subdirectories of /usr/lib). My first thought was that it's not a big problem to not check all files, but there are important categories of packages that install only in a subdirectory of /usr/lib, e.g. perl/python/... modules with a .so file. And there are even a few .so files in /usr/share (e.g. bash-completion helpers).
So I think Yann's idea of just excluding /lib/firmware is the best option.
Regards,
Arnout
Signature · 6 lines
Arnout Vandecappelle arnout at mind be Senior Embedded Software Architect +32-16-286500 Essensium/Mind http://www.mind.be G.Geenslaan 9, 3001 Leuven, Belgium BE 872 984 063 RPR Leuven LinkedIn profile: http://www.linkedin.com/in/arnoutvandecappelle GPG fingerprint: 7493 020B C7E3 8618 8DEC 222C 82EB F404 F9AC 0DDF