diff options
author | Bitan Biswas <bbiswas@nvidia.com> | 2020-01-09 13:40:17 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-01-10 15:52:13 +0300 |
commit | 16bb7abc4a6b9defffa294e4dc28383e62a1dbcf (patch) | |
tree | 51030b3853dffcda02f00974ea4167cea8293e8c /drivers/nvmem | |
parent | 226c512699ee047b7fae0df297ea0be9e2b629c5 (diff) | |
download | linux-16bb7abc4a6b9defffa294e4dc28383e62a1dbcf.tar.xz |
nvmem: core: fix memory abort in cleanup path
nvmem_cell_info_to_nvmem_cell implementation has static
allocation of name. nvmem_add_cells_from_of() call may
return error and kfree name results in memory abort. Use
kstrdup_const() and kfree_const calls for name alloc and free.
Unable to handle kernel paging request at virtual address ffffffffffe44888
Mem abort info:
ESR = 0x96000006
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000006
CM = 0, WnR = 0
swapper pgtable: 64k pages, 48-bit VAs, pgdp=00000000815d0000
[ffffffffffe44888] pgd=0000000081d30803, pud=0000000081d30803,
pmd=0000000000000000
Internal error: Oops: 96000006 [#1] PREEMPT SMP
Modules linked in:
CPU: 2 PID: 43 Comm: kworker/2:1 Tainted
Hardware name: quill (DT)
Workqueue: events deferred_probe_work_func
pstate: a0000005 (NzCv daif -PAN -UAO)
pc : kfree+0x38/0x278
lr : nvmem_cell_drop+0x68/0x80
sp : ffff80001284f9d0
x29: ffff80001284f9d0 x28: ffff0001f677e830
x27: ffff800011b0b000 x26: ffff0001c36e1008
x25: ffff8000112ad000 x24: ffff8000112c9000
x23: ffffffffffffffea x22: ffff800010adc7f0
x21: ffffffffffe44880 x20: ffff800011b0b068
x19: ffff80001122d380 x18: ffffffffffffffff
x17: 00000000d5cb4756 x16: 0000000070b193b8
x15: ffff8000119538c8 x14: 0720072007200720
x13: 07200720076e0772 x12: 07750762072d0765
x11: 0773077507660765 x10: 072f073007300730
x9 : 0730073207380733 x8 : 0000000000000151
x7 : 07660765072f0720 x6 : ffff0001c00e0f00
x5 : 0000000000000000 x4 : ffff0001c0b43800
x3 : ffff800011b0b068 x2 : 0000000000000000
x1 : 0000000000000000 x0 : ffffffdfffe00000
Call trace:
kfree+0x38/0x278
nvmem_cell_drop+0x68/0x80
nvmem_device_remove_all_cells+0x2c/0x50
nvmem_register.part.9+0x520/0x628
devm_nvmem_register+0x48/0xa0
tegra_fuse_probe+0x140/0x1f0
platform_drv_probe+0x50/0xa0
really_probe+0x108/0x348
driver_probe_device+0x58/0x100
__device_attach_driver+0x90/0xb0
bus_for_each_drv+0x64/0xc8
__device_attach+0xd8/0x138
device_initial_probe+0x10/0x18
bus_probe_device+0x90/0x98
deferred_probe_work_func+0x74/0xb0
process_one_work+0x1e0/0x358
worker_thread+0x208/0x488
kthread+0x118/0x120
ret_from_fork+0x10/0x18
Code: d350feb5 f2dffbe0 aa1e03f6 8b151815 (f94006a0)
---[ end trace 49b1303c6b83198e ]---
Fixes: badcdff107cbf ("nvmem: Convert to using %pOFn instead of device_node.name")
Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20200109104017.6249-5-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/nvmem')
-rw-r--r-- | drivers/nvmem/core.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 9f1ee9c766ec..1e4a798dce6e 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -83,7 +83,7 @@ static void nvmem_cell_drop(struct nvmem_cell *cell) list_del(&cell->node); mutex_unlock(&nvmem_mutex); of_node_put(cell->np); - kfree(cell->name); + kfree_const(cell->name); kfree(cell); } @@ -110,7 +110,9 @@ static int nvmem_cell_info_to_nvmem_cell(struct nvmem_device *nvmem, cell->nvmem = nvmem; cell->offset = info->offset; cell->bytes = info->bytes; - cell->name = info->name; + cell->name = kstrdup_const(info->name, GFP_KERNEL); + if (!cell->name) + return -ENOMEM; cell->bit_offset = info->bit_offset; cell->nbits = info->nbits; @@ -300,7 +302,7 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem) dev_err(dev, "cell %s unaligned to nvmem stride %d\n", cell->name, nvmem->stride); /* Cells already added will be freed later. */ - kfree(cell->name); + kfree_const(cell->name); kfree(cell); return -EINVAL; } |