linux/drivers/of
Srinivas Kandagatla b8821ec4aa of: platform: stop accessing invalid dev in of_platform_device_destroy
commit 522811e944 upstream.

Immediately after the platform_device_unregister() the device will be
cleaned up. Accessing the freed pointer immediately after that will
crash the system.

Found this bug when kernel is built with CONFIG_PAGE_POISONING and testing
loading/unloading audio drivers in a loop on Qcom platforms.

Fix this by moving of_node_clear_flag() just before the unregister calls.

Below is the crash trace:

Unable to handle kernel paging request at virtual address 6b6b6b6b6b6c03
Mem abort info:
  ESR = 0x96000021
  Exception class = DABT (current EL), IL = 32 bits
  SET = 0, FnV = 0
  EA = 0, S1PTW = 0
Data abort info:
  ISV = 0, ISS = 0x00000021
  CM = 0, WnR = 0
[006b6b6b6b6b6c03] address between user and kernel address ranges
Internal error: Oops: 96000021 [#1] PREEMPT SMP
Modules linked in:
CPU: 2 PID: 1784 Comm: sh Tainted: G        W         4.17.0-rc7-02230-ge3a63a7ef641-dirty #204
Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT)
pstate: 80000005 (Nzcv daif -PAN -UAO)
pc : clear_bit+0x18/0x2c
lr : of_platform_device_destroy+0x64/0xb8
sp : ffff00000c9c3930
x29: ffff00000c9c3930 x28: ffff80003d39b200
x27: ffff000008bb1000 x26: 0000000000000040
x25: 0000000000000124 x24: ffff80003a9a3080
x23: 0000000000000060 x22: ffff00000939f518
x21: ffff80003aa79e98 x20: ffff80003aa3dae0
x19: ffff80003aa3c890 x18: ffff800009feb794
x17: 0000000000000000 x16: 0000000000000000
x15: ffff800009feb790 x14: 0000000000000000
x13: ffff80003a058778 x12: ffff80003a058728
x11: ffff80003a058750 x10: 0000000000000000
x9 : 0000000000000006 x8 : ffff80003a825988
x7 : bbbbbbbbbbbbbbbb x6 : 0000000000000001
x5 : 0000000000000000 x4 : 0000000000000001
x3 : 0000000000000008 x2 : 0000000000000001
x1 : 6b6b6b6b6b6b6c03 x0 : 0000000000000000
Process sh (pid: 1784, stack limit = 0x        (ptrval))
Call trace:
 clear_bit+0x18/0x2c
 q6afe_remove+0x20/0x38
 apr_device_remove+0x30/0x70
 device_release_driver_internal+0x170/0x208
 device_release_driver+0x14/0x20
 bus_remove_device+0xcc/0x150
 device_del+0x10c/0x310
 device_unregister+0x1c/0x70
 apr_remove_device+0xc/0x18
 device_for_each_child+0x50/0x80
 apr_remove+0x18/0x20
 rpmsg_dev_remove+0x38/0x68
 device_release_driver_internal+0x170/0x208
 device_release_driver+0x14/0x20
 bus_remove_device+0xcc/0x150
 device_del+0x10c/0x310
 device_unregister+0x1c/0x70
 qcom_smd_remove_device+0xc/0x18
 device_for_each_child+0x50/0x80
 qcom_smd_unregister_edge+0x3c/0x70
 smd_subdev_remove+0x18/0x28
 rproc_stop+0x48/0xd8
 rproc_shutdown+0x60/0xe8
 state_store+0xbc/0xf8
 dev_attr_store+0x18/0x28
 sysfs_kf_write+0x3c/0x50
 kernfs_fop_write+0x118/0x1e0
 __vfs_write+0x18/0x110
 vfs_write+0xa4/0x1a8
 ksys_write+0x48/0xb0
 sys_write+0xc/0x18
 el0_svc_naked+0x30/0x34
Code: d2800022 8b400c21 f9800031 9ac32043 (c85f7c22)
---[ end trace 32020935775616a2 ]---

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Rob Herring <robh@kernel.org>
[bwh: Backported to 3.16: There's no OF_POPULATED_BUS flag]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
History 2018-11-20 18:05:09 +00:00
..
testcase-data of: Fix overflow bug in string property parsing functions 2014-11-14 15:19:58 +00:00
address.c of: fix sparse warning in of_pci_range_parser_one 2017-08-26 02:14:46 +01:00
base.c of: return NUMA_NO_NODE from fallback of_node_to_nid() 2015-07-15 10:01:25 +01:00
device.c of: device: Export of_device_{get_modalias, uvent_modalias} to modules 2017-11-11 13:32:58 +00:00
fdt.c of: fdt: Fix return with value in void function 2018-03-03 15:52:29 +00:00
fdt_address.c of/fdt: add FDT address translation support 2014-05-20 15:19:25 -05:00
irq.c of: irq: fix of_irq_get[_byname]() kernel-doc 2016-08-22 22:38:08 +01:00
Kconfig of/fdt: Convert FDT functions to use libfdt 2014-04-30 00:59:15 -05:00
Makefile of/fdt: add FDT address translation support 2014-05-20 15:19:25 -05:00
of_mdio.c of_mdio: fix node leak in of_phy_register_fixed_link error path 2017-02-23 03:54:37 +00:00
of_mtd.c of_mtd: Add helpers to get ECC strength and ECC step size 2014-03-10 22:42:28 -07:00
of_net.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2014-04-02 20:53:45 -07:00
of_pci.c of: implement pci_address_to_pio as weak function 2013-10-09 20:04:06 -05:00
of_pci_irq.c of_pci_irq: kill useless variable in of_irq_parse_pci() 2014-05-27 12:13:34 +01:00
of_private.h of: Output devicetree alias names in uevent 2013-02-06 11:06:35 +00:00
of_reserved_mem.c of: alloc anywhere from memblock if range not specified 2016-05-01 00:05:53 +02:00
pdt.c of: device_node kobject lifecycle fixes 2014-03-19 14:58:40 +00:00
platform.c of: platform: stop accessing invalid dev in of_platform_device_destroy 2018-11-20 18:05:09 +00:00
selftest.c of: unittest: for strings, account for trailing \0 in property length field 2018-11-20 18:05:00 +00:00