From 8b24baa8ceb55c92d14029f7ebabbc6740ca7052 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 28 May 2015 09:53:29 +0900 Subject: ASoC: ymu831: Fix memory corruption by exceeding too small reg_cache The driver allocated reg_cache of word size int16 but accessed it by integers. So allocated memory was (MC_ASOC_N_REG * sizeof(int16)) but referenced (read and write) was (MC_ASOC_N_REG * sizeof(int)). This lead to memory corruption of kernel and multiple NULL pointer exceptions in different places. One common NULL pointer caused by this was during freezing workqueues in suspend to RAM: [ 39.782297] PM: Preparing system for mem sleep [ 39.783612] Freezing user space processes ... (elapsed 0.004 seconds) done. [ 39.791994] Freezing remaining freezable tasks ... [ 39.917890] freeze_workqueues_begin: WQ: Freeze mkdeten db2fa200 [ 39.924005] freeze_workqueues_begin:4752 db2fa400 [ 39.928575] freeze_workqueues_begin: WQ: Freeze mb4 db2fa400 [ 39.934307] Unable to handle kernel NULL pointer dereference at virtual address 00000001 ... [ 40.186412] [] (__list_add) from [] (mutex_lock_nested+0x138/0x474) [ 40.194395] [] (mutex_lock_nested) from [] (freeze_workqueues_begin+0xec/0x260) [ 40.203421] [] (freeze_workqueues_begin) from [] (try_to_freeze_tasks+0x2a4/0x474) [ 40.212706] [] (try_to_freeze_tasks) from [] (freeze_kernel_threads+0x20/0x90) [ 40.221645] [] (freeze_kernel_threads) from [] (enter_state+0xa20/0xf58) [ 40.230064] [] (enter_state) from [] (pm_suspend+0x14/0x70) [ 40.237354] [] (pm_suspend) from [] (state_store+0x6c/0xbc) [ 40.244649] [] (state_store) from [] (kobj_attr_store+0x14/0x20) [ 40.252376] [] (kobj_attr_store) from [] (sysfs_kf_write+0x4c/0x50) [ 40.260359] [] (sysfs_kf_write) from [] (kernfs_fop_write+0xbc/0x198) [ 40.268519] [] (kernfs_fop_write) from [] (vfs_write+0xa0/0x1a8) [ 40.276244] [] (vfs_write) from [] (SyS_write+0x40/0x8c) [ 40.283276] [] (SyS_write) from [] (ret_fast_syscall+0x0/0x58) [ 40.290823] Code: e1a05001 e1a04000 e1530001 1a00000b (e5953000) Switch to sizeof(int) as size of reg_cache word because the that is the internal driver representation. Signed-off-by: Krzysztof Kozlowski --- sound/soc/codecs/ymu831/ymu831.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/ymu831/ymu831.c b/sound/soc/codecs/ymu831/ymu831.c index acc913b3ee74..49bcf8721312 100644 --- a/sound/soc/codecs/ymu831/ymu831.c +++ b/sound/soc/codecs/ymu831/ymu831.c @@ -9360,7 +9360,7 @@ struct snd_soc_codec_driver mc_asoc_codec_dev = { .read = mc_asoc_read_reg, .write = mc_asoc_write_reg, .reg_cache_size = MC_ASOC_N_REG, - .reg_word_size = sizeof(u16), + .reg_word_size = sizeof(int), .reg_cache_step = 1, .idle_bias_off = true, .set_bias_level = mc_asoc_set_bias_level -- cgit v1.2.3