From d9fdb9fba7ec08769594abede8f78523ed3f025a Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 1 Sep 2014 18:07:38 +0100 Subject: imx-drm: imx-ldb: fix NULL pointer in imx_ldb_unbind() When trying to unbind imx-drm, the following oops was observed from the imx-ldb driver: Unable to handle kernel NULL pointer dereference at virtual address 0000001c pgd = de954000 [0000001c] *pgd=2e92c831, *pte=00000000, *ppte=00000000 Internal error: Oops: 17 [#1] SMP ARM Modules linked in: bnep rfcomm bluetooth nfsd exportfs hid_cypress brcmfmac brcmutil snd_soc_fsl_ssi snd_soc_fsl_spdif imx_pcm_fiq imx_pcm_dma imx_ldb(C) imx_thermal imx_sdma imx2_wdt snd_soc_sgtl5000 snd_soc_imx_sgtl5000 snd_soc_imx_spdif snd_soc_imx_audmux CPU: 1 PID: 1228 Comm: bash Tainted: G C 3.16.0-rc2+ #1229 task: ea378d80 ti: de948000 task.ti: de948000 PC is at imx_ldb_unbind+0x1c/0x58 [imx_ldb] LR is at component_unbind+0x38/0x70 pc : [] lr : [] psr: 200f0013 sp : de949da8 ip : de949dc0 fp : de949dbc r10: e9a44b0c r9 : 00000000 r8 : de949f78 r7 : 00000012 r6 : e9b3f400 r5 : e9b133b8 r4 : e9b13010 r3 : 00000000 r2 : e9b3f400 r1 : ea9a0210 r0 : e9b13020 Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user Control: 10c53c7d Table: 2e95404a DAC: 00000015 Process bash (pid: 1228, stack limit = 0xde948240) Stack: (0xde949da8 to 0xde94a000) ... Backtrace: [] (imx_ldb_unbind [imx_ldb]) from [] (component_unbind+0x38/0x70) [] (component_unbind) from [] (component_unbind_all+0x94/0xc8) [] (component_unbind_all) from [] (imx_drm_driver_unload+0x34/0x4c) [] (imx_drm_driver_unload) from [] (drm_dev_unregister+0x2c/0xa0) [] (drm_dev_unregister) from [] (drm_put_dev+0x30/0x6c) [] (drm_put_dev) from [] (imx_drm_unbind+0x14/0x18) [] (imx_drm_unbind) from [] (component_master_del+0xbc/0xd8) ... Code: e5904058 e2840010 e2845fea e59430a0 (e593301c) ---[ end trace 4f211c6dbbcd4963 ]--- This is caused by only having one channel out of the pair configured in DT; the second channel remains uninitialised, but upon unbind, the driver attempts to clean up both, thereby dereferencing a NULL pointer. Avoid this by checking that the second channel is initialised. Fixes: 1b3f76756633 ("imx-drm: initialise drm components directly") Cc: Signed-off-by: Russell King Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/imx-ldb.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index 7e3f019d7e72..4662e00b456a 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -574,6 +574,9 @@ static void imx_ldb_unbind(struct device *dev, struct device *master, for (i = 0; i < 2; i++) { struct imx_ldb_channel *channel = &imx_ldb->channel[i]; + if (!channel->connector.funcs) + continue; + channel->connector.funcs->destroy(&channel->connector); channel->encoder.funcs->destroy(&channel->encoder); } -- cgit v1.2.3