From: Greg Kroah-Hartman Date: Thu, 29 Nov 2018 08:13:20 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.19.6~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6ea270a107f2f68f82184ab5a89509c65366bafb;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: mtd-rawnand-atmel-fix-of-child-node-lookup.patch ubi-fastmap-check-each-mapping-only-once.patch --- diff --git a/queue-4.14/mtd-rawnand-atmel-fix-of-child-node-lookup.patch b/queue-4.14/mtd-rawnand-atmel-fix-of-child-node-lookup.patch new file mode 100644 index 00000000000..fdc80730d29 --- /dev/null +++ b/queue-4.14/mtd-rawnand-atmel-fix-of-child-node-lookup.patch @@ -0,0 +1,67 @@ +From 5d1e9c2212ea6b4dd735e4fc3dd6279a365d5d10 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 27 Aug 2018 10:21:49 +0200 +Subject: mtd: rawnand: atmel: fix OF child-node lookup + +From: Johan Hovold + +commit 5d1e9c2212ea6b4dd735e4fc3dd6279a365d5d10 upstream. + +Use the new of_get_compatible_child() helper to lookup the nfc child +node instead of using of_find_compatible_node(), which searches the +entire tree from a given start node and thus can return an unrelated +(i.e. non-child) node. + +This also addresses a potential use-after-free (e.g. after probe +deferral) as the tree-wide helper drops a reference to its first +argument (i.e. the node of the device being probed). + +While at it, also fix a related nfc-node reference leak. + +Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver") +Cc: stable # 4.11 +Cc: Nicolas Ferre +Cc: Josh Wu +Cc: Boris Brezillon +Signed-off-by: Johan Hovold +Signed-off-by: Boris Brezillon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/mtd/nand/atmel/nand-controller.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/mtd/nand/atmel/nand-controller.c ++++ b/drivers/mtd/nand/atmel/nand-controller.c +@@ -2077,8 +2077,7 @@ atmel_hsmc_nand_controller_legacy_init(s + int ret; + + nand_np = dev->of_node; +- nfc_np = of_find_compatible_node(dev->of_node, NULL, +- "atmel,sama5d3-nfc"); ++ nfc_np = of_get_compatible_child(dev->of_node, "atmel,sama5d3-nfc"); + if (!nfc_np) { + dev_err(dev, "Could not find device node for sama5d3-nfc\n"); + return -ENODEV; +@@ -2492,15 +2491,19 @@ static int atmel_nand_controller_probe(s + } + + if (caps->legacy_of_bindings) { ++ struct device_node *nfc_node; + u32 ale_offs = 21; + + /* + * If we are parsing legacy DT props and the DT contains a + * valid NFC node, forward the request to the sama5 logic. + */ +- if (of_find_compatible_node(pdev->dev.of_node, NULL, +- "atmel,sama5d3-nfc")) ++ nfc_node = of_get_compatible_child(pdev->dev.of_node, ++ "atmel,sama5d3-nfc"); ++ if (nfc_node) { + caps = &atmel_sama5_nand_caps; ++ of_node_put(nfc_node); ++ } + + /* + * Even if the compatible says we are dealing with an diff --git a/queue-4.14/series b/queue-4.14/series index a6bcd28455c..f6408ec4fd8 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -72,3 +72,5 @@ power-supply-twl4030-charger-fix-of-sibling-node-loo.patch arm64-remove-no-op-p-linker-flag.patch xhci-allow-more-than-32-quirks.patch xhci-add-quirk-to-workaround-the-errata-seen-on-cavium-thunder-x2-soc.patch +mtd-rawnand-atmel-fix-of-child-node-lookup.patch +ubi-fastmap-check-each-mapping-only-once.patch diff --git a/queue-4.14/ubi-fastmap-check-each-mapping-only-once.patch b/queue-4.14/ubi-fastmap-check-each-mapping-only-once.patch new file mode 100644 index 00000000000..3cad2f2c4c8 --- /dev/null +++ b/queue-4.14/ubi-fastmap-check-each-mapping-only-once.patch @@ -0,0 +1,177 @@ +From 34653fd8c46e771585fce5975e4243f8fd401914 Mon Sep 17 00:00:00 2001 +From: Richard Weinberger +Date: Mon, 28 May 2018 22:04:33 +0200 +Subject: ubi: fastmap: Check each mapping only once + +From: Richard Weinberger + +commit 34653fd8c46e771585fce5975e4243f8fd401914 upstream. + +Maintain a bitmap to keep track of which LEB->PEB mapping +was checked already. +That way we have to read back VID headers only once. + +Fixes: a23cf10d9abb ("ubi: fastmap: Correctly handle interrupted erasures in EBA") +Signed-off-by: Richard Weinberger +Signed-off-by: Martin Kepplinger + +--- + drivers/mtd/ubi/build.c | 1 + + drivers/mtd/ubi/eba.c | 4 ++++ + drivers/mtd/ubi/fastmap.c | 20 ++++++++++++++++++++ + drivers/mtd/ubi/ubi.h | 11 +++++++++++ + drivers/mtd/ubi/vmt.c | 1 + + drivers/mtd/ubi/vtbl.c | 16 +++++++++++++++- + 6 files changed, 52 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/ubi/build.c ++++ b/drivers/mtd/ubi/build.c +@@ -526,6 +526,7 @@ void ubi_free_internal_volumes(struct ub + for (i = ubi->vtbl_slots; + i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { + ubi_eba_replace_table(ubi->volumes[i], NULL); ++ ubi_fastmap_destroy_checkmap(ubi->volumes[i]); + kfree(ubi->volumes[i]); + } + } +--- a/drivers/mtd/ubi/eba.c ++++ b/drivers/mtd/ubi/eba.c +@@ -517,6 +517,9 @@ static int check_mapping(struct ubi_devi + if (!ubi->fast_attach) + return 0; + ++ if (!vol->checkmap || test_bit(lnum, vol->checkmap)) ++ return 0; ++ + vidb = ubi_alloc_vid_buf(ubi, GFP_NOFS); + if (!vidb) + return -ENOMEM; +@@ -551,6 +554,7 @@ static int check_mapping(struct ubi_devi + goto out_free; + } + ++ set_bit(lnum, vol->checkmap); + err = 0; + + out_free: +--- a/drivers/mtd/ubi/fastmap.c ++++ b/drivers/mtd/ubi/fastmap.c +@@ -1101,6 +1101,26 @@ free_fm_sb: + goto out; + } + ++int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count) ++{ ++ struct ubi_device *ubi = vol->ubi; ++ ++ if (!ubi->fast_attach) ++ return 0; ++ ++ vol->checkmap = kcalloc(BITS_TO_LONGS(leb_count), sizeof(unsigned long), ++ GFP_KERNEL); ++ if (!vol->checkmap) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol) ++{ ++ kfree(vol->checkmap); ++} ++ + /** + * ubi_write_fastmap - writes a fastmap. + * @ubi: UBI device object +--- a/drivers/mtd/ubi/ubi.h ++++ b/drivers/mtd/ubi/ubi.h +@@ -334,6 +334,9 @@ struct ubi_eba_leb_desc { + * @changing_leb: %1 if the atomic LEB change ioctl command is in progress + * @direct_writes: %1 if direct writes are enabled for this volume + * ++ * @checkmap: bitmap to remember which PEB->LEB mappings got checked, ++ * protected by UBI LEB lock tree. ++ * + * The @corrupted field indicates that the volume's contents is corrupted. + * Since UBI protects only static volumes, this field is not relevant to + * dynamic volumes - it is user's responsibility to assure their data +@@ -377,6 +380,10 @@ struct ubi_volume { + unsigned int updating:1; + unsigned int changing_leb:1; + unsigned int direct_writes:1; ++ ++#ifdef CONFIG_MTD_UBI_FASTMAP ++ unsigned long *checkmap; ++#endif + }; + + /** +@@ -965,8 +972,12 @@ size_t ubi_calc_fm_size(struct ubi_devic + int ubi_update_fastmap(struct ubi_device *ubi); + int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, + struct ubi_attach_info *scan_ai); ++int ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count); ++void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol); + #else + static inline int ubi_update_fastmap(struct ubi_device *ubi) { return 0; } ++int static inline ubi_fastmap_init_checkmap(struct ubi_volume *vol, int leb_count) { return 0; } ++static inline void ubi_fastmap_destroy_checkmap(struct ubi_volume *vol) {} + #endif + + /* block.c */ +--- a/drivers/mtd/ubi/vmt.c ++++ b/drivers/mtd/ubi/vmt.c +@@ -139,6 +139,7 @@ static void vol_release(struct device *d + struct ubi_volume *vol = container_of(dev, struct ubi_volume, dev); + + ubi_eba_replace_table(vol, NULL); ++ ubi_fastmap_destroy_checkmap(vol); + kfree(vol); + } + +--- a/drivers/mtd/ubi/vtbl.c ++++ b/drivers/mtd/ubi/vtbl.c +@@ -534,7 +534,7 @@ static int init_volumes(struct ubi_devic + const struct ubi_attach_info *ai, + const struct ubi_vtbl_record *vtbl) + { +- int i, reserved_pebs = 0; ++ int i, err, reserved_pebs = 0; + struct ubi_ainf_volume *av; + struct ubi_volume *vol; + +@@ -620,6 +620,16 @@ static int init_volumes(struct ubi_devic + (long long)(vol->used_ebs - 1) * vol->usable_leb_size; + vol->used_bytes += av->last_data_size; + vol->last_eb_bytes = av->last_data_size; ++ ++ /* ++ * We use ubi->peb_count and not vol->reserved_pebs because ++ * we want to keep the code simple. Otherwise we'd have to ++ * resize/check the bitmap upon volume resize too. ++ * Allocating a few bytes more does not hurt. ++ */ ++ err = ubi_fastmap_init_checkmap(vol, ubi->peb_count); ++ if (err) ++ return err; + } + + /* And add the layout volume */ +@@ -645,6 +655,9 @@ static int init_volumes(struct ubi_devic + reserved_pebs += vol->reserved_pebs; + ubi->vol_count += 1; + vol->ubi = ubi; ++ err = ubi_fastmap_init_checkmap(vol, UBI_LAYOUT_VOLUME_EBS); ++ if (err) ++ return err; + + if (reserved_pebs > ubi->avail_pebs) { + ubi_err(ubi, "not enough PEBs, required %d, available %d", +@@ -849,6 +862,7 @@ int ubi_read_volume_table(struct ubi_dev + out_free: + vfree(ubi->vtbl); + for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { ++ ubi_fastmap_destroy_checkmap(ubi->volumes[i]); + kfree(ubi->volumes[i]); + ubi->volumes[i] = NULL; + }