|
@@ -0,0 +1,325 @@
|
|
|
+From e97709c9d18903f5acd5fbe2985dd054da0432b1 Mon Sep 17 00:00:00 2001
|
|
|
+From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= <[email protected]>
|
|
|
+Date: Wed, 29 Jun 2022 14:57:35 +0200
|
|
|
+Subject: [PATCH 2/4] mtd: always initialize 'stats' in struct mtd_oob_ops
|
|
|
+MIME-Version: 1.0
|
|
|
+Content-Type: text/plain; charset=UTF-8
|
|
|
+Content-Transfer-Encoding: 8bit
|
|
|
+
|
|
|
+As the 'stats' field in struct mtd_oob_ops is used in conditional
|
|
|
+expressions, ensure it is always zero-initialized in all such structures
|
|
|
+to prevent random stack garbage from being interpreted as a pointer.
|
|
|
+
|
|
|
+Strictly speaking, this problem currently only needs to be fixed for
|
|
|
+struct mtd_oob_ops structures subsequently passed to mtd_read_oob().
|
|
|
+However, this commit goes a step further and makes all instances of
|
|
|
+struct mtd_oob_ops in the tree zero-initialized, in hope of preventing
|
|
|
+future problems, e.g. if struct mtd_req_stats gets extended with write
|
|
|
+statistics at some point.
|
|
|
+
|
|
|
+Signed-off-by: Michał Kępień <[email protected]>
|
|
|
+Signed-off-by: Miquel Raynal <[email protected]>
|
|
|
+Link: https://lore.kernel.org/linux-mtd/[email protected]
|
|
|
+---
|
|
|
+ drivers/mtd/inftlcore.c | 6 +++---
|
|
|
+ drivers/mtd/mtdswap.c | 6 +++---
|
|
|
+ drivers/mtd/nand/onenand/onenand_base.c | 4 ++--
|
|
|
+ drivers/mtd/nand/onenand/onenand_bbt.c | 2 +-
|
|
|
+ drivers/mtd/nand/raw/nand_bbt.c | 8 ++++----
|
|
|
+ drivers/mtd/nand/raw/sm_common.c | 2 +-
|
|
|
+ drivers/mtd/nftlcore.c | 6 +++---
|
|
|
+ drivers/mtd/sm_ftl.c | 4 ++--
|
|
|
+ drivers/mtd/ssfdc.c | 2 +-
|
|
|
+ drivers/mtd/tests/nandbiterrs.c | 2 +-
|
|
|
+ drivers/mtd/tests/oobtest.c | 8 ++++----
|
|
|
+ drivers/mtd/tests/readtest.c | 2 +-
|
|
|
+ fs/jffs2/wbuf.c | 6 +++---
|
|
|
+ 13 files changed, 29 insertions(+), 29 deletions(-)
|
|
|
+
|
|
|
+--- a/drivers/mtd/inftlcore.c
|
|
|
++++ b/drivers/mtd/inftlcore.c
|
|
|
+@@ -136,7 +136,7 @@ static void inftl_remove_dev(struct mtd_
|
|
|
+ int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
|
|
|
+ size_t *retlen, uint8_t *buf)
|
|
|
+ {
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int res;
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_PLACE_OOB;
|
|
|
+@@ -156,7 +156,7 @@ int inftl_read_oob(struct mtd_info *mtd,
|
|
|
+ int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
|
|
|
+ size_t *retlen, uint8_t *buf)
|
|
|
+ {
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int res;
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_PLACE_OOB;
|
|
|
+@@ -176,7 +176,7 @@ int inftl_write_oob(struct mtd_info *mtd
|
|
|
+ static int inftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
|
|
|
+ size_t *retlen, uint8_t *buf, uint8_t *oob)
|
|
|
+ {
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int res;
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_PLACE_OOB;
|
|
|
+--- a/drivers/mtd/mtdswap.c
|
|
|
++++ b/drivers/mtd/mtdswap.c
|
|
|
+@@ -323,7 +323,7 @@ static int mtdswap_read_markers(struct m
|
|
|
+ struct mtdswap_oobdata *data, *data2;
|
|
|
+ int ret;
|
|
|
+ loff_t offset;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+
|
|
|
+ offset = mtdswap_eb_offset(d, eb);
|
|
|
+
|
|
|
+@@ -370,7 +370,7 @@ static int mtdswap_write_marker(struct m
|
|
|
+ struct mtdswap_oobdata n;
|
|
|
+ int ret;
|
|
|
+ loff_t offset;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+
|
|
|
+ ops.ooboffs = 0;
|
|
|
+ ops.oobbuf = (uint8_t *)&n;
|
|
|
+@@ -879,7 +879,7 @@ static unsigned int mtdswap_eblk_passes(
|
|
|
+ loff_t base, pos;
|
|
|
+ unsigned int *p1 = (unsigned int *)d->page_buf;
|
|
|
+ unsigned char *p2 = (unsigned char *)d->oob_buf;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_AUTO_OOB;
|
|
|
+--- a/drivers/mtd/nand/onenand/onenand_base.c
|
|
|
++++ b/drivers/mtd/nand/onenand/onenand_base.c
|
|
|
+@@ -2935,7 +2935,7 @@ static int do_otp_write(struct mtd_info
|
|
|
+ struct onenand_chip *this = mtd->priv;
|
|
|
+ unsigned char *pbuf = buf;
|
|
|
+ int ret;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+
|
|
|
+ /* Force buffer page aligned */
|
|
|
+ if (len < mtd->writesize) {
|
|
|
+@@ -2977,7 +2977,7 @@ static int do_otp_lock(struct mtd_info *
|
|
|
+ size_t *retlen, u_char *buf)
|
|
|
+ {
|
|
|
+ struct onenand_chip *this = mtd->priv;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ if (FLEXONENAND(this)) {
|
|
|
+--- a/drivers/mtd/nand/onenand/onenand_bbt.c
|
|
|
++++ b/drivers/mtd/nand/onenand/onenand_bbt.c
|
|
|
+@@ -61,7 +61,7 @@ static int create_bbt(struct mtd_info *m
|
|
|
+ int startblock;
|
|
|
+ loff_t from;
|
|
|
+ size_t readlen, ooblen;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int rgn;
|
|
|
+
|
|
|
+ printk(KERN_INFO "Scanning device for bad blocks\n");
|
|
|
+--- a/drivers/mtd/nand/raw/nand_bbt.c
|
|
|
++++ b/drivers/mtd/nand/raw/nand_bbt.c
|
|
|
+@@ -313,7 +313,7 @@ static int scan_read_oob(struct nand_chi
|
|
|
+ size_t len)
|
|
|
+ {
|
|
|
+ struct mtd_info *mtd = nand_to_mtd(this);
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int res, ret = 0;
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_PLACE_OOB;
|
|
|
+@@ -354,7 +354,7 @@ static int scan_write_bbt(struct nand_ch
|
|
|
+ uint8_t *buf, uint8_t *oob)
|
|
|
+ {
|
|
|
+ struct mtd_info *mtd = nand_to_mtd(this);
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_PLACE_OOB;
|
|
|
+ ops.ooboffs = 0;
|
|
|
+@@ -416,7 +416,7 @@ static int scan_block_fast(struct nand_c
|
|
|
+ {
|
|
|
+ struct mtd_info *mtd = nand_to_mtd(this);
|
|
|
+
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int ret, page_offset;
|
|
|
+
|
|
|
+ ops.ooblen = mtd->oobsize;
|
|
|
+@@ -756,7 +756,7 @@ static int write_bbt(struct nand_chip *t
|
|
|
+ uint8_t rcode = td->reserved_block_code;
|
|
|
+ size_t retlen, len = 0;
|
|
|
+ loff_t to;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+
|
|
|
+ ops.ooblen = mtd->oobsize;
|
|
|
+ ops.ooboffs = 0;
|
|
|
+--- a/drivers/mtd/nand/raw/sm_common.c
|
|
|
++++ b/drivers/mtd/nand/raw/sm_common.c
|
|
|
+@@ -99,7 +99,7 @@ static const struct mtd_ooblayout_ops oo
|
|
|
+ static int sm_block_markbad(struct nand_chip *chip, loff_t ofs)
|
|
|
+ {
|
|
|
+ struct mtd_info *mtd = nand_to_mtd(chip);
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ struct sm_oob oob;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+--- a/drivers/mtd/nftlcore.c
|
|
|
++++ b/drivers/mtd/nftlcore.c
|
|
|
+@@ -124,7 +124,7 @@ int nftl_read_oob(struct mtd_info *mtd,
|
|
|
+ size_t *retlen, uint8_t *buf)
|
|
|
+ {
|
|
|
+ loff_t mask = mtd->writesize - 1;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int res;
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_PLACE_OOB;
|
|
|
+@@ -145,7 +145,7 @@ int nftl_write_oob(struct mtd_info *mtd,
|
|
|
+ size_t *retlen, uint8_t *buf)
|
|
|
+ {
|
|
|
+ loff_t mask = mtd->writesize - 1;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int res;
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_PLACE_OOB;
|
|
|
+@@ -168,7 +168,7 @@ static int nftl_write(struct mtd_info *m
|
|
|
+ size_t *retlen, uint8_t *buf, uint8_t *oob)
|
|
|
+ {
|
|
|
+ loff_t mask = mtd->writesize - 1;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int res;
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_PLACE_OOB;
|
|
|
+--- a/drivers/mtd/sm_ftl.c
|
|
|
++++ b/drivers/mtd/sm_ftl.c
|
|
|
+@@ -239,7 +239,7 @@ static int sm_read_sector(struct sm_ftl
|
|
|
+ uint8_t *buffer, struct sm_oob *oob)
|
|
|
+ {
|
|
|
+ struct mtd_info *mtd = ftl->trans->mtd;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ struct sm_oob tmp_oob;
|
|
|
+ int ret = -EIO;
|
|
|
+ int try = 0;
|
|
|
+@@ -323,7 +323,7 @@ static int sm_write_sector(struct sm_ftl
|
|
|
+ int zone, int block, int boffset,
|
|
|
+ uint8_t *buffer, struct sm_oob *oob)
|
|
|
+ {
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ struct mtd_info *mtd = ftl->trans->mtd;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+--- a/drivers/mtd/ssfdc.c
|
|
|
++++ b/drivers/mtd/ssfdc.c
|
|
|
+@@ -163,7 +163,7 @@ static int read_physical_sector(struct m
|
|
|
+ /* Read redundancy area (wrapper to MTD_READ_OOB */
|
|
|
+ static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf)
|
|
|
+ {
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_RAW;
|
|
|
+--- a/drivers/mtd/tests/nandbiterrs.c
|
|
|
++++ b/drivers/mtd/tests/nandbiterrs.c
|
|
|
+@@ -99,7 +99,7 @@ static int write_page(int log)
|
|
|
+ static int rewrite_page(int log)
|
|
|
+ {
|
|
|
+ int err = 0;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+
|
|
|
+ if (log)
|
|
|
+ pr_info("rewrite page\n");
|
|
|
+--- a/drivers/mtd/tests/oobtest.c
|
|
|
++++ b/drivers/mtd/tests/oobtest.c
|
|
|
+@@ -56,7 +56,7 @@ static void do_vary_offset(void)
|
|
|
+ static int write_eraseblock(int ebnum)
|
|
|
+ {
|
|
|
+ int i;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int err = 0;
|
|
|
+ loff_t addr = (loff_t)ebnum * mtd->erasesize;
|
|
|
+
|
|
|
+@@ -165,7 +165,7 @@ static size_t memffshow(loff_t addr, lof
|
|
|
+ static int verify_eraseblock(int ebnum)
|
|
|
+ {
|
|
|
+ int i;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int err = 0;
|
|
|
+ loff_t addr = (loff_t)ebnum * mtd->erasesize;
|
|
|
+ size_t bitflips;
|
|
|
+@@ -260,7 +260,7 @@ static int verify_eraseblock(int ebnum)
|
|
|
+
|
|
|
+ static int verify_eraseblock_in_one_go(int ebnum)
|
|
|
+ {
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int err = 0;
|
|
|
+ loff_t addr = (loff_t)ebnum * mtd->erasesize;
|
|
|
+ size_t len = mtd->oobavail * pgcnt;
|
|
|
+@@ -338,7 +338,7 @@ static int __init mtd_oobtest_init(void)
|
|
|
+ int err = 0;
|
|
|
+ unsigned int i;
|
|
|
+ uint64_t tmp;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ loff_t addr = 0, addr0;
|
|
|
+
|
|
|
+ printk(KERN_INFO "\n");
|
|
|
+--- a/drivers/mtd/tests/readtest.c
|
|
|
++++ b/drivers/mtd/tests/readtest.c
|
|
|
+@@ -47,7 +47,7 @@ static int read_eraseblock_by_page(int e
|
|
|
+ err = ret;
|
|
|
+ }
|
|
|
+ if (mtd->oobsize) {
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_PLACE_OOB;
|
|
|
+ ops.len = 0;
|
|
|
+--- a/fs/jffs2/wbuf.c
|
|
|
++++ b/fs/jffs2/wbuf.c
|
|
|
+@@ -1035,7 +1035,7 @@ int jffs2_check_oob_empty(struct jffs2_s
|
|
|
+ {
|
|
|
+ int i, ret;
|
|
|
+ int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_AUTO_OOB;
|
|
|
+ ops.ooblen = NR_OOB_SCAN_PAGES * c->oobavail;
|
|
|
+@@ -1076,7 +1076,7 @@ int jffs2_check_oob_empty(struct jffs2_s
|
|
|
+ int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c,
|
|
|
+ struct jffs2_eraseblock *jeb)
|
|
|
+ {
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int ret, cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_AUTO_OOB;
|
|
|
+@@ -1101,7 +1101,7 @@ int jffs2_write_nand_cleanmarker(struct
|
|
|
+ struct jffs2_eraseblock *jeb)
|
|
|
+ {
|
|
|
+ int ret;
|
|
|
+- struct mtd_oob_ops ops;
|
|
|
++ struct mtd_oob_ops ops = { };
|
|
|
+ int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
|
|
|
+
|
|
|
+ ops.mode = MTD_OPS_AUTO_OOB;
|