diff --git a/firehose.c b/firehose.c index 08d7d0e..5d934d3 100644 --- a/firehose.c +++ b/firehose.c @@ -371,6 +371,11 @@ static int firehose_try_configure(struct qdl_device *qdl, bool skip_storage_init if (storage != QDL_STORAGE_NAND) { max_sector_size = sector_sizes[ARRAY_SIZE(sector_sizes) - 1]; buf = malloc(max_sector_size); + if (!buf) { + ux_err("failed to allocate sector buffer\n"); + return -1; + } + memset(&op, 0, sizeof(op)); op.partition = 0; op.start_sector = "1"; @@ -390,6 +395,8 @@ static int firehose_try_configure(struct qdl_device *qdl, bool skip_storage_init break; } } + + free(buf); } if (qdl->sector_size) diff --git a/gpt.c b/gpt.c index 52a2f97..3d795f3 100644 --- a/gpt.c +++ b/gpt.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -140,8 +141,8 @@ static int gpt_load_table_from_partition(struct qdl_device *qdl, unsigned int ph uint8_t buf[4096]; struct read_op op; unsigned int offset; - unsigned int lba; - char lba_buf[10]; + uint64_t lba; + char lba_buf[21]; uint16_t name_utf16le[36]; char name[36 * 4]; int ret; @@ -178,7 +179,7 @@ static int gpt_load_table_from_partition(struct qdl_device *qdl, unsigned int ph if (offset == 0) { lba = gpt.part_entry_lba + i * gpt.part_entry_size / qdl->sector_size; - sprintf(lba_buf, "%u", lba); + snprintf(lba_buf, sizeof(lba_buf), "%" PRIu64, lba); op.start_sector = lba_buf; memset(buf, 0, sizeof(buf)); diff --git a/qdl.c b/qdl.c index cd94600..e736096 100644 --- a/qdl.c +++ b/qdl.c @@ -171,20 +171,22 @@ static int decode_programmer_archive(struct sahara_image *images) void *ptr = blob->ptr; void *end = blob->ptr + blob->len; long id; + int ret; if (blob->len < sizeof(*hdr) || memcmp(ptr, CPIO_MAGIC, 6)) return 0; + ret = -1; for (;;) { if (ptr + sizeof(*hdr) > end) { ux_err("programmer archive is truncated\n"); - return -1; + break; } hdr = ptr; if (memcmp(hdr->c_magic, "070701", 6)) { ux_err("expected cpio header in programmer archive\n"); - return -1; + break; } filesize = parse_ascii_hex32(hdr->c_filesize); @@ -193,44 +195,70 @@ static int decode_programmer_archive(struct sahara_image *images) ptr += sizeof(*hdr); if (ptr + namesize > end || ptr + filesize + namesize > end) { ux_err("programmer archive is truncated\n"); - return -1; + break; } if (namesize > sizeof(name)) { ux_err("unexpected filename length in progammer archive\n"); - return -1; + break; } memcpy(name, ptr, namesize); - if (!memcmp(name, "TRAILER!!!", 11)) + if (!memcmp(name, "TRAILER!!!", 11)) { + ret = 1; break; + } tok = strtok_r(name, ":", &save); id = strtoul(tok, NULL, 0); if (id == 0 || id >= MAPPING_SZ) { ux_err("invalid image id \"%s\" in programmer archive\n", tok); - return -1; + break; } ptr += namesize; ptr = ALIGN_UP(ptr, 4); tok = strtok_r(NULL, ":", &save); - if (tok) + if (tok) { images[id].name = strdup(tok); + if (!images[id].name) { + ux_err("failed to allocated buffer for an image name\n"); + break; + } + } images[id].len = filesize; images[id].ptr = malloc(filesize); + if (!images[id].ptr) { + ux_err("failed to allocated buffer for an image, len = %z\n", images[id].len); + break; + } memcpy(images[id].ptr, ptr, filesize); ptr += filesize; ptr = ALIGN_UP(ptr, 4); } - free(blob->ptr); - blob->ptr = NULL; - blob->len = 0; + /* + * even if some images aren't initialized, it's safe to enumerate over each + * image and try to free, as otherwise image[i] will be filled with zeros. + * + * first image isn't freed if error occurred + */ + for (size_t i = 0; i < MAPPING_SZ; i++) { + if (ret != 1 && i == 0) + continue; - return 1; + if (images[i].ptr) + free(images[i].ptr); + if (images[i].name) + free((void *)images[i].name); + images[i].ptr = NULL; + images[i].name = NULL; + images[i].len = 0; + } + + return ret; } /** diff --git a/util.c b/util.c index 70cbd43..6872ceb 100644 --- a/util.c +++ b/util.c @@ -242,6 +242,10 @@ int load_sahara_image(const char *filename, struct sahara_image *image) lseek(fd, 0, SEEK_SET); ptr = malloc(len); + if (!ptr) { + ux_err("failed to init buffer for content of \"%s\"\n", filename); + goto err_close; + } n = read(fd, ptr, len); if (n != len) {