aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorRichard Fitzgerald <rf@opensource.cirrus.com>2018-02-28 10:31:10 +0000
committerMark Brown <broonie@kernel.org>2018-02-28 10:38:40 +0000
commitd7789f5bcdb298c4a302db471b1b20f74a20de95 (patch)
tree05bcdd40337a46b08de19b4cccd026b035aab526 /sound
parentLinux 4.16-rc1 (diff)
downloadlinux-dev-d7789f5bcdb298c4a302db471b1b20f74a20de95.tar.xz
linux-dev-d7789f5bcdb298c4a302db471b1b20f74a20de95.zip
ASoC: wm_adsp: For TLV controls only register TLV get/set
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
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/wm_adsp.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 66e32f5d2917..989d093abda7 100644
--- 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 *dsp, struct wm_coeff_ctl *ctl)
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;
}