Blame SOURCES/microcode_ctl-intel-microcode2ucode-buf-handling.patch

1abd92
Fix most obvious intel-microcode2ucode buffer overruns.
1abd92
Index: microcode_ctl-2.1-19/intel-microcode2ucode.c
1abd92
===================================================================
1abd92
--- microcode_ctl-2.1-19.orig/intel-microcode2ucode.c	2018-08-20 04:32:26.803450076 +0200
1abd92
+++ microcode_ctl-2.1-19/intel-microcode2ucode.c	2018-08-20 04:33:49.324661025 +0200
1abd92
@@ -47,16 +47,25 @@
1abd92
 	char c[0];
1abd92
 };
1abd92
 
1abd92
+#define MAX_MICROCODE 4000000
1abd92
+
1abd92
 int main(int argc, char *argv[])
1abd92
 {
1abd92
 	char *filename = "/lib/firmware/microcode.dat";
1abd92
 	FILE *input, *f;
1abd92
 	char line[LINE_MAX];
1abd92
-	char buf[4000000];
1abd92
+	char *buf = NULL;
1abd92
 	union mcbuf *mc;
1abd92
 	size_t bufsize, count, start;
1abd92
 	int rc = EXIT_SUCCESS;
1abd92
 
1abd92
+	buf = malloc(MAX_MICROCODE);
1abd92
+	if (!buf) {
1abd92
+		printf("can't allocate buffer\n");
1abd92
+		rc = EXIT_FAILURE;
1abd92
+		goto out;
1abd92
+	}
1abd92
+
1abd92
 	if (argv[1] != NULL)
1abd92
 		filename = argv[1];
1abd92
 
1abd92
@@ -74,6 +83,12 @@
1abd92
 	count = 0;
1abd92
 	mc = (union mcbuf *) buf;
1abd92
 	while (fgets(line, sizeof(line), input) != NULL) {
1abd92
+		if ((count + 3) >= (MAX_MICROCODE / sizeof(mc->i[0]))) {
1abd92
+			printf("input file is too big");
1abd92
+			rc = EXIT_FAILURE;
1abd92
+			goto out;
1abd92
+		}
1abd92
+
1abd92
 		if (sscanf(line, "%x, %x, %x, %x",
1abd92
 		    &mc->i[count],
1abd92
 		    &mc->i[count + 1],
1abd92
@@ -102,6 +117,10 @@
1abd92
 		unsigned int family, model, stepping;
1abd92
 		unsigned int year, month, day;
1abd92
 
1abd92
+		if ((start > bufsize) ||
1abd92
+		    ((bufsize - start) < sizeof(struct microcode_header_intel)))
1abd92
+			goto out;
1abd92
+
1abd92
 		mc = (union mcbuf *) &buf[start];
1abd92
 
1abd92
 		if (mc->hdr.totalsize)
1abd92
@@ -109,8 +128,12 @@
1abd92
 		else
1abd92
 			size = 2000 + sizeof(struct microcode_header_intel);
1abd92
 
1abd92
+		if (size > (bufsize - start))
1abd92
+			goto out;
1abd92
+
1abd92
 		if (mc->hdr.ldrver != 1 || mc->hdr.hdrver != 1) {
1abd92
-			printf("unknown version/format:\n");
1abd92
+			printf("unknown version/format: %d/%d\n",
1abd92
+			       mc->hdr.ldrver, mc->hdr.hdrver);
1abd92
 			rc = EXIT_FAILURE;
1abd92
 			break;
1abd92
 		}
1abd92
@@ -135,7 +158,11 @@
1abd92
 		month = mc->hdr.date >> 24;
1abd92
 		day = (mc->hdr.date >> 16) & 0xff;
1abd92
 
1abd92
-		asprintf(&filename, "intel-ucode/%02x-%02x-%02x", family, model, stepping);
1abd92
+		if (asprintf(&filename, "intel-ucode/%02x-%02x-%02x", family,
1abd92
+		    model, stepping) == -1) {
1abd92
+			printf("Failed to generate ucode filename\n");
1abd92
+			goto out;
1abd92
+		}
1abd92
 		printf("\n");
1abd92
 		printf("%s\n", filename);
1abd92
 		printf("signature: 0x%02x\n", mc->hdr.sig);
1abd92
@@ -164,6 +191,11 @@
1abd92
 	}
1abd92
 	printf("\n");
1abd92
 
1abd92
+	if (start != bufsize)
1abd92
+		printf("Finished parsing at byte %zu of %zu\n", start, bufsize);
1abd92
+
1abd92
  out:
1abd92
+	free(buf);
1abd92
+
1abd92
 	return rc;
1abd92
 }