The test subject: Public on GitHub, commit 1fd48f2 (MIT)
Which files does an IAR build produce?
According to IAR, the ILINK linker produces “an absolute object file containing the executable image in the ELF (including DWARF for debug information) format”. It produces no other formats; HEX, S-record or BIN for the flash are made from it with ielftool.
| File | What it contains |
|---|---|
.out | The image as ELF with symbols and DWARF debug information. The file for the analysis. |
.map | Linker version, command line, the contribution of each module and library to the image, all public symbols with their origin. |
.hex .srec .bin | Made from the .out with ielftool. Only the bytes for the flash, without symbols. |
Step 1: With which toolchain and for which target was it built?
The .comment section carries the linker version and the full linker command line with all object files and libraries. This puts the compiler in the SBOM as a build tool.
file ITAT_RNDIS.outOutput
ITAT_RNDIS.out: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not strippedstrings -a ITAT_RNDIS.out | grep -m1 "IAR ELF Linker"Output
IAR ELF Linker V9.10.1.308/ W64 for ARMstrings -a ITAT_RNDIS.out \
| grep -c "IAR ANSI C/C++ Compiler V9.10.1.308/W64 for ARM$"713Step 2: What is linked?
The symbol table shows which functions are in the image: here the FreeRTOS kernel, the CMSIS-RTOS2 layer and the FreeRTOS+TCP TCP/IP stack.
A function name alone is no proof. tcpip_init sounds like lwIP, but in this project it is a function of the demo itself: not a single symbol with lwip_ is in the image. A component belongs in the SBOM only when several pieces of evidence agree.
nm ITAT_RNDIS.out \
| grep -E " T (FreeRTOS_IPInit|FreeRTOS_socket|vTaskStartScheduler|xTaskCreate|osKernelStart|tcpip_init)$"Output
08004797T FreeRTOS_IPInit0800272bT FreeRTOS_socket08007f31T osKernelStart0800656dT tcpip_init08005305T vTaskStartScheduler08004fffT xTaskCreatenm ITAT_RNDIS.out | grep -c -E "lwip_|mbedtls_"0Step 3: Which versions are in the .out?
Here the FreeRTOS version is in the image itself, in the flash area between the HTTP server's text. With IAR the source paths in the DWARF name the project folders, for example Middlewares\Third_Party\FreeRTOS-Plus-TCP, but no version in the path.
Because the version sits in flash, it is in the BIN too. There it sits 0x34 bytes earlier, at 0x890c: the BIN starts with the first flash section, while the .out has the 52-byte ELF header in front of it. In the Keil example the version was only in the debug information and missing from the BIN.
For FreeRTOS+TCP and the HAL there is no version in the image. It comes from the project headers: FreeRTOS+TCP V2.3.2 LTS Patch 1 in FreeRTOS_IP.c and HAL 1.7.13 in stm32f4xx_hal.c. In the SBOM these versions belong to the component, with a note on where they come from.
strings -a -t x ITAT_RNDIS.out | grep -m1 "V10.3.1"Output
8940 V10.3.1strings -a -t x ITAT_RNDIS.bin | grep "V10.3.1"Output
890c V10.3.1strings -a ITAT_RNDIS.out | grep -m1 -i "FreeRTOS-Plus-TCP"Output
D:\GitHub\STM32F4XX_RNDIS_DEMO\Middlewares\Third_Party\FreeRTOS-Plus-TCP\portable\BufferManagement\BufferAllocation_2.cStep 4: What does the map file show?
According to IAR, ILINK loads only the library modules the application needs and eliminates sections that are not required. The map file shows the result. It is written with --map, in the IDE under Project > Options > Linker > List. Its header names linker version, date and command line, the MODULE SUMMARY the contribution of each module to the image, sorted by directory and library.
In the test subject, 18 object files are on the linker command line but missing from the MODULE SUMMARY. Among them are FreeRTOS_DNS.o and FreeRTOS_DHCP.o. The DNS and DHCP parts of FreeRTOS+TCP have no code in this image. A vulnerability that affects only these parts does not affect this device.
The four libraries at the end of the list are IAR's runtime. Their name encodes the variant: dl7M_tlf.a is the C library for Armv7-M in Thumb mode, little-endian, Full configuration. m7M_tls.a is the math library, s meaning VFP for single precision only. Their version is the toolchain's version.
grep -m1 "IAR ELF Linker" ITAT_RNDIS.mapOutput
# IAR ELF Linker V9.10.1.308/W64 for ARM 27/Nov/2021 23:47:44sed -n '/MODULE SUMMARY/,/Grand Total/p' ITAT_RNDIS.map \
| grep -A10 "FreeRTOS_TCP: \[8\]"Output
D:\GitHub\STM32F4XX_RNDIS_DEMO\EWARM\ITAT_RNDIS\Obj\Middlewares\FreeRTOS_TCP: [8]
BufferAllocation_2.o 348 4 508
FreeRTOS_ARP.o 1'068 40 76
FreeRTOS_IP.o 3'412 110
FreeRTOS_Sockets.o 4'212 44
FreeRTOS_Stream_Buffer.o 308
FreeRTOS_TCP_IP.o 9'228
FreeRTOS_TCP_WIN.o 1'986 24
FreeRTOS_UDP_IP.o 344 7 24
NetworkInterface.o 36
-------------------------------------------------------sed -n '/MODULE SUMMARY/,/Grand Total/p' ITAT_RNDIS.map \
| grep -E "^[A-Za-z0-9_]+\.a: "Output
dl7M_tlf.a: [12]
m7M_tls.a: [13]
rt7M_tl.a: [14]
shb_l.a: [15]What does this mean for the SBOM?
FreeRTOS V10.3.1 is in the version range of CVE-2021-31571, CVE-2021-31572 and CVE-2021-32020, which NVD lists for FreeRTOS before 10.4.3. Whether one of them can be exploited in the device depends on the use of the affected functions.
| Component | Version and evidence |
|---|---|
| FreeRTOS kernel | V10.3.1, in the image at offset 0x8940, confirmed by task.h |
| FreeRTOS+TCP | V2.3.2 LTS Patch 1, from FreeRTOS_IP.c; in the image only the name |
| STM32F4 HAL | 1.7.13, from stm32f4xx_hal.c; in the image only functions |
| IAR runtime libraries | dl7M_tlf.a, m7M_tls.a, rt7M_tl.a, shb_l.a per the map file, version of the toolchain |
| IAR compiler and linker | V9.10.1.308, from .comment, as build tool |
Can this run automatically?
LegacyMind reads the linked libraries and the toolchain with its version from .out, .elf and .axf files, and from Keil and GNU Arm builds also the library versions. It adds the hardening (stack protection, MPU, privilege separation). If the file evidences no version, the field stays blank. You export the SBOM as CycloneDX or SPDX.
Questions
Which IAR file should I use?
The .out from your project's Exe folder, plus the .map from the List folder. A HEX or BIN from ielftool holds only the bytes for the flash, without symbols and debug information.
Is every library's version in the .out?
No. Some libraries write their version into the image, others do not. Then the project headers or release notes supply the version, and the SBOM notes where it comes from.
Does the map file help?
Yes. It lists per module and library what ends up in the image, and where each symbol comes from. Next to the .out it is the best source for whether a library is really linked.
Why are files that were built missing from the MODULE SUMMARY?
Because ILINK takes in only what the program needs. In the example, 18 object files are on the command line and contribute nothing to the image, among them DNS and DHCP of FreeRTOS+TCP. --no_remove turns off the removal of unused sections.
How do I generate the map file in IAR Embedded Workbench?
With the linker option --map, in the IDE under Project > Options > Linker > List, Generate linker map file. In the example it sits in the project's List folder.
Is it different with Keil?
Keil writes an .axf, also an ELF file. In the public Keil example the FreeRTOS version is also in the source path, third_party/FreeRTOSv10.1.1; in the IAR example it is not.