fa4dc86e98
MEMREAD is a new ioctl for MTD character devices that was first included in Linux 6.1. It allows userspace applications to use the Linux kernel's OOB autoplacement mechanism while reading data from NAND devices. The Yafut tool needs this ioctl to do its job. Signed-off-by: Michał Kępień <openwrt@kempniu.pl>
326 lines
9.8 KiB
Diff
326 lines
9.8 KiB
Diff
From e97709c9d18903f5acd5fbe2985dd054da0432b1 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= <kernel@kempniu.pl>
|
|
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ń <kernel@kempniu.pl>
|
|
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
|
Link: https://lore.kernel.org/linux-mtd/20220629125737.14418-3-kernel@kempniu.pl
|
|
---
|
|
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;
|