mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-04 06:54:27 -05:00 
			
		
		
		
	kernel: mt29f_spinand: fix memory leak during page program
Memory is allocated with devm_kzalloc() on every page program and leaks until device is closed (which never happens). Convert to kzalloc() and handle error paths manually. Signed-off-by: Mantas Pucka <mantas@8devices.com>
This commit is contained in:
		
							parent
							
								
									28baaaae82
								
							
						
					
					
						commit
						7193067edb
					
				@ -0,0 +1,90 @@
 | 
				
			|||||||
 | 
					--- a/drivers/staging/mt29f_spinand/mt29f_spinand.c
 | 
				
			||||||
 | 
					+++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c
 | 
				
			||||||
 | 
					@@ -492,7 +492,7 @@ static int spinand_program_page(struct s
 | 
				
			||||||
 | 
					 #ifdef CONFIG_MTD_SPINAND_ONDIEECC
 | 
				
			||||||
 | 
					 	unsigned int i, j;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					-	wbuf = devm_kzalloc(&spi_nand->dev, CACHE_BUF, GFP_KERNEL);
 | 
				
			||||||
 | 
					+	wbuf = kzalloc(CACHE_BUF, GFP_KERNEL);
 | 
				
			||||||
 | 
					 	if (!wbuf)
 | 
				
			||||||
 | 
					 		return -ENOMEM;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					@@ -500,7 +500,7 @@ static int spinand_program_page(struct s
 | 
				
			||||||
 | 
					 	retval = spinand_read_page(spi_nand, page_id, 0, CACHE_BUF, wbuf);
 | 
				
			||||||
 | 
					 	if (retval < 0) {
 | 
				
			||||||
 | 
					 		dev_err(&spi_nand->dev, "ecc error on read page!!!\n");
 | 
				
			||||||
 | 
					-		return retval;
 | 
				
			||||||
 | 
					+		goto cleanup;
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 	for (i = offset, j = 0; i < len; i++, j++)
 | 
				
			||||||
 | 
					@@ -510,7 +510,7 @@ static int spinand_program_page(struct s
 | 
				
			||||||
 | 
					 		retval = spinand_enable_ecc(spi_nand);
 | 
				
			||||||
 | 
					 		if (retval < 0) {
 | 
				
			||||||
 | 
					 			dev_err(&spi_nand->dev, "enable ecc failed!!\n");
 | 
				
			||||||
 | 
					-			return retval;
 | 
				
			||||||
 | 
					+			goto cleanup;
 | 
				
			||||||
 | 
					 		}
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 #else
 | 
				
			||||||
 | 
					@@ -519,7 +519,7 @@ static int spinand_program_page(struct s
 | 
				
			||||||
 | 
					 	retval = spinand_write_enable(spi_nand);
 | 
				
			||||||
 | 
					 	if (retval < 0) {
 | 
				
			||||||
 | 
					 		dev_err(&spi_nand->dev, "write enable failed!!\n");
 | 
				
			||||||
 | 
					-		return retval;
 | 
				
			||||||
 | 
					+		goto cleanup;
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					 	if (wait_till_ready(spi_nand))
 | 
				
			||||||
 | 
					 		dev_err(&spi_nand->dev, "wait timedout!!!\n");
 | 
				
			||||||
 | 
					@@ -527,23 +527,24 @@ static int spinand_program_page(struct s
 | 
				
			||||||
 | 
					 	retval = spinand_program_data_to_cache(spi_nand, page_id,
 | 
				
			||||||
 | 
					 					       offset, len, wbuf);
 | 
				
			||||||
 | 
					 	if (retval < 0)
 | 
				
			||||||
 | 
					-		return retval;
 | 
				
			||||||
 | 
					+		goto cleanup;
 | 
				
			||||||
 | 
					 	retval = spinand_program_execute(spi_nand, page_id);
 | 
				
			||||||
 | 
					 	if (retval < 0)
 | 
				
			||||||
 | 
					-		return retval;
 | 
				
			||||||
 | 
					+		goto cleanup;
 | 
				
			||||||
 | 
					 	while (1) {
 | 
				
			||||||
 | 
					 		retval = spinand_read_status(spi_nand, &status);
 | 
				
			||||||
 | 
					 		if (retval < 0) {
 | 
				
			||||||
 | 
					 			dev_err(&spi_nand->dev,
 | 
				
			||||||
 | 
					 				"error %d reading status register\n", retval);
 | 
				
			||||||
 | 
					-			return retval;
 | 
				
			||||||
 | 
					+			goto cleanup;
 | 
				
			||||||
 | 
					 		}
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 		if ((status & STATUS_OIP_MASK) == STATUS_READY) {
 | 
				
			||||||
 | 
					 			if ((status & STATUS_P_FAIL_MASK) == STATUS_P_FAIL) {
 | 
				
			||||||
 | 
					 				dev_err(&spi_nand->dev,
 | 
				
			||||||
 | 
					 					"program error, page %d\n", page_id);
 | 
				
			||||||
 | 
					-				return -1;
 | 
				
			||||||
 | 
					+				retval = -1;
 | 
				
			||||||
 | 
					+				goto cleanup;
 | 
				
			||||||
 | 
					 			}
 | 
				
			||||||
 | 
					 			break;
 | 
				
			||||||
 | 
					 		}
 | 
				
			||||||
 | 
					@@ -553,13 +554,20 @@ static int spinand_program_page(struct s
 | 
				
			||||||
 | 
					 		retval = spinand_disable_ecc(spi_nand);
 | 
				
			||||||
 | 
					 		if (retval < 0) {
 | 
				
			||||||
 | 
					 			dev_err(&spi_nand->dev, "disable ecc failed!!\n");
 | 
				
			||||||
 | 
					-			return retval;
 | 
				
			||||||
 | 
					+			goto cleanup;
 | 
				
			||||||
 | 
					 		}
 | 
				
			||||||
 | 
					 		enable_hw_ecc = 0;
 | 
				
			||||||
 | 
					 	}
 | 
				
			||||||
 | 
					+	kfree(wbuf);
 | 
				
			||||||
 | 
					 #endif
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
 | 
					 	return 0;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					+cleanup:
 | 
				
			||||||
 | 
					+#ifdef CONFIG_MTD_SPINAND_ONDIEECC
 | 
				
			||||||
 | 
					+	kfree(wbuf);
 | 
				
			||||||
 | 
					+#endif
 | 
				
			||||||
 | 
					+	return retval;
 | 
				
			||||||
 | 
					+
 | 
				
			||||||
 | 
					 }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					 /**
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user