From aac17948a7ce01fb60b9ee6cf902967a47b3ce26 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 17 Jan 2018 19:12:42 +0100 Subject: [PATCH 1/7] ubifs: Check ubifs_wbuf_sync() return code If ubifs_wbuf_sync() fails we must not write a master node with the dirty marker cleared. Otherwise it is possible that in case of an IO error while syncing we mark the filesystem as clean and UBIFS refuses to recover upon next mount. Cc: Fixes: 1e51764a3c2a ("UBIFS: add new flash file system") Signed-off-by: Richard Weinberger --- fs/ubifs/super.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index b16ef162344a..6c397a389105 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1737,8 +1737,11 @@ static void ubifs_remount_ro(struct ubifs_info *c) dbg_save_space_info(c); - for (i = 0; i < c->jhead_cnt; i++) - ubifs_wbuf_sync(&c->jheads[i].wbuf); + for (i = 0; i < c->jhead_cnt; i++) { + err = ubifs_wbuf_sync(&c->jheads[i].wbuf); + if (err) + ubifs_ro_mode(c, err); + } c->mst_node->flags &= ~cpu_to_le32(UBIFS_MST_DIRTY); c->mst_node->flags |= cpu_to_le32(UBIFS_MST_NO_ORPHS); @@ -1804,8 +1807,11 @@ static void ubifs_put_super(struct super_block *sb) int err; /* Synchronize write-buffers */ - for (i = 0; i < c->jhead_cnt; i++) - ubifs_wbuf_sync(&c->jheads[i].wbuf); + for (i = 0; i < c->jhead_cnt; i++) { + err = ubifs_wbuf_sync(&c->jheads[i].wbuf); + if (err) + ubifs_ro_mode(c, err); + } /* * We are being cleanly unmounted which means the From 29b7a6fa1ec07e8480b0d9caf635a4498a438bf4 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Wed, 17 Jan 2018 23:15:57 +0100 Subject: [PATCH 2/7] ubi: fastmap: Don't flush fastmap work on detach At this point UBI volumes have already been free()'ed and fastmap can no longer access these data structures. Reported-by: Martin Townsend Fixes: 74cdaf24004a ("UBI: Fastmap: Fix memory leaks while closing the WL sub-system") Cc: stable@vger.kernel.org Signed-off-by: Richard Weinberger --- drivers/mtd/ubi/fastmap-wl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c index 590d967011bb..98f7d6be8d1f 100644 --- a/drivers/mtd/ubi/fastmap-wl.c +++ b/drivers/mtd/ubi/fastmap-wl.c @@ -362,7 +362,6 @@ static void ubi_fastmap_close(struct ubi_device *ubi) { int i; - flush_work(&ubi->fm_work); return_unused_pool_pebs(ubi, &ubi->fm_pool); return_unused_pool_pebs(ubi, &ubi->fm_wl_pool); From 78a8dfbabbece22bee58ac4cb26cab10e7a19c5d Mon Sep 17 00:00:00 2001 From: Romain Izard Date: Mon, 29 Jan 2018 11:18:20 +0100 Subject: [PATCH 3/7] ubi: Fix error for write access When opening a device with write access, ubiblock_open returns an error code. Currently, this error code is -EPERM, but this is not the right value. The open function for other block devices returns -EROFS when opening read-only devices with FMODE_WRITE set. When used with dm-verity, the veritysetup userspace tool is expecting EROFS, and refuses to use the ubiblock device. Use -EROFS for ubiblock as well. As a result, veritysetup accepts the ubiblock device as valid. Cc: stable@vger.kernel.org Fixes: 9d54c8a33eec (UBI: R/O block driver on top of UBI volumes) Signed-off-by: Romain Izard Signed-off-by: Richard Weinberger --- drivers/mtd/ubi/block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index b1fc28f63882..d0b63bbf46a7 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c @@ -244,7 +244,7 @@ static int ubiblock_open(struct block_device *bdev, fmode_t mode) * in any case. */ if (mode & FMODE_WRITE) { - ret = -EPERM; + ret = -EROFS; goto out_unlock; } From ae4c8081eb77bc82ac5ac8a7d55abea6f98e0209 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Sun, 11 Feb 2018 23:17:36 +0100 Subject: [PATCH 4/7] ubifs: remove unnecessary assignment Assigning a value of a variable to itself is not useful. This fixes a warning shown when using clang: warning: explicitly assigning value of variable of type 'int' to itself [-Wself-assign] Signed-off-by: Stefan Agner Signed-off-by: Richard Weinberger --- fs/ubifs/scan.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c index aab87340d3de..16f03d9929e5 100644 --- a/fs/ubifs/scan.c +++ b/fs/ubifs/scan.c @@ -175,7 +175,6 @@ struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum, void ubifs_end_scan(const struct ubifs_info *c, struct ubifs_scan_leb *sleb, int lnum, int offs) { - lnum = lnum; dbg_scan("stop scanning LEB %d at offset %d", lnum, offs); ubifs_assert(offs % c->min_io_size == 0); From cc1947834827379a5fd66e8b73969fd7eaab4516 Mon Sep 17 00:00:00 2001 From: Jiang Biao Date: Wed, 28 Feb 2018 10:13:57 +0800 Subject: [PATCH 5/7] ubifs: Constify struct ubifs_lprops in scan_for_leb_for_idx Constify struct ubifs_lprops in scan_for_leb_for_idx to be consistent with other references. Signed-off-by: Jiang Biao Signed-off-by: Richard Weinberger --- fs/ubifs/find.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c index 2dcf3d473fec..9571616b5dda 100644 --- a/fs/ubifs/find.c +++ b/fs/ubifs/find.c @@ -632,7 +632,7 @@ static int scan_for_idx_cb(struct ubifs_info *c, */ static const struct ubifs_lprops *scan_for_leb_for_idx(struct ubifs_info *c) { - struct ubifs_lprops *lprops; + const struct ubifs_lprops *lprops; struct scan_data data; int err; From 4fb1cd82302e2aa87bb4876d67f3ed679f1f4a04 Mon Sep 17 00:00:00 2001 From: Jiang Biao Date: Wed, 28 Feb 2018 10:22:37 +0800 Subject: [PATCH 6/7] ubifs: Remove useless parameter of lpt_heap_replace The parameter *old_lprops* is never used in lpt_heap_replace(), remove it to avoid compile warning. Signed-off-by: Jiang Biao Signed-off-by: Richard Weinberger --- fs/ubifs/lprops.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c index 6c3a1abd0e22..f5a46844340c 100644 --- a/fs/ubifs/lprops.c +++ b/fs/ubifs/lprops.c @@ -244,7 +244,6 @@ static void remove_from_lpt_heap(struct ubifs_info *c, /** * lpt_heap_replace - replace lprops in a category heap. * @c: UBIFS file-system description object - * @old_lprops: LEB properties to replace * @new_lprops: LEB properties with which to replace * @cat: LEB category * @@ -254,7 +253,6 @@ static void remove_from_lpt_heap(struct ubifs_info *c, * lprops. This function does that. */ static void lpt_heap_replace(struct ubifs_info *c, - struct ubifs_lprops *old_lprops, struct ubifs_lprops *new_lprops, int cat) { struct ubifs_lpt_heap *heap; @@ -362,7 +360,7 @@ void ubifs_replace_cat(struct ubifs_info *c, struct ubifs_lprops *old_lprops, case LPROPS_DIRTY: case LPROPS_DIRTY_IDX: case LPROPS_FREE: - lpt_heap_replace(c, old_lprops, new_lprops, cat); + lpt_heap_replace(c, new_lprops, cat); break; case LPROPS_UNCAT: case LPROPS_EMPTY: From b5094b7f135be34630e3ea8a98fa215715d0f29d Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Sat, 3 Mar 2018 11:45:54 +0100 Subject: [PATCH 7/7] ubi: Reject MLC NAND While UBI and UBIFS seem to work at first sight with MLC NAND, you will most likely lose all your data upon a power-cut or due to read/write disturb. In order to protect users from bad surprises, refuse to attach to MLC NAND. Cc: stable@vger.kernel.org Signed-off-by: Richard Weinberger Acked-by: Boris Brezillon Acked-by: Artem Bityutskiy --- drivers/mtd/ubi/build.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index e941395de3ae..753494e042d5 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -854,6 +854,17 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, return -EINVAL; } + /* + * Both UBI and UBIFS have been designed for SLC NAND and NOR flashes. + * MLC NAND is different and needs special care, otherwise UBI or UBIFS + * will die soon and you will lose all your data. + */ + if (mtd->type == MTD_MLCNANDFLASH) { + pr_err("ubi: refuse attaching mtd%d - MLC NAND is not supported\n", + mtd->index); + return -EINVAL; + } + if (ubi_num == UBI_DEV_NUM_AUTO) { /* Search for an empty slot in the @ubi_devices array */ for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++)