Date: Thu, 20 Sep 2007 13:41:06 +0200
From: Brandon Philips <bphilips@novell.com>
To: Hannes Reinecke <hare@suse.de>
Subject: [PATCH] open-iscsi: possible bug fix for #293845

Restrict searching to 0xc0000 and 0xf0000 (the expansion ROM area) and search
for a valid ROM header before proceeding to search for the iBFT data.

Has not been tested against a machine with a valid checksum.

Signed-off-by: Brandon Philips <bphilips@suse.de>
---
 utils/fwparam_ibft/fwparam_ibft.c |   62 +++++++++++++++++++++++---------------
 1 file changed, 38 insertions(+), 24 deletions(-)

Index: open-iscsi-svn/utils/fwparam_ibft/fwparam_ibft.c
===================================================================
--- open-iscsi-svn.orig/utils/fwparam_ibft/fwparam_ibft.c
+++ open-iscsi-svn/utils/fwparam_ibft/fwparam_ibft.c
@@ -39,6 +39,8 @@ char default_file_name[] = "/dev/mem";
 char *filename = default_file_name;
 int boot_selected_only;
 
+char ID_ROMEXT[]={0x55, 0xaa, 0}; /* extended rom magic */
+
 const char nulls[16]; /* defaults to zero */
 
 /*
@@ -409,30 +411,42 @@ dump_ibft(void *ibft_loc)
  * return the address of the location of string in filebuf, search up to
  * max bytes of *filebuf, if not found returns NULL.
  */
-char *
-search_file(char *filebuf, char *string, int len, int max)
+static char * search_rom(char * buf, int start_addr, int last)
 {
-	char *cur = filebuf;
-	char *end = filebuf + max;
-	int i = 0;
-
-	if (debug > 1) {
-		fprintf(stderr,
-			"%s: cur 0x%p, end 0x%p, string '%.4s', len %d\n",
-			__FUNCTION__, cur, end, string, len);
-	}
-	while ((cur < end) && memcmp(cur, string, len)) {
-		if (debug > 2) {
-			fprintf(stderr, "i %d, cur 0x%p: 0x%x ('%c')\n",
-				i, cur, cur[0], cur[0]);
-			i++;
+	char *rom_end, *cur = buf, *end = buf + last;
+	unsigned char csize;
+
+	while(cur < end) {
+		if (memcmp(cur, ID_ROMEXT, strlen(ID_ROMEXT)) == 0) {
+			memcpy(&csize, cur + 2, 1);
+			/* Don't search past end rom */
+			rom_end = (cur + (csize * 512)) - strlen(iBFTSTR);
+
+			if (debug > 1) {
+				fprintf(stderr, "Found rom at %x of size %d\n"
+					"%s: string '%.4s', len %lu\n",
+					((int)(cur - buf)) + start_addr,
+					csize*512, __FUNCTION__, iBFTSTR,
+					strlen(iBFTSTR));
+			}
+
+			while (cur < rom_end) {
+				if (debug > 2)
+					fprintf(stderr, "i %x: 0x%x\n",
+						(int)(cur - buf) + start_addr,
+						(unsigned char)cur[0]);
+
+				if (memcmp(cur, iBFTSTR, strlen(iBFTSTR)) == 0)
+					return cur;
+
+				cur++;
+			}
+			cur += strlen(iBFTSTR);
+		} else {
+			cur += 512;
 		}
-		cur += 4;
 	}
-	if (cur < end)
-		return cur;
-	else
-		return NULL;
+	return NULL;
 }
 
 int
@@ -440,8 +454,8 @@ main (int argc, char **argv)
 {
 	int fd, option, ret;
 	char *filebuf, *ibft_loc;
-	int start = 512 * 1024; /* 512k */
-	int end_search = (1024 * 1024) - start; /* 512k */
+	int start = 0xc0000;
+	int end_search = 0xf0000 - start;
 
 	progname = argv[0];
 
@@ -502,7 +516,7 @@ main (int argc, char **argv)
 		exit(1);
 	}
 
-	ibft_loc = search_file(filebuf, iBFTSTR, strlen(iBFTSTR), end_search);
+	ibft_loc = search_rom(filebuf, start, end_search);
 	if (ibft_loc) {
 		if (dump_ibft(ibft_loc))
 			ret = 0;

