From: Greg Kroah-Hartman Date: Sat, 30 Mar 2019 09:58:41 +0000 (+0100) Subject: 3.18-stable patches X-Git-Tag: v3.18.138~54 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=48a95e3144ce1d32859b6d87152a2d8a0718ab4c;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: alsa-pcm-don-t-suspend-stream-in-unrecoverable-pcm-state.patch alsa-pcm-fix-possible-oob-access-in-pcm-oss-plugins.patch --- diff --git a/queue-3.18/alsa-pcm-don-t-suspend-stream-in-unrecoverable-pcm-state.patch b/queue-3.18/alsa-pcm-don-t-suspend-stream-in-unrecoverable-pcm-state.patch new file mode 100644 index 00000000000..29c55f58859 --- /dev/null +++ b/queue-3.18/alsa-pcm-don-t-suspend-stream-in-unrecoverable-pcm-state.patch @@ -0,0 +1,70 @@ +From 113ce08109f8e3b091399e7cc32486df1cff48e7 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 25 Mar 2019 10:38:58 +0100 +Subject: ALSA: pcm: Don't suspend stream in unrecoverable PCM state + +From: Takashi Iwai + +commit 113ce08109f8e3b091399e7cc32486df1cff48e7 upstream. + +Currently PCM core sets each opened stream forcibly to SUSPENDED state +via snd_pcm_suspend_all() call, and the user-space is responsible for +re-triggering the resume manually either via snd_pcm_resume() or +prepare call. The scheme works fine usually, but there are corner +cases where the stream can't be resumed by that call: the streams +still in OPEN state before finishing hw_params. When they are +suspended, user-space cannot perform resume or prepare because they +haven't been set up yet. The only possible recovery is to re-open the +device, which isn't nice at all. Similarly, when a stream is in +DISCONNECTED state, it makes no sense to change it to SUSPENDED +state. Ditto for in SETUP state; which you can re-prepare directly. + +So, this patch addresses these issues by filtering the PCM streams to +be suspended by checking the PCM state. When a stream is in either +OPEN, SETUP or DISCONNECTED as well as already SUSPENDED, the suspend +action is skipped. + +To be noted, this problem was originally reported for the PCM runtime +PM on HD-audio. And, the runtime PM problem itself was already +addressed (although not intended) by the code refactoring commits +3d21ef0b49f8 ("ALSA: pcm: Suspend streams globally via device type PM +ops") and 17bc4815de58 ("ALSA: pci: Remove superfluous +snd_pcm_suspend*() calls"). These commits eliminated the +snd_pcm_suspend*() calls from the runtime PM suspend callback code +path, hence the racy OPEN state won't appear while runtime PM. +(FWIW, the race window is between snd_pcm_open_substream() and the +first power up in azx_pcm_open().) + +Although the runtime PM issue was already "fixed", the same problem is +still present for the system PM, hence this patch is still needed. +And for stable trees, this patch alone should suffice for fixing the +runtime PM problem, too. + +Reported-and-tested-by: Jon Hunter +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/pcm_native.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/sound/core/pcm_native.c ++++ b/sound/core/pcm_native.c +@@ -1225,8 +1225,15 @@ static int snd_pcm_pause(struct snd_pcm_ + static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state) + { + struct snd_pcm_runtime *runtime = substream->runtime; +- if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) ++ switch (runtime->status->state) { ++ case SNDRV_PCM_STATE_SUSPENDED: + return -EBUSY; ++ /* unresumable PCM state; return -EBUSY for skipping suspend */ ++ case SNDRV_PCM_STATE_OPEN: ++ case SNDRV_PCM_STATE_SETUP: ++ case SNDRV_PCM_STATE_DISCONNECTED: ++ return -EBUSY; ++ } + runtime->trigger_master = substream; + return 0; + } diff --git a/queue-3.18/alsa-pcm-fix-possible-oob-access-in-pcm-oss-plugins.patch b/queue-3.18/alsa-pcm-fix-possible-oob-access-in-pcm-oss-plugins.patch new file mode 100644 index 00000000000..c6b7fbfc71b --- /dev/null +++ b/queue-3.18/alsa-pcm-fix-possible-oob-access-in-pcm-oss-plugins.patch @@ -0,0 +1,104 @@ +From ca0214ee2802dd47239a4e39fb21c5b00ef61b22 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 22 Mar 2019 16:00:54 +0100 +Subject: ALSA: pcm: Fix possible OOB access in PCM oss plugins + +From: Takashi Iwai + +commit ca0214ee2802dd47239a4e39fb21c5b00ef61b22 upstream. + +The PCM OSS emulation converts and transfers the data on the fly via +"plugins". The data is converted over the dynamically allocated +buffer for each plugin, and recently syzkaller caught OOB in this +flow. + +Although the bisection by syzbot pointed out to the commit +65766ee0bf7f ("ALSA: oss: Use kvzalloc() for local buffer +allocations"), this is merely a commit to replace vmalloc() with +kvmalloc(), hence it can't be the cause. The further debug action +revealed that this happens in the case where a slave PCM doesn't +support only the stereo channels while the OSS stream is set up for a +mono channel. Below is a brief explanation: + +At each OSS parameter change, the driver sets up the PCM hw_params +again in snd_pcm_oss_change_params_lock(). This is also the place +where plugins are created and local buffers are allocated. The +problem is that the plugins are created before the final hw_params is +determined. Namely, two snd_pcm_hw_param_near() calls for setting the +period size and periods may influence on the final result of channels, +rates, etc, too, while the current code has already created plugins +beforehand with the premature values. So, the plugin believes that +channels=1, while the actual I/O is with channels=2, which makes the +driver reading/writing over the allocated buffer size. + +The fix is simply to move the plugin allocation code after the final +hw_params call. + +Reported-by: syzbot+d4503ae45b65c5bc1194@syzkaller.appspotmail.com +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/oss/pcm_oss.c | 43 ++++++++++++++++++++++--------------------- + 1 file changed, 22 insertions(+), 21 deletions(-) + +--- a/sound/core/oss/pcm_oss.c ++++ b/sound/core/oss/pcm_oss.c +@@ -951,6 +951,28 @@ static int snd_pcm_oss_change_params_loc + oss_frame_size = snd_pcm_format_physical_width(params_format(params)) * + params_channels(params) / 8; + ++ err = snd_pcm_oss_period_size(substream, params, sparams); ++ if (err < 0) ++ goto failure; ++ ++ n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size); ++ err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, NULL); ++ if (err < 0) ++ goto failure; ++ ++ err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS, ++ runtime->oss.periods, NULL); ++ if (err < 0) ++ goto failure; ++ ++ snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); ++ ++ err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams); ++ if (err < 0) { ++ pcm_dbg(substream->pcm, "HW_PARAMS failed: %i\n", err); ++ goto failure; ++ } ++ + #ifdef CONFIG_SND_PCM_OSS_PLUGINS + snd_pcm_oss_plugin_clear(substream); + if (!direct) { +@@ -985,27 +1007,6 @@ static int snd_pcm_oss_change_params_loc + } + #endif + +- err = snd_pcm_oss_period_size(substream, params, sparams); +- if (err < 0) +- goto failure; +- +- n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size); +- err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, NULL); +- if (err < 0) +- goto failure; +- +- err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS, +- runtime->oss.periods, NULL); +- if (err < 0) +- goto failure; +- +- snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); +- +- if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams)) < 0) { +- pcm_dbg(substream->pcm, "HW_PARAMS failed: %i\n", err); +- goto failure; +- } +- + if (runtime->oss.trigger) { + sw_params->start_threshold = 1; + } else { diff --git a/queue-3.18/series b/queue-3.18/series index c85633a813d..537cd1d23dd 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -34,3 +34,5 @@ packets-always-register-packet-sk-in-the-same-order.patch tcp-do-not-use-ipv6-header-for-ipv4-flow.patch sctp-get-sctphdr-by-offset-in-sctp_compute_cksum.patch mac8390-fix-mmio-access-size-probe.patch +alsa-pcm-fix-possible-oob-access-in-pcm-oss-plugins.patch +alsa-pcm-don-t-suspend-stream-in-unrecoverable-pcm-state.patch