linux_spi.c: align argument parsing with upstream and fix memory leaks
Reorder argument parsing and free() strings returned by
parse_programmer_param() to match upstream. To reduce the
complexity assiciated with freeing the device filename string,
check_fdt() and check_sysfs() now return heap allocated strings.
This commit is mostly a repeat of `ac7ed8b70847`, which was
reverted in `5556b94dedcb` because it was built on top of a commit
that needed to be reverted, but did not cause a regression itself.
An additional difference between this and the original patch
is that check_sysfs() has been changed to return a heap-allocated
string in this patch, whereas it had been deleted in the original
patch. Also, malloc/sprintf have been changed to calloc/snprintf
as suggested by quasisec@.
BUG=b:153598437
BRANCH=none
TEST=builds
Signed-off-by: Nikolai Artemiev <nartemiev@chromium.org>
Change-Id: I71f94ce0598d3b3ff24c789d6844e03d6df7ba8c
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/flashrom/+/2383220
Tested-by: Nikolai Artemiev <nartemiev@google.com>
Commit-Queue: Sam McNally <sammc@chromium.org>
Reviewed-by: Sam McNally <sammc@chromium.org>
Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
diff --git a/linux_spi.c b/linux_spi.c
index 4a0aba5..15921ed 100644
--- a/linux_spi.c
+++ b/linux_spi.c
@@ -48,6 +48,9 @@
#define MODALIAS_FILE "modalias"
#define LINUX_SPI_SYSFS_ROOT "/sys/bus/spi/devices"
+/* At least big enough to fit /dev/spidevX.Y */
+#define DEVFS_PATH_LEN 32
+
static int fd = -1;
#define BUF_SIZE_FROM_SYSFS "/sys/module/spidev/parameters/bufsiz"
static size_t max_kernel_buf_size;
@@ -72,11 +75,11 @@
.write_256 = linux_spi_write_256,
};
-static char devfs_path[32]; /* at least big enough to fit /dev/spidevX.Y */
static char *check_sysfs(void)
{
int i;
const char *sysfs_path = NULL;
+ char *devfs_path = NULL;
char *p;
char *modalias[] = {
"spi:spidev", /* raw access over SPI bus (newer kernels) */
@@ -100,7 +103,8 @@
if (sscanf(p, "spi%u.%u", &major, &minor) == 2) {
msg_pdbg("Found SPI device %s on spi%u.%u\n",
modalias[i], major, minor);
- sprintf(devfs_path, "/dev/spidev%u.%u", major, minor);
+ devfs_path = calloc(1, DEVFS_PATH_LEN);
+ snprintf(devfs_path, DEVFS_PATH_LEN, "/dev/spidev%u.%u", major, minor);
free((void *)sysfs_path);
break;
}
@@ -116,10 +120,11 @@
{
unsigned int bus, cs;
+ char *devfs_path = calloc(1, DEVFS_PATH_LEN);
if (fdt_find_spi_nor_flash(&bus, &cs) < 0)
return NULL;
- sprintf(devfs_path, "/dev/spidev%u.%u", bus, cs);
+ snprintf(devfs_path, DEVFS_PATH_LEN, "/dev/spidev%u.%u", bus, cs);
return devfs_path;
}
@@ -155,20 +160,12 @@
if (alias && alias->type != ALIAS_HOST)
return 1;
- dev = extract_programmer_param("dev");
- if (!dev)
- dev = linux_spi_probe();
- if (!dev || !strlen(dev)) {
- msg_perr("No SPI device found. Use flashrom -p "
- "linux_spi:dev=/dev/spidevX.Y\n");
- return 1;
- }
-
p = extract_programmer_param("spispeed");
if (p && strlen(p)) {
speed_hz = (uint32_t)strtoul(p, &endp, 10) * 1000;
if (p == endp || speed_hz == 0) {
msg_perr("%s: invalid clock: %s kHz\n", __func__, p);
+ free(p);
return 1;
}
} else {
@@ -176,14 +173,26 @@
"kHz clock. Use 'spispeed' parameter to override.\n",
speed_hz / 1000);
}
+ free(p);
+
+ dev = extract_programmer_param("dev");
+ if (!dev)
+ dev = linux_spi_probe();
+ if (!dev || !strlen(dev)) {
+ msg_perr("No SPI device found. Use flashrom -p "
+ "linux_spi:dev=/dev/spidevX.Y\n");
+ free(dev);
+ return 1;
+ }
msg_pdbg("Using device %s\n", dev);
if ((fd = open(dev, O_RDWR)) == -1) {
msg_perr("%s: failed to open %s: %s\n", __func__,
dev, strerror(errno));
-
+ free(dev);
return 1;
}
+ free(dev);
if (register_shutdown(linux_spi_shutdown, NULL))
return 1;