⬢ DragonFlyBSD Kernel Audit
DF-4385 / fix.diff
← back to finding ↓ download raw
--- 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;