Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: bcm63xxpart: check the image tag's crc32

Only use the values from the image tag if it is valid. Always create
the CFE, NVRAM and linux partitions, to allow flashing a new image even
if the old is invalid without overwriting CFE or NVRAM.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>

authored by

Jonas Gorski and committed by
David Woodhouse
f98872fc 80516678

+27 -14
+27 -14
drivers/mtd/bcm63xxpart.c
··· 24 24 25 25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 26 26 27 + #include <linux/crc32.h> 27 28 #include <linux/module.h> 28 29 #include <linux/kernel.h> 29 30 #include <linux/slab.h> ··· 81 80 unsigned int cfelen, nvramlen; 82 81 int namelen = 0; 83 82 int i; 84 - char *boardid; 85 - char *tagversion; 83 + u32 computed_crc; 86 84 87 85 if (bcm63xx_detect_cfe(master)) 88 86 return -EINVAL; ··· 103 103 return -EIO; 104 104 } 105 105 106 - sscanf(buf->kernel_address, "%u", &kerneladdr); 107 - sscanf(buf->kernel_length, "%u", &kernellen); 108 - sscanf(buf->total_length, "%u", &totallen); 109 - tagversion = &(buf->tag_version[0]); 110 - boardid = &(buf->board_id[0]); 106 + computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf, 107 + offsetof(struct bcm_tag, header_crc)); 108 + if (computed_crc == buf->header_crc) { 109 + char *boardid = &(buf->board_id[0]); 110 + char *tagversion = &(buf->tag_version[0]); 111 111 112 - pr_info("CFE boot tag found with version %s and board type %s\n", 113 - tagversion, boardid); 112 + sscanf(buf->kernel_address, "%u", &kerneladdr); 113 + sscanf(buf->kernel_length, "%u", &kernellen); 114 + sscanf(buf->total_length, "%u", &totallen); 114 115 115 - kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; 116 - rootfsaddr = kerneladdr + kernellen; 117 - spareaddr = roundup(totallen, master->erasesize) + cfelen; 118 - sparelen = master->size - spareaddr - nvramlen; 119 - rootfslen = spareaddr - rootfsaddr; 116 + pr_info("CFE boot tag found with version %s and board type %s\n", 117 + tagversion, boardid); 118 + 119 + kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; 120 + rootfsaddr = kerneladdr + kernellen; 121 + spareaddr = roundup(totallen, master->erasesize) + cfelen; 122 + sparelen = master->size - spareaddr - nvramlen; 123 + rootfslen = spareaddr - rootfsaddr; 124 + } else { 125 + pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n", 126 + buf->header_crc, computed_crc); 127 + kernellen = 0; 128 + rootfslen = 0; 129 + rootfsaddr = 0; 130 + spareaddr = cfelen; 131 + sparelen = master->size - cfelen - nvramlen; 132 + } 120 133 121 134 /* Determine number of partitions */ 122 135 namelen = 8;