2015-02-28 10:02:55

by Brian Norris

[permalink] [raw]
Subject: [PATCH 0/7] mtd: various fixes caught by Coverity

Several unrelated MTD fixes inspired by Coverity Scan results. I couldn't test
all of them, but they're all pretty obvious.

Brian Norris (7):
mtd: docg3: drop dead code
mtd: onenand: drop dead code
mtd: tests: fix more potential integer overflows
mtd: nand: fixup bounds checks for nand_{lock,unlock}()
mtd: nand: denali: drop dead code
mtd: blkdevs: remove dead code
mtd: nand: fully initialize mtd_oob_ops

drivers/mtd/devices/docg3.c | 2 --
drivers/mtd/mtd_blkdevs.c | 3 ---
drivers/mtd/nand/denali.c | 3 ---
drivers/mtd/nand/nand_base.c | 12 ++++++------
drivers/mtd/onenand/onenand_base.c | 12 +++---------
drivers/mtd/tests/oobtest.c | 2 +-
drivers/mtd/tests/speedtest.c | 2 +-
drivers/mtd/tests/stresstest.c | 4 ++--
drivers/mtd/tests/subpagetest.c | 4 ++--
drivers/mtd/tests/torturetest.c | 8 ++++----
10 files changed, 19 insertions(+), 33 deletions(-)

--
2.1.0


2015-02-28 10:05:05

by Brian Norris

[permalink] [raw]
Subject: [PATCH 1/7] mtd: docg3: drop dead code

If no devices were found, we would already have skipped over this code.

Detected by Coverity, CID #744270

Signed-off-by: Brian Norris <[email protected]>
---
drivers/mtd/devices/docg3.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index 448ce42f951e..01eddea1f0d9 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -2079,8 +2079,6 @@ static int __init docg3_probe(struct platform_device *pdev)
ret = doc_register_sysfs(pdev, cascade);
if (ret)
goto err_probe;
- if (!found)
- goto notfound;

platform_set_drvdata(pdev, cascade);
doc_dbg_register(cascade->floors[0]->priv);
--
2.1.0

2015-02-28 10:03:00

by Brian Norris

[permalink] [raw]
Subject: [PATCH 2/7] mtd: onenand: drop dead code

'ret' is always zero, so this is all dead code.

This should quiet Coverity CID #1226739.

Signed-off-by: Brian Norris <[email protected]>
Cc: Kyungmin Park <[email protected]>
---
drivers/mtd/onenand/onenand_base.c | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 635ee0027691..43b3392ffee7 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1743,7 +1743,6 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
struct onenand_chip *this = mtd->priv;
int column, subpage;
int written = 0;
- int ret = 0;

if (this->state == FL_PM_SUSPENDED)
return -EBUSY;
@@ -1786,15 +1785,10 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
onenand_panic_wait(mtd);

/* In partial page write we don't update bufferram */
- onenand_update_bufferram(mtd, to, !ret && !subpage);
+ onenand_update_bufferram(mtd, to, !subpage);
if (ONENAND_IS_2PLANE(this)) {
ONENAND_SET_BUFFERRAM1(this);
- onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage);
- }
-
- if (ret) {
- printk(KERN_ERR "%s: write failed %d\n", __func__, ret);
- break;
+ onenand_update_bufferram(mtd, to + this->writesize, !subpage);
}

written += thislen;
@@ -1808,7 +1802,7 @@ static int onenand_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
}

*retlen = written;
- return ret;
+ return 0;
}

/**
--
2.1.0

2015-02-28 10:04:08

by Brian Norris

[permalink] [raw]
Subject: [PATCH 3/7] mtd: tests: fix more potential integer overflows

Caught by Coverity (CID #200625 and others)

Signed-off-by: Brian Norris <[email protected]>
Cc: Akinobu Mita <[email protected]>
---
drivers/mtd/tests/oobtest.c | 2 +-
drivers/mtd/tests/speedtest.c | 2 +-
drivers/mtd/tests/stresstest.c | 4 ++--
drivers/mtd/tests/subpagetest.c | 4 ++--
drivers/mtd/tests/torturetest.c | 8 ++++----
5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/tests/oobtest.c b/drivers/mtd/tests/oobtest.c
index 5e061186eab1..64390ab88a80 100644
--- a/drivers/mtd/tests/oobtest.c
+++ b/drivers/mtd/tests/oobtest.c
@@ -70,7 +70,7 @@ static int write_eraseblock(int ebnum)
int i;
struct mtd_oob_ops ops;
int err = 0;
- loff_t addr = ebnum * mtd->erasesize;
+ loff_t addr = (loff_t)ebnum * mtd->erasesize;

prandom_bytes_state(&rnd_state, writebuf, use_len_max * pgcnt);
for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) {
diff --git a/drivers/mtd/tests/speedtest.c b/drivers/mtd/tests/speedtest.c
index 5ee9f7021020..a77019cb5510 100644
--- a/drivers/mtd/tests/speedtest.c
+++ b/drivers/mtd/tests/speedtest.c
@@ -185,7 +185,7 @@ static long calc_speed(void)
(finish.tv_usec - start.tv_usec) / 1000;
if (ms == 0)
return 0;
- k = goodebcnt * (mtd->erasesize / 1024) * 1000;
+ k = (uint64_t)goodebcnt * (mtd->erasesize / 1024) * 1000;
do_div(k, ms);
return k;
}
diff --git a/drivers/mtd/tests/stresstest.c b/drivers/mtd/tests/stresstest.c
index c9d42cc2df1b..d90c1c01dac6 100644
--- a/drivers/mtd/tests/stresstest.c
+++ b/drivers/mtd/tests/stresstest.c
@@ -96,7 +96,7 @@ static int do_read(void)
if (offs + len > mtd->erasesize)
len = mtd->erasesize - offs;
}
- addr = eb * mtd->erasesize + offs;
+ addr = (loff_t)eb * mtd->erasesize + offs;
return mtdtest_read(mtd, addr, len, readbuf);
}

@@ -124,7 +124,7 @@ static int do_write(void)
offsets[eb + 1] = 0;
}
}
- addr = eb * mtd->erasesize + offs;
+ addr = (loff_t)eb * mtd->erasesize + offs;
err = mtdtest_write(mtd, addr, len, writebuf);
if (unlikely(err))
return err;
diff --git a/drivers/mtd/tests/subpagetest.c b/drivers/mtd/tests/subpagetest.c
index 7b59ef522d5e..0b835c631f91 100644
--- a/drivers/mtd/tests/subpagetest.c
+++ b/drivers/mtd/tests/subpagetest.c
@@ -95,7 +95,7 @@ static int write_eraseblock2(int ebnum)
loff_t addr = (loff_t)ebnum * mtd->erasesize;

for (k = 1; k < 33; ++k) {
- if (addr + (subpgsize * k) > (ebnum + 1) * mtd->erasesize)
+ if (addr + (subpgsize * k) > (loff_t)(ebnum + 1) * mtd->erasesize)
break;
prandom_bytes_state(&rnd_state, writebuf, subpgsize * k);
err = mtd_write(mtd, addr, subpgsize * k, &written, writebuf);
@@ -195,7 +195,7 @@ static int verify_eraseblock2(int ebnum)
loff_t addr = (loff_t)ebnum * mtd->erasesize;

for (k = 1; k < 33; ++k) {
- if (addr + (subpgsize * k) > (ebnum + 1) * mtd->erasesize)
+ if (addr + (subpgsize * k) > (loff_t)(ebnum + 1) * mtd->erasesize)
break;
prandom_bytes_state(&rnd_state, writebuf, subpgsize * k);
clear_data(readbuf, subpgsize * k);
diff --git a/drivers/mtd/tests/torturetest.c b/drivers/mtd/tests/torturetest.c
index b55bc52a1340..5045cf1b3160 100644
--- a/drivers/mtd/tests/torturetest.c
+++ b/drivers/mtd/tests/torturetest.c
@@ -101,11 +101,11 @@ static inline int check_eraseblock(int ebnum, unsigned char *buf)
{
int err, retries = 0;
size_t read;
- loff_t addr = ebnum * mtd->erasesize;
+ loff_t addr = (loff_t)ebnum * mtd->erasesize;
size_t len = mtd->erasesize;

if (pgcnt) {
- addr = (ebnum + 1) * mtd->erasesize - pgcnt * pgsize;
+ addr = (loff_t)(ebnum + 1) * mtd->erasesize - pgcnt * pgsize;
len = pgcnt * pgsize;
}

@@ -155,11 +155,11 @@ static inline int write_pattern(int ebnum, void *buf)
{
int err;
size_t written;
- loff_t addr = ebnum * mtd->erasesize;
+ loff_t addr = (loff_t)ebnum * mtd->erasesize;
size_t len = mtd->erasesize;

if (pgcnt) {
- addr = (ebnum + 1) * mtd->erasesize - pgcnt * pgsize;
+ addr = (loff_t)(ebnum + 1) * mtd->erasesize - pgcnt * pgsize;
len = pgcnt * pgsize;
}
err = mtd_write(mtd, addr, len, &written, buf);
--
2.1.0

2015-02-28 10:04:07

by Brian Norris

[permalink] [raw]
Subject: [PATCH 4/7] mtd: nand: fixup bounds checks for nand_{lock,unlock}()

Coverity noticed that these 'ret' assignments weren't being used. Let's
use them.

Note that nand_lock() and nand_unlock() are still not officially used by
any drivers.

Coverity CIDs #1227054 and #1227037

Signed-off-by: Brian Norris <[email protected]>
---
drivers/mtd/nand/nand_base.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index df7eb4ff07d1..5488a7ad63e7 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -968,7 +968,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
__func__, (unsigned long long)ofs, len);

if (check_offs_len(mtd, ofs, len))
- ret = -EINVAL;
+ return -EINVAL;

/* Align to last block address if size addresses end of the device */
if (ofs + len == mtd->size)
@@ -1031,7 +1031,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
__func__, (unsigned long long)ofs, len);

if (check_offs_len(mtd, ofs, len))
- ret = -EINVAL;
+ return -EINVAL;

nand_get_device(mtd, FL_LOCKING);

--
2.1.0

2015-02-28 10:03:08

by Brian Norris

[permalink] [raw]
Subject: [PATCH 5/7] mtd: nand: denali: drop dead code

TclsRising is always 1.

Caught by Coverity.

Signed-off-by: Brian Norris <[email protected]>
Cc: Masahiro Yamada <[email protected]>
---
drivers/mtd/nand/denali.c | 3 ---
1 file changed, 3 deletions(-)

diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index f44c6061536a..09f51395f2c0 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -225,7 +225,6 @@ static void nand_onfi_timing_set(struct denali_nand_info *denali,
uint16_t Twhr[6] = {120, 80, 80, 60, 60, 60};
uint16_t Tcs[6] = {70, 35, 25, 25, 20, 15};

- uint16_t TclsRising = 1;
uint16_t data_invalid_rhoh, data_invalid_rloh, data_invalid;
uint16_t dv_window = 0;
uint16_t en_lo, en_hi;
@@ -276,8 +275,6 @@ static void nand_onfi_timing_set(struct denali_nand_info *denali,
re_2_re = CEIL_DIV(Trhz[mode], CLK_X);
we_2_re = CEIL_DIV(Twhr[mode], CLK_X);
cs_cnt = CEIL_DIV((Tcs[mode] - Trp[mode]), CLK_X);
- if (!TclsRising)
- cs_cnt = CEIL_DIV(Tcs[mode], CLK_X);
if (cs_cnt == 0)
cs_cnt = 1;

--
2.1.0

2015-02-28 10:03:11

by Brian Norris

[permalink] [raw]
Subject: [PATCH 6/7] mtd: blkdevs: remove dead code

The only exit (break) from the preceding loop is nested within a
condition which yields req == NULL. This code is dead.

Coverity CID #752669

Signed-off-by: Brian Norris <[email protected]>
---
drivers/mtd/mtd_blkdevs.c | 3 ---
1 file changed, 3 deletions(-)

diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index d08229eb44d8..2b0c52870999 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -171,9 +171,6 @@ static void mtd_blktrans_work(struct work_struct *work)
background_done = 0;
}

- if (req)
- __blk_end_request_all(req, -EIO);
-
spin_unlock_irq(rq->queue_lock);
}

--
2.1.0

2015-02-28 10:03:46

by Brian Norris

[permalink] [raw]
Subject: [PATCH 7/7] mtd: nand: fully initialize mtd_oob_ops

We're not initializing the ooblen field. Our users don't care, since
they check that oobbuf == NULL first, but it's good practice to zero
unused fields out.

We can drop the NULL initializations since we're memset()ing the whole
thing.

Noticed by Coverity, CID #200821, #200822

Signed-off-by: Brian Norris <[email protected]>
---
drivers/mtd/nand/nand_base.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 5488a7ad63e7..d4cec2f8a016 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -386,7 +386,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
uint8_t buf[2] = { 0, 0 };
int ret = 0, res, i = 0;

- ops.datbuf = NULL;
+ memset(&ops, 0, sizeof(ops));
ops.oobbuf = buf;
ops.ooboffs = chip->badblockpos;
if (chip->options & NAND_BUSWIDTH_16) {
@@ -1716,9 +1716,9 @@ static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
int ret;

nand_get_device(mtd, FL_READING);
+ memset(&ops, 0, sizeof(ops));
ops.len = len;
ops.datbuf = buf;
- ops.oobbuf = NULL;
ops.mode = MTD_OPS_PLACE_OOB;
ret = nand_do_read_ops(mtd, from, &ops);
*retlen = ops.retlen;
@@ -2508,9 +2508,9 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
/* Grab the device */
panic_nand_get_device(chip, mtd, FL_WRITING);

+ memset(&ops, 0, sizeof(ops));
ops.len = len;
ops.datbuf = (uint8_t *)buf;
- ops.oobbuf = NULL;
ops.mode = MTD_OPS_PLACE_OOB;

ret = nand_do_write_ops(mtd, to, &ops);
@@ -2536,9 +2536,9 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
int ret;

nand_get_device(mtd, FL_WRITING);
+ memset(&ops, 0, sizeof(ops));
ops.len = len;
ops.datbuf = (uint8_t *)buf;
- ops.oobbuf = NULL;
ops.mode = MTD_OPS_PLACE_OOB;
ret = nand_do_write_ops(mtd, to, &ops);
*retlen = ops.retlen;
--
2.1.0