summaryrefslogtreecommitdiffstats
path: root/flashrom.c
diff options
context:
space:
mode:
authorAlexander Goncharov <chat@joursoir.net>2023-02-14 19:31:44 +0400
committerAnastasia Klimchuk <aklm@chromium.org>2023-04-24 13:30:12 +0000
commit5affc221f3074be4e7239ba2a0683cae06b525fd (patch)
tree49b9d01b929279a5803507d0a83e157c667c9be0 /flashrom.c
parent590a621e164a09b9a435e12ef14800f55cf4805e (diff)
downloadflashrom-5affc221f3074be4e7239ba2a0683cae06b525fd.tar.gz
flashrom-5affc221f3074be4e7239ba2a0683cae06b525fd.tar.bz2
flashrom-5affc221f3074be4e7239ba2a0683cae06b525fd.zip
flashrom: rewrite flashbuses_to_text()
The previous implementation had no error handling, as a result the flashrom could crash if the computer ran out of memory. The new version returns NULL in such cases. Also, rewrite lots of `if` conditions to one cycle, store a name of buses and `enum chipbustype` in an array by using a custom struct. The caller always expected a non-null value, so change its behavior to handle a possible null value or use the `?` symbol. As far as `free()` can handle null pointers, do nothing with such callers. TEST=ninja test Change-Id: I59b9044c99b4ba6c00d8c97f1e91af09d70dce2c Signed-off-by: Alexander Goncharov <chat@joursoir.net> Ticket: https://ticket.coreboot.org/issues/408 Reviewed-on: https://review.coreboot.org/c/flashrom/+/73039 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Anastasia Klimchuk <aklm@chromium.org>
Diffstat (limited to 'flashrom.c')
-rw-r--r--flashrom.c60
1 files changed, 40 insertions, 20 deletions
diff --git a/flashrom.c b/flashrom.c
index 3e6e0fb5a..e14516f6a 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -65,6 +65,17 @@ static struct shutdown_func_data {
*/
static bool may_register_shutdown = false;
+static struct bus_type_info {
+ enum chipbustype type;
+ const char *name;
+} bustypes[] = {
+ { BUS_PARALLEL, "Parallel, " },
+ { BUS_LPC, "LPC, " },
+ { BUS_FWH, "FWH, " },
+ { BUS_SPI, "SPI, " },
+ { BUS_PROG, "Programmer-specific, " },
+};
+
/* Register a function to be executed on programmer shutdown.
* The advantage over atexit() is that you can supply a void pointer which will
* be used as parameter to the registered function upon programmer shutdown.
@@ -912,35 +923,44 @@ int map_flash(struct flashctx *flash)
/*
* Return a string corresponding to the bustype parameter.
- * Memory is obtained with malloc() and must be freed with free() by the caller.
+ * Memory to store the string is allocated. The caller is responsible to free memory.
+ * If there is not enough memory remaining, then NULL is returned.
*/
char *flashbuses_to_text(enum chipbustype bustype)
{
- char *ret = calloc(1, 1);
+ char *ret, *ptr;
+
/*
* FIXME: Once all chipsets and flash chips have been updated, NONSPI
* will cease to exist and should be eliminated here as well.
*/
- if (bustype == BUS_NONSPI) {
- ret = strcat_realloc(ret, "Non-SPI, ");
- } else {
- if (bustype & BUS_PARALLEL)
- ret = strcat_realloc(ret, "Parallel, ");
- if (bustype & BUS_LPC)
- ret = strcat_realloc(ret, "LPC, ");
- if (bustype & BUS_FWH)
- ret = strcat_realloc(ret, "FWH, ");
- if (bustype & BUS_SPI)
- ret = strcat_realloc(ret, "SPI, ");
- if (bustype & BUS_PROG)
- ret = strcat_realloc(ret, "Programmer-specific, ");
- if (bustype == BUS_NONE)
- ret = strcat_realloc(ret, "None, ");
+ if (bustype == BUS_NONSPI)
+ return strdup("Non-SPI");
+ if (bustype == BUS_NONE)
+ return strdup("None");
+
+ ret = calloc(1, 1);
+ if (!ret)
+ return NULL;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(bustypes); i++)
+ {
+ if (bustype & bustypes[i].type) {
+ ptr = strcat_realloc(ret, bustypes[i].name);
+ if (!ptr) {
+ free(ret);
+ return NULL;
+ }
+ ret = ptr;
+ }
}
+
/* Kill last comma. */
ret[strlen(ret) - 2] = '\0';
- ret = realloc(ret, strlen(ret) + 1);
- return ret;
+ ptr = realloc(ret, strlen(ret) + 1);
+ if (!ptr)
+ free(ret);
+ return ptr;
}
static int init_default_layout(struct flashctx *flash)
@@ -1165,7 +1185,7 @@ notfound:
tmp = flashbuses_to_text(flash->chip->bustype);
msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found",
- flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
+ flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp ? tmp : "?");
free(tmp);
if (master_uses_physmap(mst))
msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",