]> www.infradead.org Git - mtd-utils.git/commitdiff
mtd-utils: Check mtdoffset is not larger than mtd.size in case of a bad block.
authorTomer Barletz <barletz@gmail.com>
Tue, 26 Jun 2012 21:46:41 +0000 (14:46 -0700)
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Fri, 29 Jun 2012 08:29:26 +0000 (11:29 +0300)
mtdoffset is being tested against mtd.size in the outer two loops, but
the third nested one does not test against it.
In case of a bad block we'll try to access an out of bounds offset in
the next MEMGETBADBLOCK ioctl, which will fail with EINVAL.
In case mtdoffset is indeed larger than the partition size, we need to
bail, since there are not enough "good" blocks to complete the write.

Signed-off-by: Tomer Barletz <barletz@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
nandwrite.c

index ca0c263c0d0e50fc0f22fc09bfca94b0f96bf859..de8e7d2aee11a9b3ae72b02204583c42de14b9fb 100644 (file)
@@ -385,7 +385,8 @@ int main(int argc, char * const argv[])
                                continue;
 
                        do {
-                               if ((ret = mtd_is_bad(&mtd, fd, offs / ebsize_aligned)) < 0) {
+                               ret = mtd_is_bad(&mtd, fd, offs / ebsize_aligned);
+                               if (ret < 0) {
                                        sys_errmsg("%s: MTD get bad block failed", mtd_device);
                                        goto closeall;
                                } else if (ret == 1) {
@@ -396,9 +397,15 @@ int main(int argc, char * const argv[])
                                                                offs, blockalign, blockstart);
                                }
 
-                               if (baderaseblock)
+                               if (baderaseblock) {
                                        mtdoffset = blockstart + ebsize_aligned;
 
+                                       if (mtdoffset > mtd.size) {
+                                               errmsg("too many bad blocks, cannot complete request");
+                                               goto closeall;
+                                       }
+                               }
+
                                offs +=  ebsize_aligned / blockalign;
                        } while (offs < blockstart + ebsize_aligned);