fel: Check the U-Boot's CRC instead of its size
The current code checks that the transferred size is matching the size reported in the image header. Unfortunately, the transferred image might be padded, which doesn't change anything at the functional level, but will make that check trigger since the actual image will be smaller than the transferred data. Change that logic to first check that the transferred size isn't less that the header image size, which will still be an error, and then check for the CRC of the image itself. This will prove to be an more robust integrity check than what we have right now anyway. The CRC used in the image header is the CRC32 algorithm, that is implemented in the zlib, which is installed on most devices on the planet, so we can just use that implementation instead of rolling our own. Tested-by: Frank Kunz <mailinglists@kunz-im-inter.net> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
This commit is contained in:
parent
b1bbc431c3
commit
e753821ea0
8
Makefile
8
Makefile
@ -118,6 +118,11 @@ sunxi-fexc: fexc.h script.h script.c \
|
||||
LIBUSB = libusb-1.0
|
||||
LIBUSB_CFLAGS ?= `pkg-config --cflags $(LIBUSB)`
|
||||
LIBUSB_LIBS ?= `pkg-config --libs $(LIBUSB)`
|
||||
|
||||
ZLIB = zlib
|
||||
ZLIB_CFLAGS ?= `pkg-config --cflags $(ZLIB)`
|
||||
ZLIB_LIBS ?= `pkg-config --libs $(ZLIB)`
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
# Windows lacks mman.h / mmap()
|
||||
DEFAULT_CFLAGS += -DNO_MMAP
|
||||
@ -132,7 +137,8 @@ SOC_INFO := soc_info.c soc_info.h
|
||||
FEL_LIB := fel_lib.c fel_lib.h
|
||||
|
||||
sunxi-fel: fel.c thunks/fel-to-spl-thunk.h $(PROGRESS) $(SOC_INFO) $(FEL_LIB)
|
||||
$(CC) $(HOST_CFLAGS) $(LIBUSB_CFLAGS) $(LDFLAGS) -o $@ $(filter %.c,$^) $(LIBS) $(LIBUSB_LIBS)
|
||||
$(CC) $(HOST_CFLAGS) $(LIBUSB_CFLAGS) $(ZLIB_CFLAGS) $(LDFLAGS) -o $@ \
|
||||
$(filter %.c,$^) $(LIBS) $(LIBUSB_LIBS) $(ZLIB_LIBS)
|
||||
|
||||
sunxi-nand-part: nand-part-main.c nand-part.c nand-part-a10.h nand-part-a20.h
|
||||
$(CC) $(HOST_CFLAGS) -c -o nand-part-main.o nand-part-main.c
|
||||
|
||||
24
fel.c
24
fel.c
@ -27,6 +27,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <zlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
static bool verbose = false; /* If set, makes the 'fel' tool more talkative */
|
||||
@ -785,21 +786,16 @@ void aw_fel_write_uboot_image(feldev_handle *dev, uint8_t *buf, size_t len)
|
||||
|
||||
uint32_t data_size = be32toh(hdr.ih_size); /* Image Data Size */
|
||||
uint32_t load_addr = be32toh(hdr.ih_load); /* Data Load Address */
|
||||
if (data_size != len - HEADER_SIZE)
|
||||
pr_fatal("U-Boot image data size mismatch: "
|
||||
"expected %zu, got %u\n", len - HEADER_SIZE, data_size);
|
||||
if (data_size > len - HEADER_SIZE)
|
||||
pr_fatal("U-Boot image data trucated: "
|
||||
"expected %zu bytes, got %u\n",
|
||||
len - HEADER_SIZE, data_size);
|
||||
|
||||
/* TODO: Verify image data integrity using the checksum field ih_dcrc,
|
||||
* available from be32toh(buf32[6])
|
||||
*
|
||||
* However, this requires CRC routines that mimic their U-Boot
|
||||
* counterparts, namely image_check_dcrc() in ${U-BOOT}/common/image.c
|
||||
* and crc_wd() in ${U-BOOT}/lib/crc32.c
|
||||
*
|
||||
* It should be investigated if existing CRC routines in sunxi-tools
|
||||
* could be factored out and reused for this purpose - e.g. calc_crc32()
|
||||
* from nand-part-main.c
|
||||
*/
|
||||
uint32_t dcrc = be32toh(hdr.ih_dcrc);
|
||||
uint32_t computed_dcrc = crc32(0, buf + HEADER_SIZE, data_size);
|
||||
if (dcrc != computed_dcrc)
|
||||
pr_fatal("U-Boot data CRC mismatch: expected %x, got %x\n",
|
||||
dcrc, computed_dcrc);
|
||||
|
||||
/* If we get here, we're "good to go" (i.e. actually write the data) */
|
||||
pr_info("Writing image \"%.*s\", %u bytes @ 0x%08X.\n",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user