ASoC: pcm: Fix possible buffer overflow in dpcm state sysfs output

dpcm_show_state() invokes multiple snprintf() calls to concatenate
formatted strings on the fixed size buffer.  The usage of snprintf()
is supposed for avoiding the buffer overflow, but it doesn't work as
expected because snprintf() doesn't return the actual output size but
the size to be written.

Fix this bug by replacing all snprintf() calls with scnprintf()
calls.

Fixes: f86dcef87b ("ASoC: dpcm: Add debugFS support for DPCM")
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Acked-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20200218111737.14193-4-tiwai@suse.de
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Takashi Iwai 2020-02-18 12:17:37 +01:00 committed by Mark Brown
parent 549cd0ba04
commit 6c89ffea60
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0

View file

@ -3171,16 +3171,16 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe,
unsigned long flags; unsigned long flags;
/* FE state */ /* FE state */
offset += snprintf(buf + offset, size - offset, offset += scnprintf(buf + offset, size - offset,
"[%s - %s]\n", fe->dai_link->name, "[%s - %s]\n", fe->dai_link->name,
stream ? "Capture" : "Playback"); stream ? "Capture" : "Playback");
offset += snprintf(buf + offset, size - offset, "State: %s\n", offset += scnprintf(buf + offset, size - offset, "State: %s\n",
dpcm_state_string(fe->dpcm[stream].state)); dpcm_state_string(fe->dpcm[stream].state));
if ((fe->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) && if ((fe->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) &&
(fe->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP)) (fe->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP))
offset += snprintf(buf + offset, size - offset, offset += scnprintf(buf + offset, size - offset,
"Hardware Params: " "Hardware Params: "
"Format = %s, Channels = %d, Rate = %d\n", "Format = %s, Channels = %d, Rate = %d\n",
snd_pcm_format_name(params_format(params)), snd_pcm_format_name(params_format(params)),
@ -3188,10 +3188,10 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe,
params_rate(params)); params_rate(params));
/* BEs state */ /* BEs state */
offset += snprintf(buf + offset, size - offset, "Backends:\n"); offset += scnprintf(buf + offset, size - offset, "Backends:\n");
if (list_empty(&fe->dpcm[stream].be_clients)) { if (list_empty(&fe->dpcm[stream].be_clients)) {
offset += snprintf(buf + offset, size - offset, offset += scnprintf(buf + offset, size - offset,
" No active DSP links\n"); " No active DSP links\n");
goto out; goto out;
} }
@ -3201,16 +3201,16 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe,
struct snd_soc_pcm_runtime *be = dpcm->be; struct snd_soc_pcm_runtime *be = dpcm->be;
params = &dpcm->hw_params; params = &dpcm->hw_params;
offset += snprintf(buf + offset, size - offset, offset += scnprintf(buf + offset, size - offset,
"- %s\n", be->dai_link->name); "- %s\n", be->dai_link->name);
offset += snprintf(buf + offset, size - offset, offset += scnprintf(buf + offset, size - offset,
" State: %s\n", " State: %s\n",
dpcm_state_string(be->dpcm[stream].state)); dpcm_state_string(be->dpcm[stream].state));
if ((be->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) && if ((be->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) &&
(be->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP)) (be->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP))
offset += snprintf(buf + offset, size - offset, offset += scnprintf(buf + offset, size - offset,
" Hardware Params: " " Hardware Params: "
"Format = %s, Channels = %d, Rate = %d\n", "Format = %s, Channels = %d, Rate = %d\n",
snd_pcm_format_name(params_format(params)), snd_pcm_format_name(params_format(params)),