mtd: m25p80: fix allocation size
authorBrian Norris <computersforpeace@gmail.com>
Thu, 25 Jul 2013 01:32:07 +0000 (18:32 -0700)
committerBrian Norris <computersforpeace@gmail.com>
Thu, 7 Nov 2013 07:33:04 +0000 (23:33 -0800)
This patch fixes two memory errors:

1. During a probe failure (in mtd_device_parse_register?) the command
   buffer would not be freed.

2. The command buffer's size is determined based on the 'fast_read'
   boolean, but the assignment of fast_read is made after this
   allocation. Thus, the buffer may be allocated "too small".

To fix the first, just switch to the devres version of kzalloc.

To fix the second, increase MAX_CMD_SIZE unconditionally. It's not worth
saving a byte to fiddle around with the conditions here.

This problem was reported by Yuhang Wang a while back.

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Reported-by: Yuhang Wang <wangyuhang2014@gmail.com>
Reviewed-by: Sourav Poddar <sourav.poddar@ti.com>
Cc: <stable@vger.kernel.org>
drivers/mtd/devices/m25p80.c

index 8d6c87be95982f22ec48c79fe581dc0a387116e6..63a95ac89f18460f6abb0950894eccb756203bbe 100644 (file)
@@ -78,7 +78,7 @@
 
 /* Define max times to check status register before we give up. */
 #define        MAX_READY_WAIT_JIFFIES  (40 * HZ)       /* M25P16 specs 40s max chip erase */
-#define        MAX_CMD_SIZE            5
+#define        MAX_CMD_SIZE            6
 
 #define JEDEC_MFR(_jedec_id)   ((_jedec_id) >> 16)
 
@@ -996,15 +996,13 @@ static int m25p_probe(struct spi_device *spi)
                }
        }
 
-       flash = kzalloc(sizeof *flash, GFP_KERNEL);
+       flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
        if (!flash)
                return -ENOMEM;
-       flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0),
-                                       GFP_KERNEL);
-       if (!flash->command) {
-               kfree(flash);
+
+       flash->command = devm_kzalloc(&spi->dev, MAX_CMD_SIZE, GFP_KERNEL);
+       if (!flash->command)
                return -ENOMEM;
-       }
 
        flash->spi = spi;
        mutex_init(&flash->lock);
@@ -1137,14 +1135,10 @@ static int m25p_probe(struct spi_device *spi)
 static int m25p_remove(struct spi_device *spi)
 {
        struct m25p     *flash = spi_get_drvdata(spi);
-       int             status;
 
        /* Clean up MTD stuff. */
-       status = mtd_device_unregister(&flash->mtd);
-       if (status == 0) {
-               kfree(flash->command);
-               kfree(flash);
-       }
+       mtd_device_unregister(&flash->mtd);
+
        return 0;
 }