diff options
author | Krzysztof Kozlowski <k.kozlowski@samsung.com> | 2015-05-28 09:53:29 +0900 |
---|---|---|
committer | Seung-Woo Kim <sw0312.kim@samsung.com> | 2016-12-14 13:45:22 +0900 |
commit | 8b24baa8ceb55c92d14029f7ebabbc6740ca7052 (patch) | |
tree | 88f1713f80788e629b850b43ac7587496b4132f3 | |
parent | d11e68d30775a40c367b6b5c34981db7c841c1e1 (diff) |
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] [<c02bc1ac>] (__list_add) from [<c0667a54>] (mutex_lock_nested+0x138/0x474)
[ 40.194395] [<c0667a54>] (mutex_lock_nested) from [<c00465e0>] (freeze_workqueues_begin+0xec/0x260)
[ 40.203421] [<c00465e0>] (freeze_workqueues_begin) from [<c0086690>] (try_to_freeze_tasks+0x2a4/0x474)
[ 40.212706] [<c0086690>] (try_to_freeze_tasks) from [<c0087148>] (freeze_kernel_threads+0x20/0x90)
[ 40.221645] [<c0087148>] (freeze_kernel_threads) from [<c0089038>] (enter_state+0xa20/0xf58)
[ 40.230064] [<c0089038>] (enter_state) from [<c0089584>] (pm_suspend+0x14/0x70)
[ 40.237354] [<c0089584>] (pm_suspend) from [<c008611c>] (state_store+0x6c/0xbc)
[ 40.244649] [<c008611c>] (state_store) from [<c02a31f8>] (kobj_attr_store+0x14/0x20)
[ 40.252376] [<c02a31f8>] (kobj_attr_store) from [<c01c50e0>] (sysfs_kf_write+0x4c/0x50)
[ 40.260359] [<c01c50e0>] (sysfs_kf_write) from [<c01c44c4>] (kernfs_fop_write+0xbc/0x198)
[ 40.268519] [<c01c44c4>] (kernfs_fop_write) from [<c0158a54>] (vfs_write+0xa0/0x1a8)
[ 40.276244] [<c0158a54>] (vfs_write) from [<c0158d74>] (SyS_write+0x40/0x8c)
[ 40.283276] [<c0158d74>] (SyS_write) from [<c000f220>] (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 <k.kozlowski@samsung.com>
-rw-r--r-- | sound/soc/codecs/ymu831/ymu831.c | 2 |
1 files changed, 1 insertions, 1 deletions
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 |