--- a/sys/dev/netif/oce/oce_sysctl.c +++ b/sys/dev/netif/oce/oce_sysctl.c @@ -54,7 +54,8 @@ static boolean_t oce_phy_flashing_required(POCE_SOFTC sc); static boolean_t oce_img_flashing_required(POCE_SOFTC sc, const char *p, int img_optype, uint32_t img_offset, - uint32_t img_size, uint32_t hdrs_size); + uint32_t img_size, uint32_t hdrs_size, + uint32_t fw_datasize); static void oce_add_stats_sysctls_be3(POCE_SOFTC sc, struct sysctl_ctx_list *ctx, struct sysctl_oid *stats_node); @@ -332,7 +333,8 @@ size = 1048576; start = 262144; if (!oce_img_flashing_required(sc, fw->data, - optype, start, size, bin_offset)) + optype, start, size, bin_offset, + fw->datasize)) skip_image = TRUE; break; case IMG_BIOS: @@ -449,12 +451,19 @@ static boolean_t oce_img_flashing_required(POCE_SOFTC sc, const char *p, int img_optype, uint32_t img_offset, - uint32_t img_size, uint32_t hdrs_size) + uint32_t img_size, uint32_t hdrs_size, + uint32_t fw_datasize) { uint32_t crc_offset; uint8_t flashed_crc[4]; int status; + /* The CRC lives at the very end of the image region: refuse to + * read past a truncated image; the size gate in the caller then + * aborts the upgrade. */ + if ((uint64_t)hdrs_size + img_offset + img_size > fw_datasize) + return TRUE; + crc_offset = hdrs_size + img_offset + img_size - 4; p += crc_offset;