Next try. Uwe, could you please check if I fixed all new bugs? Thanks.
The pattern of foo = realloc(foo, size); causes a memory leak if realloc fails because realloc does not free foo in case of failure, but foo will be NULL after a failure, so there is no way to access or free the original foo.
Fix unchecked [mc]alloc return values as well.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-memleak/flash.h =================================================================== --- flashrom-memleak/flash.h (Revision 727) +++ flashrom-memleak/flash.h (Arbeitskopie) @@ -323,7 +323,7 @@ void print_supported_chipsets(void); void print_supported_boards(void); void print_supported_pcidevs(struct pcidev_status *devs); -void print_wiki_tables(void); +int print_wiki_tables(void);
/* board_enable.c */ void w836xx_ext_enter(uint16_t port); Index: flashrom-memleak/ft2232_spi.c =================================================================== --- flashrom-memleak/ft2232_spi.c (Revision 727) +++ flashrom-memleak/ft2232_spi.c (Arbeitskopie) @@ -193,19 +193,21 @@ { struct ftdi_context *ftdic = &ftdic_context; static unsigned char *buf = NULL; - int i, ret = 0; + unsigned char *newbuf = NULL; + int i = 0, ret = 0;
if (writecnt > 65536 || readcnt > 65536) return SPI_INVALID_LENGTH;
- buf = realloc(buf, writecnt + readcnt + 100); - if (!buf) { + newbuf = realloc(buf, writecnt + readcnt + 100); + if (!newbuf) { fprintf(stderr, "Out of memory!\n"); + free(buf); + buf = NULL; exit(1); } + buf = newbuf;
- i = 0; - /* minimize USB transfers by packing as many commands * as possible together. if we're not expecting to * read, we can assert CS, write, and deassert CS all Index: flashrom-memleak/flashrom.c =================================================================== --- flashrom-memleak/flashrom.c (Revision 727) +++ flashrom-memleak/flashrom.c (Arbeitskopie) @@ -282,9 +282,13 @@
char *strcat_realloc(char *dest, const char *src) { - dest = realloc(dest, strlen(dest) + strlen(src) + 1); - if (!dest) + char *newdest = realloc(dest, strlen(dest) + strlen(src) + 1); + if (!newdest) { + free(dest); + fprintf(stderr, "Could not allocate memory!\n"); return NULL; + } + dest = newdest; strcat(dest, src); return dest; } @@ -459,6 +463,10 @@ printf("Error: No filename specified.\n"); return 1; } + if (!buf) { + fprintf(stderr, "Could not allocate memory!\n"); + exit(1); + } if ((image = fopen(filename, "w")) == NULL) { perror(filename); exit(1); @@ -829,7 +837,8 @@
#if PRINT_WIKI_SUPPORT == 1 if (list_supported_wiki) { - print_wiki_tables(); + if (print_wiki_tables()) + exit(1); exit(0); } #endif @@ -944,6 +953,10 @@
size = flash->total_size * 1024; buf = (uint8_t *) calloc(size, sizeof(char)); + if (!buf) { + fprintf(stderr, "Could not allocate memory!\n"); + exit(1); + }
if (erase_it) { if (flash->tested & TEST_BAD_ERASE) { Index: flashrom-memleak/print_wiki.c =================================================================== --- flashrom-memleak/print_wiki.c (Revision 727) +++ flashrom-memleak/print_wiki.c (Arbeitskopie) @@ -353,7 +353,7 @@ printf("\n|}\n\n|}\n"); }
-static void wiki_helper(const char *heading, const char *status, +static int wiki_helper(const char *heading, const char *status, int cols, const struct board_info boards[]) { int i, j, k, c, boardcount = 0, color = 1, num_notes = 0; @@ -362,6 +362,10 @@ char *notes = calloc(1, 1); char tmp[900 + 1];
+ if (!notes) { + fprintf(stderr, "Could not allocate memory!\n"); + return 1; + } for (b = boards; b->vendor != NULL; b++) boardcount++;
@@ -388,6 +392,10 @@ snprintf((char *)&tmp, 900, "<sup>%d</sup> %s<br />\n", 1 + num_notes++, boards_notes[c].note); notes = strcat_realloc(notes, (char *)&tmp); + if (!notes) { + return 1; + } + } else { printf("\n"); } @@ -404,6 +412,8 @@ if (num_notes > 0) printf("\n<small>\n%s</small>\n", notes); free(notes); + + return 0; }
static void wiki_helper2(const char *heading, int cols) @@ -447,16 +457,21 @@ printf("\n|}\n\n|}\n"); }
-void print_supported_boards_wiki(void) +int print_supported_boards_wiki(void) { printf("%s", board_intro); - wiki_helper("Known good (worked out of the box)", "OK", 3, boards_ok); + if (wiki_helper("Known good (worked out of the box)", "OK", 3, boards_ok)) + return 1; wiki_helper2("Known good (with write-enable code in flashrom)", 3); - wiki_helper("Not supported (yet)", "No", 3, boards_bad); + if (wiki_helper("Not supported (yet)", "No", 3, boards_bad)) + return 1;
printf("%s", laptop_intro); - wiki_helper("Known good (worked out of the box)", "OK", 1, laptops_ok); - wiki_helper("Not supported (yet)", "No", 1, laptops_bad); + if (wiki_helper("Known good (worked out of the box)", "OK", 1, laptops_ok)) + return 1; + if (wiki_helper("Not supported (yet)", "No", 1, laptops_bad)) + return 1; + return 0; }
void print_supported_chips_wiki(void) @@ -524,14 +539,15 @@ } }
-void print_wiki_tables(void) +int print_wiki_tables(void) { time_t t = time(NULL);
printf(wiki_header, ctime(&t), flashrom_version); print_supported_chips_wiki(); print_supported_chipsets_wiki(); - print_supported_boards_wiki(); + if (print_supported_boards_wiki()) + return 1; printf("%s", programmer_section); #if NIC3COM_SUPPORT == 1 print_supported_pcidevs_wiki(nics_3com); @@ -543,5 +559,6 @@ print_supported_pcidevs_wiki(satas_sii); #endif printf("\n|}\n"); + return 0; }
Index: flashrom-memleak/print.c =================================================================== --- flashrom-memleak/print.c (Revision 727) +++ flashrom-memleak/print.c (Arbeitskopie) @@ -31,25 +31,48 @@ char *flashbuses_to_text(enum chipbustype bustype) { char *ret = calloc(1, 1); + if (!ret) { + fprintf(stderr, "Could not allocate memory!\n"); + return NULL; + } if (bustype == CHIP_BUSTYPE_UNKNOWN) { ret = strcat_realloc(ret, "Unknown,"); + if (!ret) + return NULL; /* * FIXME: Once all chipsets and flash chips have been updated, NONSPI * will cease to exist and should be eliminated here as well. */ } else if (bustype == CHIP_BUSTYPE_NONSPI) { ret = strcat_realloc(ret, "Non-SPI,"); + if (!ret) + return NULL; } else { - if (bustype & CHIP_BUSTYPE_PARALLEL) + if (bustype & CHIP_BUSTYPE_PARALLEL) { ret = strcat_realloc(ret, "Parallel,"); - if (bustype & CHIP_BUSTYPE_LPC) + if (!ret) + return NULL; + } + if (bustype & CHIP_BUSTYPE_LPC) { ret = strcat_realloc(ret, "LPC,"); - if (bustype & CHIP_BUSTYPE_FWH) + if (!ret) + return NULL; + } + if (bustype & CHIP_BUSTYPE_FWH) { ret = strcat_realloc(ret, "FWH,"); - if (bustype & CHIP_BUSTYPE_SPI) + if (!ret) + return NULL; + } + if (bustype & CHIP_BUSTYPE_SPI) { ret = strcat_realloc(ret, "SPI,"); - if (bustype == CHIP_BUSTYPE_NONE) + if (!ret) + return NULL; + } + if (bustype == CHIP_BUSTYPE_NONE) { ret = strcat_realloc(ret, "None,"); + if (!ret) + return NULL; + } } /* Kill last comma. */ ret[strlen(ret) - 1] = '\0';