mtd: fix resetbc on nand w/ min I/O size > 2048
authorQiyuan Zhang <zhang.github@outlook.com>
Fri, 2 Aug 2024 14:57:51 +0000 (10:57 -0400)
committerRobert Marko <robimarko@gmail.com>
Tue, 31 Dec 2024 16:44:10 +0000 (17:44 +0100)
Fix a bug in linksys_bootcount.c that resetbc  won't work on nand
with min I/O size> 2048.

Check the boot-log entry's intergrity with checksum.

Signed-off-by: Qiyuan Zhang <zhang.github@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/16070
Signed-off-by: Robert Marko <robimarko@gmail.com>
package/system/mtd/src/linksys_bootcount.c

index bd06728696ce3f01875789b6bdfaa83ba8bc4e24..d22486203e90c115e098806ab17bfee323973b79 100644 (file)
@@ -69,12 +69,10 @@ struct bootcounter {
        uint32_t checksum;
 };
 
-static char page[2048];
-
 int mtd_resetbc(const char *mtd)
 {
        struct mtd_info_user mtd_info;
-       struct bootcounter *curr = (struct bootcounter *)page;
+       struct bootcounter *curr = NULL;
        unsigned int i;
        unsigned int bc_offset_increment;
        int last_count = 0;
@@ -108,24 +106,23 @@ int mtd_resetbc(const char *mtd)
        }
 
        num_bc = mtd_info.size / bc_offset_increment;
+        curr = malloc(bc_offset_increment);
 
        for (i = 0; i < num_bc; i++) {
-               pread(fd, curr, sizeof(*curr), i * bc_offset_increment);
+               pread(fd, curr, sizeof(struct bootcounter), i * bc_offset_increment);
 
                /* Existing code assumes erase is to 0xff; left as-is (2019) */
+               if (curr->magic == 0xffffffff)
+                       break;
 
-               if (curr->magic != BOOTCOUNT_MAGIC &&
-                   curr->magic != 0xffffffff) {
-                       DLOG_ERR("Unexpected magic %08x at offset %08x; aborting.",
-                                curr->magic, i * bc_offset_increment);
+               if (curr->magic != BOOTCOUNT_MAGIC || curr->checksum != curr->magic + curr->count) {
+                       DLOG_ERR("Unexpected boot-count log at offset %08x: magic %08x boot count %08x checksum %08x; aborting.",
+                                i * bc_offset_increment, curr->magic, curr->count, curr->checksum);
 
                        retval = -2;
                        goto out;
                }
 
-               if (curr->magic == 0xffffffff)
-                       break;
-
                last_count = curr->count;
        }
 
@@ -182,6 +179,7 @@ int mtd_resetbc(const char *mtd)
        }
 
 out:
+       if (curr != NULL) free(curr);
        close(fd);
        return retval;
 }