| From d7789f5bcdb298c4a302db471b1b20f74a20de95 Mon Sep 17 00:00:00 2001 |
| From: Richard Fitzgerald <rf@opensource.cirrus.com> |
| Date: Wed, 28 Feb 2018 10:31:10 +0000 |
| Subject: ASoC: wm_adsp: For TLV controls only register TLV get/set |
| |
| From: Richard Fitzgerald <rf@opensource.cirrus.com> |
| |
| commit d7789f5bcdb298c4a302db471b1b20f74a20de95 upstream. |
| |
| Normal 512-byte get/set of a TLV isn't supported but we were |
| registering the normal get/set anyway and relying on omitting |
| the SNDRV_CTL_ELEM_ACCESS_[READ|WRITE] flags to prevent them |
| being called. |
| |
| Trouble is if this gets broken in the core ALSA code - as it has |
| been since at least 4.14 - the standard get/set can be called |
| unexpectedly and corrupt memory. |
| |
| There's no point providing functions that won't be called and |
| it's a trivial change. The benefit is that if the ALSA core gets |
| broken again we get a big fat immediate NULL dereference instead |
| of a memory corruption timebomb. |
| |
| Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com> |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| sound/soc/codecs/wm_adsp.c | 14 ++++++++------ |
| 1 file changed, 8 insertions(+), 6 deletions(-) |
| |
| --- a/sound/soc/codecs/wm_adsp.c |
| +++ b/sound/soc/codecs/wm_adsp.c |
| @@ -1204,12 +1204,14 @@ static int wmfw_add_ctl(struct wm_adsp * |
| kcontrol->put = wm_coeff_put_acked; |
| break; |
| default: |
| - kcontrol->get = wm_coeff_get; |
| - kcontrol->put = wm_coeff_put; |
| - |
| - ctl->bytes_ext.max = ctl->len; |
| - ctl->bytes_ext.get = wm_coeff_tlv_get; |
| - ctl->bytes_ext.put = wm_coeff_tlv_put; |
| + if (kcontrol->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { |
| + ctl->bytes_ext.max = ctl->len; |
| + ctl->bytes_ext.get = wm_coeff_tlv_get; |
| + ctl->bytes_ext.put = wm_coeff_tlv_put; |
| + } else { |
| + kcontrol->get = wm_coeff_get; |
| + kcontrol->put = wm_coeff_put; |
| + } |
| break; |
| } |
| |