Patchwork at45db buffer overflow

login
register
about
Submitter Alexander Irenkov
Date 2014-02-01 05:56:22
Message ID <1391234182.3993.9.camel@Nokia-N900>
Download mbox | patch
Permalink /patch/4107/
State Superseded
Headers show

Comments

Alexander Irenkov - 2014-02-01 05:56:22
I found buffer overflow at at45db module. Error was in chunk length calculation.
Patch is attached.

Chip AT45DB041D: reading, writing and erasing operations works correctly.

Best regards, Alexander Irenkov

Patch

--- flashrom.orig/at45db.c	Wed Aug 28 00:02:19 2013
+++ flashrom/at45db.c	Sat Feb  1 11:41:46 2014
@@ -252,12 +252,13 @@  int spi_read_at45db(struct flashctx *fla
 
 	/* We have to split this up into chunks to fit within the programmer's read size limit, but those
 	 * chunks can cross page boundaries. */
 	const unsigned int max_data_read = flash->pgm->spi.max_data_read;
 	const unsigned int max_chunk = (max_data_read > 0) ? max_data_read : page_size;
-	while (addr < len) {
-		unsigned int chunk = min(max_chunk, len);
+	const unsigned int end_addr = addr + len;
+	while (addr < end_addr) {
+		unsigned int chunk = min(max_chunk, end_addr - addr);
 		int ret = spi_nbyte_read(flash, at45db_convert_addr(addr, page_size), buf + addr, chunk);
 		if (ret) {
 			msg_cerr("%s: error sending read command!\n", __func__);
 			return ret;
 		}
@@ -281,20 +282,21 @@  int spi_read_at45db_e8(struct flashctx *
 
 	/* We have to split this up into chunks to fit within the programmer's read size limit, but those
 	 * chunks can cross page boundaries. */
 	const unsigned int max_data_read = flash->pgm->spi.max_data_read;
 	const unsigned int max_chunk = (max_data_read > 0) ? max_data_read : page_size;
-	while (addr < len) {
+	const unsigned int end_addr = addr + len;
+	while (addr < end_addr) {
 		const unsigned int addr_at45 = at45db_convert_addr(addr, page_size);
 		const unsigned char cmd[] = {
 			AT45DB_READ_ARRAY,
 			(addr_at45 >> 16) & 0xff,
 			(addr_at45 >> 8) & 0xff,
 			(addr_at45 >> 0) & 0xff
 		};
 		/* We need to leave place for 4 dummy bytes and handle them explicitly. */
-		unsigned int chunk = min(max_chunk, len + 4);
+		unsigned int chunk = min(max_chunk, end_addr - addr + 4);
 		uint8_t tmp[chunk];
 		int ret = spi_send_command(flash, sizeof(cmd), chunk, cmd, tmp);
 		if (ret) {
 			msg_cerr("%s: error sending read command!\n", __func__);
 			return ret;