programmer_init: Work on a mutable copy of programmer params

The signature of extract_param() was wrong all the time. It actually
modifies the passed, global `programmer_param` string. This only com-
piled w/o warnings because of a deficiency of the strstr() API. It
takes a const string as argument but returns a mutable pointer to
a substring of it.

As we take a const parameter string in the libflashrom API and should
not change that, we create a copy in programmer_init() instead.

Now that we free our copy of the programmer parameters at the end of
programmer_init() it's more obvious that the string can only be used
during initialization. So also clear `programmer_param` inside
programmer_init() instead of programmer_shutdown().

Change-Id: If6bb2e5e4312b07f756615984bd3757e92b86b0a
Signed-off-by: Nico Huber <nico.h@gmx.de>
Original-Reviewed-on: https://review.coreboot.org/c/flashrom/+/67094
Original-Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Original-Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
Original-Reviewed-by: Thomas Heijligen <src@posteo.de>
Reviewed-on: https://review.coreboot.org/c/flashrom-stable/+/71491
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/flashrom.c b/flashrom.c
index f656872..406c20f 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -44,7 +44,7 @@
 const char *chip_to_probe = NULL;
 
 static const struct programmer_entry *programmer = NULL;
-static const char *programmer_param = NULL;
+static char *programmer_param = NULL;
 
 /*
  * Programmers supporting multiple buses can have differing size limits on
@@ -160,7 +160,16 @@
 	/* Default to allowing writes. Broken programmers set this to 0. */
 	programmer_may_write = true;
 
-	programmer_param = param;
+	if (param) {
+		programmer_param = strdup(param);
+		if (!programmer_param) {
+			msg_perr("Out of memory!\n");
+			return ERROR_FATAL;
+		}
+	} else {
+		programmer_param = NULL;
+	}
+
 	msg_pdbg("Initializing %s programmer\n", programmer->name);
 	ret = programmer->init();
 	if (programmer_param && strlen(programmer_param)) {
@@ -179,6 +188,8 @@
 			ret = ERROR_FATAL;
 		}
 	}
+	free(programmer_param);
+	programmer_param = NULL;
 	return ret;
 }
 
@@ -197,8 +208,6 @@
 		int i = --shutdown_fn_count;
 		ret |= shutdown_fn[i].func(shutdown_fn[i].data);
 	}
-
-	programmer_param = NULL;
 	registered_master_count = 0;
 
 	return ret;
@@ -278,7 +287,7 @@
  * needle and remove everything from the first occurrence of needle to the next
  * delimiter from haystack.
  */
-static char *extract_param(const char *const *haystack, const char *needle, const char *delim)
+static char *extract_param(char *const *haystack, const char *needle, const char *delim)
 {
 	char *param_pos, *opt_pos, *rest;
 	char *opt = NULL;