This is a note to let you know that I've just added the patch titled
ALSA: pcm: Allow aborting mutex lock at OSS read/write loops
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 900498a34a3ac9c611e9b425094c8106bdd7dc1c Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Mon, 8 Jan 2018 14:03:53 +0100
Subject: ALSA: pcm: Allow aborting mutex lock at OSS read/write loops
From: Takashi Iwai <tiwai(a)suse.de>
commit 900498a34a3ac9c611e9b425094c8106bdd7dc1c upstream.
PCM OSS read/write loops keep taking the mutex lock for the whole
read/write, and this might take very long when the exceptionally high
amount of data is given. Also, since it invokes with mutex_lock(),
the concurrent read/write becomes unbreakable.
This patch tries to address these issues by replacing mutex_lock()
with mutex_lock_interruptible(), and also splits / re-takes the lock
at each read/write period chunk, so that it can switch the context
more finely if requested.
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_oss.c | 36 +++++++++++++++++++++---------------
1 file changed, 21 insertions(+), 15 deletions(-)
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1334,8 +1334,11 @@ static ssize_t snd_pcm_oss_write1(struct
if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
return tmp;
- mutex_lock(&runtime->oss.params_lock);
while (bytes > 0) {
+ if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
+ tmp = -ERESTARTSYS;
+ break;
+ }
if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
tmp = bytes;
if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
@@ -1379,18 +1382,18 @@ static ssize_t snd_pcm_oss_write1(struct
xfer += tmp;
if ((substream->f_flags & O_NONBLOCK) != 0 &&
tmp != runtime->oss.period_bytes)
- break;
+ tmp = -EAGAIN;
}
+ err:
+ mutex_unlock(&runtime->oss.params_lock);
+ if (tmp < 0)
+ break;
if (signal_pending(current)) {
tmp = -ERESTARTSYS;
- goto err;
+ break;
}
+ tmp = 0;
}
- mutex_unlock(&runtime->oss.params_lock);
- return xfer;
-
- err:
- mutex_unlock(&runtime->oss.params_lock);
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
}
@@ -1438,8 +1441,11 @@ static ssize_t snd_pcm_oss_read1(struct
if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
return tmp;
- mutex_lock(&runtime->oss.params_lock);
while (bytes > 0) {
+ if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
+ tmp = -ERESTARTSYS;
+ break;
+ }
if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
if (runtime->oss.buffer_used == 0) {
tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
@@ -1470,16 +1476,16 @@ static ssize_t snd_pcm_oss_read1(struct
bytes -= tmp;
xfer += tmp;
}
+ err:
+ mutex_unlock(&runtime->oss.params_lock);
+ if (tmp < 0)
+ break;
if (signal_pending(current)) {
tmp = -ERESTARTSYS;
- goto err;
+ break;
}
+ tmp = 0;
}
- mutex_unlock(&runtime->oss.params_lock);
- return xfer;
-
- err:
- mutex_unlock(&runtime->oss.params_lock);
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
}
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.14/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.14/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.14/alsa-pcm-workaround-for-weird-pulseaudio-behavior-on-rewind-error.patch
queue-4.14/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.14/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.14/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.14/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.14/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: aloop: Release cable upon open error path
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-aloop-release-cable-upon-open-error-path.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 9685347aa0a5c2869058ca6ab79fd8e93084a67f Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Fri, 5 Jan 2018 16:09:47 +0100
Subject: ALSA: aloop: Release cable upon open error path
From: Takashi Iwai <tiwai(a)suse.de>
commit 9685347aa0a5c2869058ca6ab79fd8e93084a67f upstream.
The aloop runtime object and its assignment in the cable are left even
when opening a substream fails. This doesn't mean any memory leak,
but it still keeps the invalid pointer that may be referred by the
another side of the cable spontaneously, which is a potential Oops
cause.
Clean up the cable assignment and the empty cable upon the error path
properly.
Fixes: 597603d615d2 ("ALSA: introduce the snd-aloop module for the PCM loopback")
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/drivers/aloop.c | 38 +++++++++++++++++++++++++-------------
1 file changed, 25 insertions(+), 13 deletions(-)
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -658,12 +658,31 @@ static int rule_channels(struct snd_pcm_
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
}
+static void free_cable(struct snd_pcm_substream *substream)
+{
+ struct loopback *loopback = substream->private_data;
+ int dev = get_cable_index(substream);
+ struct loopback_cable *cable;
+
+ cable = loopback->cables[substream->number][dev];
+ if (!cable)
+ return;
+ if (cable->streams[!substream->stream]) {
+ /* other stream is still alive */
+ cable->streams[substream->stream] = NULL;
+ } else {
+ /* free the cable */
+ loopback->cables[substream->number][dev] = NULL;
+ kfree(cable);
+ }
+}
+
static int loopback_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct loopback *loopback = substream->private_data;
struct loopback_pcm *dpcm;
- struct loopback_cable *cable;
+ struct loopback_cable *cable = NULL;
int err = 0;
int dev = get_cable_index(substream);
@@ -682,7 +701,6 @@ static int loopback_open(struct snd_pcm_
if (!cable) {
cable = kzalloc(sizeof(*cable), GFP_KERNEL);
if (!cable) {
- kfree(dpcm);
err = -ENOMEM;
goto unlock;
}
@@ -724,6 +742,10 @@ static int loopback_open(struct snd_pcm_
else
runtime->hw = cable->hw;
unlock:
+ if (err < 0) {
+ free_cable(substream);
+ kfree(dpcm);
+ }
mutex_unlock(&loopback->cable_lock);
return err;
}
@@ -732,20 +754,10 @@ static int loopback_close(struct snd_pcm
{
struct loopback *loopback = substream->private_data;
struct loopback_pcm *dpcm = substream->runtime->private_data;
- struct loopback_cable *cable;
- int dev = get_cable_index(substream);
loopback_timer_stop(dpcm);
mutex_lock(&loopback->cable_lock);
- cable = loopback->cables[substream->number][dev];
- if (cable->streams[!substream->stream]) {
- /* other stream is still alive */
- cable->streams[substream->stream] = NULL;
- } else {
- /* free the cable */
- loopback->cables[substream->number][dev] = NULL;
- kfree(cable);
- }
+ free_cable(substream);
mutex_unlock(&loopback->cable_lock);
return 0;
}
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.14/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.14/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.14/alsa-pcm-workaround-for-weird-pulseaudio-behavior-on-rewind-error.patch
queue-4.14/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.14/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.14/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.14/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.14/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Add missing error checks in OSS emulation plugin builder
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 6708913750344a900f2e73bfe4a4d6dbbce4fe8d Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Thu, 4 Jan 2018 16:39:27 +0100
Subject: ALSA: pcm: Add missing error checks in OSS emulation plugin builder
From: Takashi Iwai <tiwai(a)suse.de>
commit 6708913750344a900f2e73bfe4a4d6dbbce4fe8d upstream.
In the OSS emulation plugin builder where the frame size is parsed in
the plugin chain, some places miss the possible errors returned from
the plugin src_ or dst_frames callback.
This patch papers over such places.
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_plugin.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -592,18 +592,26 @@ snd_pcm_sframes_t snd_pcm_plug_write_tra
snd_pcm_sframes_t frames = size;
plugin = snd_pcm_plug_first(plug);
- while (plugin && frames > 0) {
+ while (plugin) {
+ if (frames <= 0)
+ return frames;
if ((next = plugin->next) != NULL) {
snd_pcm_sframes_t frames1 = frames;
- if (plugin->dst_frames)
+ if (plugin->dst_frames) {
frames1 = plugin->dst_frames(plugin, frames);
+ if (frames1 <= 0)
+ return frames1;
+ }
if ((err = next->client_channels(next, frames1, &dst_channels)) < 0) {
return err;
}
if (err != frames1) {
frames = err;
- if (plugin->src_frames)
+ if (plugin->src_frames) {
frames = plugin->src_frames(plugin, frames1);
+ if (frames <= 0)
+ return frames;
+ }
}
} else
dst_channels = NULL;
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.14/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.14/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.14/alsa-pcm-workaround-for-weird-pulseaudio-behavior-on-rewind-error.patch
queue-4.14/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.14/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.14/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.14/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.14/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Abort properly at pending signal in OSS read/write loops
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 29159a4ed7044c52e3e2cf1a9fb55cec4745c60b Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Mon, 8 Jan 2018 13:58:31 +0100
Subject: ALSA: pcm: Abort properly at pending signal in OSS read/write loops
From: Takashi Iwai <tiwai(a)suse.de>
commit 29159a4ed7044c52e3e2cf1a9fb55cec4745c60b upstream.
The loops for read and write in PCM OSS emulation have no proper check
of pending signals, and they keep processing even after user tries to
break. This results in a very long delay, often seen as RCU stall
when a huge unprocessed bytes remain queued. The bug could be easily
triggered by syzkaller.
As a simple workaround, this patch adds the proper check of pending
signals and aborts the loop appropriately.
Reported-by: syzbot+993cb4cfcbbff3947c21(a)syzkaller.appspotmail.com
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_oss.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1381,6 +1381,10 @@ static ssize_t snd_pcm_oss_write1(struct
tmp != runtime->oss.period_bytes)
break;
}
+ if (signal_pending(current)) {
+ tmp = -ERESTARTSYS;
+ goto err;
+ }
}
mutex_unlock(&runtime->oss.params_lock);
return xfer;
@@ -1466,6 +1470,10 @@ static ssize_t snd_pcm_oss_read1(struct
bytes -= tmp;
xfer += tmp;
}
+ if (signal_pending(current)) {
+ tmp = -ERESTARTSYS;
+ goto err;
+ }
}
mutex_unlock(&runtime->oss.params_lock);
return xfer;
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.14/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.14/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.14/alsa-pcm-workaround-for-weird-pulseaudio-behavior-on-rewind-error.patch
queue-4.14/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.14/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.14/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.14/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.14/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: aloop: Fix racy hw constraints adjustment
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-aloop-fix-racy-hw-constraints-adjustment.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 898dfe4687f460ba337a01c11549f87269a13fa2 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Thu, 4 Jan 2018 17:38:54 +0100
Subject: ALSA: aloop: Fix racy hw constraints adjustment
From: Takashi Iwai <tiwai(a)suse.de>
commit 898dfe4687f460ba337a01c11549f87269a13fa2 upstream.
The aloop driver tries to update the hw constraints of the connected
target on the cable of the opened PCM substream. This is done by
adding the extra hw constraints rules referring to the substream
runtime->hw fields, while the other substream may update the runtime
hw of another side on the fly.
This is, however, racy and may result in the inconsistent values when
both PCM streams perform the prepare concurrently. One of the reason
is that it overwrites the other's runtime->hw field; which is not only
racy but also broken when it's called before the open of another side
finishes. And, since the reference to runtime->hw isn't protected,
the concurrent write may give the partial value update and become
inconsistent.
This patch is an attempt to fix and clean up:
- The prepare doesn't change the runtime->hw of other side any longer,
but only update the cable->hw that is referred commonly.
- The extra rules refer to the loopback_pcm object instead of the
runtime->hw. The actual hw is deduced from cable->hw.
- The extra rules take the cable_lock to protect against the race.
Fixes: b1c73fc8e697 ("ALSA: snd-aloop: Fix hw_params restrictions and checking")
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/drivers/aloop.c | 51 ++++++++++++++++++++------------------------------
1 file changed, 21 insertions(+), 30 deletions(-)
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -306,19 +306,6 @@ static int loopback_trigger(struct snd_p
return 0;
}
-static void params_change_substream(struct loopback_pcm *dpcm,
- struct snd_pcm_runtime *runtime)
-{
- struct snd_pcm_runtime *dst_runtime;
-
- if (dpcm == NULL || dpcm->substream == NULL)
- return;
- dst_runtime = dpcm->substream->runtime;
- if (dst_runtime == NULL)
- return;
- dst_runtime->hw = dpcm->cable->hw;
-}
-
static void params_change(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -330,10 +317,6 @@ static void params_change(struct snd_pcm
cable->hw.rate_max = runtime->rate;
cable->hw.channels_min = runtime->channels;
cable->hw.channels_max = runtime->channels;
- params_change_substream(cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
- runtime);
- params_change_substream(cable->streams[SNDRV_PCM_STREAM_CAPTURE],
- runtime);
}
static int loopback_prepare(struct snd_pcm_substream *substream)
@@ -621,24 +604,29 @@ static unsigned int get_cable_index(stru
static int rule_format(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
-
- struct snd_pcm_hardware *hw = rule->private;
+ struct loopback_pcm *dpcm = rule->private;
+ struct loopback_cable *cable = dpcm->cable;
struct snd_mask m;
snd_mask_none(&m);
- m.bits[0] = (u_int32_t)hw->formats;
- m.bits[1] = (u_int32_t)(hw->formats >> 32);
+ mutex_lock(&dpcm->loopback->cable_lock);
+ m.bits[0] = (u_int32_t)cable->hw.formats;
+ m.bits[1] = (u_int32_t)(cable->hw.formats >> 32);
+ mutex_unlock(&dpcm->loopback->cable_lock);
return snd_mask_refine(hw_param_mask(params, rule->var), &m);
}
static int rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
- struct snd_pcm_hardware *hw = rule->private;
+ struct loopback_pcm *dpcm = rule->private;
+ struct loopback_cable *cable = dpcm->cable;
struct snd_interval t;
- t.min = hw->rate_min;
- t.max = hw->rate_max;
+ mutex_lock(&dpcm->loopback->cable_lock);
+ t.min = cable->hw.rate_min;
+ t.max = cable->hw.rate_max;
+ mutex_unlock(&dpcm->loopback->cable_lock);
t.openmin = t.openmax = 0;
t.integer = 0;
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
@@ -647,11 +635,14 @@ static int rule_rate(struct snd_pcm_hw_p
static int rule_channels(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
- struct snd_pcm_hardware *hw = rule->private;
+ struct loopback_pcm *dpcm = rule->private;
+ struct loopback_cable *cable = dpcm->cable;
struct snd_interval t;
- t.min = hw->channels_min;
- t.max = hw->channels_max;
+ mutex_lock(&dpcm->loopback->cable_lock);
+ t.min = cable->hw.channels_min;
+ t.max = cable->hw.channels_max;
+ mutex_unlock(&dpcm->loopback->cable_lock);
t.openmin = t.openmax = 0;
t.integer = 0;
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
@@ -717,19 +708,19 @@ static int loopback_open(struct snd_pcm_
/* are cached -> they do not reflect the actual state */
err = snd_pcm_hw_rule_add(runtime, 0,
SNDRV_PCM_HW_PARAM_FORMAT,
- rule_format, &runtime->hw,
+ rule_format, dpcm,
SNDRV_PCM_HW_PARAM_FORMAT, -1);
if (err < 0)
goto unlock;
err = snd_pcm_hw_rule_add(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
- rule_rate, &runtime->hw,
+ rule_rate, dpcm,
SNDRV_PCM_HW_PARAM_RATE, -1);
if (err < 0)
goto unlock;
err = snd_pcm_hw_rule_add(runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
- rule_channels, &runtime->hw,
+ rule_channels, dpcm,
SNDRV_PCM_HW_PARAM_CHANNELS, -1);
if (err < 0)
goto unlock;
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.14/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.14/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.14/alsa-pcm-workaround-for-weird-pulseaudio-behavior-on-rewind-error.patch
queue-4.14/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.14/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.14/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.14/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.14/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: aloop: Fix inconsistent format due to incomplete rule
to the 4.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
and it can be found in the queue-4.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From b088b53e20c7d09b5ab84c5688e609f478e5c417 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Fri, 5 Jan 2018 16:15:33 +0100
Subject: ALSA: aloop: Fix inconsistent format due to incomplete rule
From: Takashi Iwai <tiwai(a)suse.de>
commit b088b53e20c7d09b5ab84c5688e609f478e5c417 upstream.
The extra hw constraint rule for the formats the aloop driver
introduced has a slight flaw, where it doesn't return a positive value
when the mask got changed. It came from the fact that it's basically
a copy&paste from snd_hw_constraint_mask64(). The original code is
supposed to be a single-shot and it modifies the mask bits only once
and never after, while what we need for aloop is the dynamic hw rule
that limits the mask bits.
This difference results in the inconsistent state, as the hw_refine
doesn't apply the dependencies fully. The worse and surprisingly
result is that it causes a crash in OSS emulation when multiple
full-duplex reads/writes are performed concurrently (I leave why it
triggers Oops to readers as a homework).
For fixing this, replace a few open-codes with the standard
snd_mask_*() macros.
Reported-by: syzbot+3902b5220e8ca27889ca(a)syzkaller.appspotmail.com
Fixes: b1c73fc8e697 ("ALSA: snd-aloop: Fix hw_params restrictions and checking")
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/drivers/aloop.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -39,6 +39,7 @@
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include <sound/info.h>
#include <sound/initval.h>
@@ -622,14 +623,12 @@ static int rule_format(struct snd_pcm_hw
{
struct snd_pcm_hardware *hw = rule->private;
- struct snd_mask *maskp = hw_param_mask(params, rule->var);
+ struct snd_mask m;
- maskp->bits[0] &= (u_int32_t)hw->formats;
- maskp->bits[1] &= (u_int32_t)(hw->formats >> 32);
- memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
- if (! maskp->bits[0] && ! maskp->bits[1])
- return -EINVAL;
- return 0;
+ snd_mask_none(&m);
+ m.bits[0] = (u_int32_t)hw->formats;
+ m.bits[1] = (u_int32_t)(hw->formats >> 32);
+ return snd_mask_refine(hw_param_mask(params, rule->var), &m);
}
static int rule_rate(struct snd_pcm_hw_params *params,
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-4.14/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-4.14/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-4.14/alsa-pcm-workaround-for-weird-pulseaudio-behavior-on-rewind-error.patch
queue-4.14/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-4.14/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-4.14/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-4.14/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-4.14/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Remove incorrect snd_BUG_ON() usages
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From fe08f34d066f4404934a509b6806db1a4f700c86 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Mon, 1 Jan 2018 09:50:50 +0100
Subject: ALSA: pcm: Remove incorrect snd_BUG_ON() usages
From: Takashi Iwai <tiwai(a)suse.de>
commit fe08f34d066f4404934a509b6806db1a4f700c86 upstream.
syzkaller triggered kernel warnings through PCM OSS emulation at
closing a stream:
WARNING: CPU: 0 PID: 3502 at sound/core/pcm_lib.c:1635
snd_pcm_hw_param_first+0x289/0x690 sound/core/pcm_lib.c:1635
Call Trace:
....
snd_pcm_hw_param_near.constprop.27+0x78d/0x9a0 sound/core/oss/pcm_oss.c:457
snd_pcm_oss_change_params+0x17d3/0x3720 sound/core/oss/pcm_oss.c:969
snd_pcm_oss_make_ready+0xaa/0x130 sound/core/oss/pcm_oss.c:1128
snd_pcm_oss_sync+0x257/0x830 sound/core/oss/pcm_oss.c:1638
snd_pcm_oss_release+0x20b/0x280 sound/core/oss/pcm_oss.c:2431
__fput+0x327/0x7e0 fs/file_table.c:210
....
This happens while it tries to open and set up the aloop device
concurrently. The warning above (invoked from snd_BUG_ON() macro) is
to detect the unexpected logical error where snd_pcm_hw_refine() call
shouldn't fail. The theory is true for the case where the hw_params
config rules are static. But for an aloop device, the hw_params rule
condition does vary dynamically depending on the connected target;
when another device is opened and changes the parameters, the device
connected in another side is also affected, and it caused the error
from snd_pcm_hw_refine().
That is, the simplest "solution" for this is to remove the incorrect
assumption of static rules, and treat such an error as a normal error
path. As there are a couple of other places using snd_BUG_ON()
incorrectly, this patch removes these spurious snd_BUG_ON() calls.
Reported-by: syzbot+6f11c7e2a1b91d466432(a)syzkaller.appspotmail.com
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_oss.c | 1 -
sound/core/pcm_lib.c | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -465,7 +465,6 @@ static int snd_pcm_hw_param_near(struct
v = snd_pcm_hw_param_last(pcm, params, var, dir);
else
v = snd_pcm_hw_param_first(pcm, params, var, dir);
- snd_BUG_ON(v < 0);
return v;
}
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1633,7 +1633,7 @@ int snd_pcm_hw_param_first(struct snd_pc
return changed;
if (params->rmask) {
int err = snd_pcm_hw_refine(pcm, params);
- if (snd_BUG_ON(err < 0))
+ if (err < 0)
return err;
}
return snd_pcm_hw_param_value(params, var, dir);
@@ -1680,7 +1680,7 @@ int snd_pcm_hw_param_last(struct snd_pcm
return changed;
if (params->rmask) {
int err = snd_pcm_hw_refine(pcm, params);
- if (snd_BUG_ON(err < 0))
+ if (err < 0)
return err;
}
return snd_pcm_hw_param_value(params, var, dir);
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-3.18/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-3.18/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-3.18/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-3.18/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-3.18/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-3.18/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-3.18/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Add missing error checks in OSS emulation plugin builder
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 6708913750344a900f2e73bfe4a4d6dbbce4fe8d Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Thu, 4 Jan 2018 16:39:27 +0100
Subject: ALSA: pcm: Add missing error checks in OSS emulation plugin builder
From: Takashi Iwai <tiwai(a)suse.de>
commit 6708913750344a900f2e73bfe4a4d6dbbce4fe8d upstream.
In the OSS emulation plugin builder where the frame size is parsed in
the plugin chain, some places miss the possible errors returned from
the plugin src_ or dst_frames callback.
This patch papers over such places.
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_plugin.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
--- a/sound/core/oss/pcm_plugin.c
+++ b/sound/core/oss/pcm_plugin.c
@@ -591,18 +591,26 @@ snd_pcm_sframes_t snd_pcm_plug_write_tra
snd_pcm_sframes_t frames = size;
plugin = snd_pcm_plug_first(plug);
- while (plugin && frames > 0) {
+ while (plugin) {
+ if (frames <= 0)
+ return frames;
if ((next = plugin->next) != NULL) {
snd_pcm_sframes_t frames1 = frames;
- if (plugin->dst_frames)
+ if (plugin->dst_frames) {
frames1 = plugin->dst_frames(plugin, frames);
+ if (frames1 <= 0)
+ return frames1;
+ }
if ((err = next->client_channels(next, frames1, &dst_channels)) < 0) {
return err;
}
if (err != frames1) {
frames = err;
- if (plugin->src_frames)
+ if (plugin->src_frames) {
frames = plugin->src_frames(plugin, frames1);
+ if (frames <= 0)
+ return frames;
+ }
}
} else
dst_channels = NULL;
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-3.18/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-3.18/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-3.18/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-3.18/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-3.18/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-3.18/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-3.18/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Allow aborting mutex lock at OSS read/write loops
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 900498a34a3ac9c611e9b425094c8106bdd7dc1c Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Mon, 8 Jan 2018 14:03:53 +0100
Subject: ALSA: pcm: Allow aborting mutex lock at OSS read/write loops
From: Takashi Iwai <tiwai(a)suse.de>
commit 900498a34a3ac9c611e9b425094c8106bdd7dc1c upstream.
PCM OSS read/write loops keep taking the mutex lock for the whole
read/write, and this might take very long when the exceptionally high
amount of data is given. Also, since it invokes with mutex_lock(),
the concurrent read/write becomes unbreakable.
This patch tries to address these issues by replacing mutex_lock()
with mutex_lock_interruptible(), and also splits / re-takes the lock
at each read/write period chunk, so that it can switch the context
more finely if requested.
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_oss.c | 36 +++++++++++++++++++++---------------
1 file changed, 21 insertions(+), 15 deletions(-)
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1370,8 +1370,11 @@ static ssize_t snd_pcm_oss_write1(struct
if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
return tmp;
- mutex_lock(&runtime->oss.params_lock);
while (bytes > 0) {
+ if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
+ tmp = -ERESTARTSYS;
+ break;
+ }
if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
tmp = bytes;
if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
@@ -1415,18 +1418,18 @@ static ssize_t snd_pcm_oss_write1(struct
xfer += tmp;
if ((substream->f_flags & O_NONBLOCK) != 0 &&
tmp != runtime->oss.period_bytes)
- break;
+ tmp = -EAGAIN;
}
+ err:
+ mutex_unlock(&runtime->oss.params_lock);
+ if (tmp < 0)
+ break;
if (signal_pending(current)) {
tmp = -ERESTARTSYS;
- goto err;
+ break;
}
+ tmp = 0;
}
- mutex_unlock(&runtime->oss.params_lock);
- return xfer;
-
- err:
- mutex_unlock(&runtime->oss.params_lock);
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
}
@@ -1474,8 +1477,11 @@ static ssize_t snd_pcm_oss_read1(struct
if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
return tmp;
- mutex_lock(&runtime->oss.params_lock);
while (bytes > 0) {
+ if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
+ tmp = -ERESTARTSYS;
+ break;
+ }
if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
if (runtime->oss.buffer_used == 0) {
tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
@@ -1506,16 +1512,16 @@ static ssize_t snd_pcm_oss_read1(struct
bytes -= tmp;
xfer += tmp;
}
+ err:
+ mutex_unlock(&runtime->oss.params_lock);
+ if (tmp < 0)
+ break;
if (signal_pending(current)) {
tmp = -ERESTARTSYS;
- goto err;
+ break;
}
+ tmp = 0;
}
- mutex_unlock(&runtime->oss.params_lock);
- return xfer;
-
- err:
- mutex_unlock(&runtime->oss.params_lock);
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
}
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-3.18/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-3.18/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-3.18/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-3.18/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-3.18/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-3.18/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-3.18/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: aloop: Release cable upon open error path
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-aloop-release-cable-upon-open-error-path.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 9685347aa0a5c2869058ca6ab79fd8e93084a67f Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Fri, 5 Jan 2018 16:09:47 +0100
Subject: ALSA: aloop: Release cable upon open error path
From: Takashi Iwai <tiwai(a)suse.de>
commit 9685347aa0a5c2869058ca6ab79fd8e93084a67f upstream.
The aloop runtime object and its assignment in the cable are left even
when opening a substream fails. This doesn't mean any memory leak,
but it still keeps the invalid pointer that may be referred by the
another side of the cable spontaneously, which is a potential Oops
cause.
Clean up the cable assignment and the empty cable upon the error path
properly.
Fixes: 597603d615d2 ("ALSA: introduce the snd-aloop module for the PCM loopback")
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/drivers/aloop.c | 38 +++++++++++++++++++++++++-------------
1 file changed, 25 insertions(+), 13 deletions(-)
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -659,12 +659,31 @@ static int rule_channels(struct snd_pcm_
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
}
+static void free_cable(struct snd_pcm_substream *substream)
+{
+ struct loopback *loopback = substream->private_data;
+ int dev = get_cable_index(substream);
+ struct loopback_cable *cable;
+
+ cable = loopback->cables[substream->number][dev];
+ if (!cable)
+ return;
+ if (cable->streams[!substream->stream]) {
+ /* other stream is still alive */
+ cable->streams[substream->stream] = NULL;
+ } else {
+ /* free the cable */
+ loopback->cables[substream->number][dev] = NULL;
+ kfree(cable);
+ }
+}
+
static int loopback_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct loopback *loopback = substream->private_data;
struct loopback_pcm *dpcm;
- struct loopback_cable *cable;
+ struct loopback_cable *cable = NULL;
int err = 0;
int dev = get_cable_index(substream);
@@ -683,7 +702,6 @@ static int loopback_open(struct snd_pcm_
if (!cable) {
cable = kzalloc(sizeof(*cable), GFP_KERNEL);
if (!cable) {
- kfree(dpcm);
err = -ENOMEM;
goto unlock;
}
@@ -725,6 +743,10 @@ static int loopback_open(struct snd_pcm_
else
runtime->hw = cable->hw;
unlock:
+ if (err < 0) {
+ free_cable(substream);
+ kfree(dpcm);
+ }
mutex_unlock(&loopback->cable_lock);
return err;
}
@@ -733,20 +755,10 @@ static int loopback_close(struct snd_pcm
{
struct loopback *loopback = substream->private_data;
struct loopback_pcm *dpcm = substream->runtime->private_data;
- struct loopback_cable *cable;
- int dev = get_cable_index(substream);
loopback_timer_stop(dpcm);
mutex_lock(&loopback->cable_lock);
- cable = loopback->cables[substream->number][dev];
- if (cable->streams[!substream->stream]) {
- /* other stream is still alive */
- cable->streams[substream->stream] = NULL;
- } else {
- /* free the cable */
- loopback->cables[substream->number][dev] = NULL;
- kfree(cable);
- }
+ free_cable(substream);
mutex_unlock(&loopback->cable_lock);
return 0;
}
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-3.18/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-3.18/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-3.18/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-3.18/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-3.18/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-3.18/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-3.18/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: pcm: Abort properly at pending signal in OSS read/write loops
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 29159a4ed7044c52e3e2cf1a9fb55cec4745c60b Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Mon, 8 Jan 2018 13:58:31 +0100
Subject: ALSA: pcm: Abort properly at pending signal in OSS read/write loops
From: Takashi Iwai <tiwai(a)suse.de>
commit 29159a4ed7044c52e3e2cf1a9fb55cec4745c60b upstream.
The loops for read and write in PCM OSS emulation have no proper check
of pending signals, and they keep processing even after user tries to
break. This results in a very long delay, often seen as RCU stall
when a huge unprocessed bytes remain queued. The bug could be easily
triggered by syzkaller.
As a simple workaround, this patch adds the proper check of pending
signals and aborts the loop appropriately.
Reported-by: syzbot+993cb4cfcbbff3947c21(a)syzkaller.appspotmail.com
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/core/oss/pcm_oss.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1417,6 +1417,10 @@ static ssize_t snd_pcm_oss_write1(struct
tmp != runtime->oss.period_bytes)
break;
}
+ if (signal_pending(current)) {
+ tmp = -ERESTARTSYS;
+ goto err;
+ }
}
mutex_unlock(&runtime->oss.params_lock);
return xfer;
@@ -1502,6 +1506,10 @@ static ssize_t snd_pcm_oss_read1(struct
bytes -= tmp;
xfer += tmp;
}
+ if (signal_pending(current)) {
+ tmp = -ERESTARTSYS;
+ goto err;
+ }
}
mutex_unlock(&runtime->oss.params_lock);
return xfer;
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-3.18/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-3.18/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-3.18/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-3.18/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-3.18/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-3.18/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-3.18/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: aloop: Fix racy hw constraints adjustment
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-aloop-fix-racy-hw-constraints-adjustment.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 898dfe4687f460ba337a01c11549f87269a13fa2 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Thu, 4 Jan 2018 17:38:54 +0100
Subject: ALSA: aloop: Fix racy hw constraints adjustment
From: Takashi Iwai <tiwai(a)suse.de>
commit 898dfe4687f460ba337a01c11549f87269a13fa2 upstream.
The aloop driver tries to update the hw constraints of the connected
target on the cable of the opened PCM substream. This is done by
adding the extra hw constraints rules referring to the substream
runtime->hw fields, while the other substream may update the runtime
hw of another side on the fly.
This is, however, racy and may result in the inconsistent values when
both PCM streams perform the prepare concurrently. One of the reason
is that it overwrites the other's runtime->hw field; which is not only
racy but also broken when it's called before the open of another side
finishes. And, since the reference to runtime->hw isn't protected,
the concurrent write may give the partial value update and become
inconsistent.
This patch is an attempt to fix and clean up:
- The prepare doesn't change the runtime->hw of other side any longer,
but only update the cable->hw that is referred commonly.
- The extra rules refer to the loopback_pcm object instead of the
runtime->hw. The actual hw is deduced from cable->hw.
- The extra rules take the cable_lock to protect against the race.
Fixes: b1c73fc8e697 ("ALSA: snd-aloop: Fix hw_params restrictions and checking")
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/drivers/aloop.c | 51 ++++++++++++++++++++------------------------------
1 file changed, 21 insertions(+), 30 deletions(-)
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -307,19 +307,6 @@ static int loopback_trigger(struct snd_p
return 0;
}
-static void params_change_substream(struct loopback_pcm *dpcm,
- struct snd_pcm_runtime *runtime)
-{
- struct snd_pcm_runtime *dst_runtime;
-
- if (dpcm == NULL || dpcm->substream == NULL)
- return;
- dst_runtime = dpcm->substream->runtime;
- if (dst_runtime == NULL)
- return;
- dst_runtime->hw = dpcm->cable->hw;
-}
-
static void params_change(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
@@ -331,10 +318,6 @@ static void params_change(struct snd_pcm
cable->hw.rate_max = runtime->rate;
cable->hw.channels_min = runtime->channels;
cable->hw.channels_max = runtime->channels;
- params_change_substream(cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
- runtime);
- params_change_substream(cable->streams[SNDRV_PCM_STREAM_CAPTURE],
- runtime);
}
static int loopback_prepare(struct snd_pcm_substream *substream)
@@ -622,24 +605,29 @@ static unsigned int get_cable_index(stru
static int rule_format(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
-
- struct snd_pcm_hardware *hw = rule->private;
+ struct loopback_pcm *dpcm = rule->private;
+ struct loopback_cable *cable = dpcm->cable;
struct snd_mask m;
snd_mask_none(&m);
- m.bits[0] = (u_int32_t)hw->formats;
- m.bits[1] = (u_int32_t)(hw->formats >> 32);
+ mutex_lock(&dpcm->loopback->cable_lock);
+ m.bits[0] = (u_int32_t)cable->hw.formats;
+ m.bits[1] = (u_int32_t)(cable->hw.formats >> 32);
+ mutex_unlock(&dpcm->loopback->cable_lock);
return snd_mask_refine(hw_param_mask(params, rule->var), &m);
}
static int rule_rate(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
- struct snd_pcm_hardware *hw = rule->private;
+ struct loopback_pcm *dpcm = rule->private;
+ struct loopback_cable *cable = dpcm->cable;
struct snd_interval t;
- t.min = hw->rate_min;
- t.max = hw->rate_max;
+ mutex_lock(&dpcm->loopback->cable_lock);
+ t.min = cable->hw.rate_min;
+ t.max = cable->hw.rate_max;
+ mutex_unlock(&dpcm->loopback->cable_lock);
t.openmin = t.openmax = 0;
t.integer = 0;
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
@@ -648,11 +636,14 @@ static int rule_rate(struct snd_pcm_hw_p
static int rule_channels(struct snd_pcm_hw_params *params,
struct snd_pcm_hw_rule *rule)
{
- struct snd_pcm_hardware *hw = rule->private;
+ struct loopback_pcm *dpcm = rule->private;
+ struct loopback_cable *cable = dpcm->cable;
struct snd_interval t;
- t.min = hw->channels_min;
- t.max = hw->channels_max;
+ mutex_lock(&dpcm->loopback->cable_lock);
+ t.min = cable->hw.channels_min;
+ t.max = cable->hw.channels_max;
+ mutex_unlock(&dpcm->loopback->cable_lock);
t.openmin = t.openmax = 0;
t.integer = 0;
return snd_interval_refine(hw_param_interval(params, rule->var), &t);
@@ -718,19 +709,19 @@ static int loopback_open(struct snd_pcm_
/* are cached -> they do not reflect the actual state */
err = snd_pcm_hw_rule_add(runtime, 0,
SNDRV_PCM_HW_PARAM_FORMAT,
- rule_format, &runtime->hw,
+ rule_format, dpcm,
SNDRV_PCM_HW_PARAM_FORMAT, -1);
if (err < 0)
goto unlock;
err = snd_pcm_hw_rule_add(runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
- rule_rate, &runtime->hw,
+ rule_rate, dpcm,
SNDRV_PCM_HW_PARAM_RATE, -1);
if (err < 0)
goto unlock;
err = snd_pcm_hw_rule_add(runtime, 0,
SNDRV_PCM_HW_PARAM_CHANNELS,
- rule_channels, &runtime->hw,
+ rule_channels, dpcm,
SNDRV_PCM_HW_PARAM_CHANNELS, -1);
if (err < 0)
goto unlock;
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-3.18/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-3.18/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-3.18/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-3.18/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-3.18/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-3.18/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-3.18/alsa-aloop-release-cable-upon-open-error-path.patch
This is a note to let you know that I've just added the patch titled
ALSA: aloop: Fix inconsistent format due to incomplete rule
to the 3.18-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
and it can be found in the queue-3.18 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From b088b53e20c7d09b5ab84c5688e609f478e5c417 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <tiwai(a)suse.de>
Date: Fri, 5 Jan 2018 16:15:33 +0100
Subject: ALSA: aloop: Fix inconsistent format due to incomplete rule
From: Takashi Iwai <tiwai(a)suse.de>
commit b088b53e20c7d09b5ab84c5688e609f478e5c417 upstream.
The extra hw constraint rule for the formats the aloop driver
introduced has a slight flaw, where it doesn't return a positive value
when the mask got changed. It came from the fact that it's basically
a copy&paste from snd_hw_constraint_mask64(). The original code is
supposed to be a single-shot and it modifies the mask bits only once
and never after, while what we need for aloop is the dynamic hw rule
that limits the mask bits.
This difference results in the inconsistent state, as the hw_refine
doesn't apply the dependencies fully. The worse and surprisingly
result is that it causes a crash in OSS emulation when multiple
full-duplex reads/writes are performed concurrently (I leave why it
triggers Oops to readers as a homework).
For fixing this, replace a few open-codes with the standard
snd_mask_*() macros.
Reported-by: syzbot+3902b5220e8ca27889ca(a)syzkaller.appspotmail.com
Fixes: b1c73fc8e697 ("ALSA: snd-aloop: Fix hw_params restrictions and checking")
Signed-off-by: Takashi Iwai <tiwai(a)suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
sound/drivers/aloop.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -39,6 +39,7 @@
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
+#include <sound/pcm_params.h>
#include <sound/info.h>
#include <sound/initval.h>
@@ -623,14 +624,12 @@ static int rule_format(struct snd_pcm_hw
{
struct snd_pcm_hardware *hw = rule->private;
- struct snd_mask *maskp = hw_param_mask(params, rule->var);
+ struct snd_mask m;
- maskp->bits[0] &= (u_int32_t)hw->formats;
- maskp->bits[1] &= (u_int32_t)(hw->formats >> 32);
- memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
- if (! maskp->bits[0] && ! maskp->bits[1])
- return -EINVAL;
- return 0;
+ snd_mask_none(&m);
+ m.bits[0] = (u_int32_t)hw->formats;
+ m.bits[1] = (u_int32_t)(hw->formats >> 32);
+ return snd_mask_refine(hw_param_mask(params, rule->var), &m);
}
static int rule_rate(struct snd_pcm_hw_params *params,
Patches currently in stable-queue which might be from tiwai(a)suse.de are
queue-3.18/alsa-pcm-remove-incorrect-snd_bug_on-usages.patch
queue-3.18/alsa-aloop-fix-inconsistent-format-due-to-incomplete-rule.patch
queue-3.18/alsa-pcm-add-missing-error-checks-in-oss-emulation-plugin-builder.patch
queue-3.18/alsa-pcm-abort-properly-at-pending-signal-in-oss-read-write-loops.patch
queue-3.18/alsa-pcm-allow-aborting-mutex-lock-at-oss-read-write-loops.patch
queue-3.18/alsa-aloop-fix-racy-hw-constraints-adjustment.patch
queue-3.18/alsa-aloop-release-cable-upon-open-error-path.patch
From: Eric Biggers <ebiggers(a)google.com>
pipe-user-pages-hard and pipe-user-pages-soft are only supposed to apply
to unprivileged users, as documented in both Documentation/sysctl/fs.txt
and the pipe(7) man page.
However, the capabilities are actually only checked when increasing a
pipe's size using F_SETPIPE_SZ, not when creating a new pipe.
Therefore, if pipe-user-pages-hard has been set, the root user can run
into it and be unable to create pipes. Similarly, if
pipe-user-pages-soft has been set, the root user can run into it and
have their pipes limited to 1 page each.
Fix this by allowing the privileged override in both cases.
Fixes: 759c01142a5d ("pipe: limit the per-user amount of pages allocated in pipes")
Cc: stable(a)vger.kernel.org
Signed-off-by: Eric Biggers <ebiggers(a)google.com>
---
fs/pipe.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/fs/pipe.c b/fs/pipe.c
index d0dec5e7ef33..847ecc388820 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -613,6 +613,11 @@ static bool too_many_pipe_buffers_hard(unsigned long user_bufs)
return pipe_user_pages_hard && user_bufs >= pipe_user_pages_hard;
}
+static bool is_unprivileged_user(void)
+{
+ return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
+}
+
struct pipe_inode_info *alloc_pipe_info(void)
{
struct pipe_inode_info *pipe;
@@ -629,12 +634,12 @@ struct pipe_inode_info *alloc_pipe_info(void)
user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
- if (too_many_pipe_buffers_soft(user_bufs)) {
+ if (too_many_pipe_buffers_soft(user_bufs) && is_unprivileged_user()) {
user_bufs = account_pipe_buffers(user, pipe_bufs, 1);
pipe_bufs = 1;
}
- if (too_many_pipe_buffers_hard(user_bufs))
+ if (too_many_pipe_buffers_hard(user_bufs) && is_unprivileged_user())
goto out_revert_acct;
pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer),
@@ -1065,7 +1070,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
if (nr_pages > pipe->buffers &&
(too_many_pipe_buffers_hard(user_bufs) ||
too_many_pipe_buffers_soft(user_bufs)) &&
- !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) {
+ is_unprivileged_user()) {
ret = -EPERM;
goto out_revert_acct;
}
--
2.15.1
Complement commit c23b3d1a5311 ("MIPS: ptrace: Change GP regset to use
correct core dump register layout") and also reject outsized
PTRACE_SETREGSET requests to the NT_PRFPREG regset, like with the
NT_PRSTATUS regset.
Signed-off-by: Maciej W. Rozycki <macro(a)mips.com>
Fixes: c23b3d1a5311 ("MIPS: ptrace: Change GP regset to use correct core dump register layout")
Cc: James Hogan <james.hogan(a)mips.com>
Cc: Paul Burton <Paul.Burton(a)mips.com>
Cc: Alex Smith <alex(a)alex-smith.me.uk>
Cc: Dave Martin <Dave.Martin(a)arm.com>
Cc: linux-mips(a)linux-mips.org
Cc: linux-kernel(a)vger.kernel.org
Cc: stable(a)vger.kernel.org # v3.17+
Patchwork: https://patchwork.linux-mips.org/patch/17930/
Signed-off-by: Ralf Baechle <ralf(a)linux-mips.org>
---
Hi,
This is a (mechanically regenerated) version of commit c8c5a3a24d39 for
3.18-stable and before. No functional changes. Please apply.
Maciej
---
arch/mips/kernel/ptrace.c | 3 +++
1 file changed, 3 insertions(+)
linux-mips-nt-prfpreg-size.diff
Index: linux-stable-el/arch/mips/kernel/ptrace.c
===================================================================
--- linux-stable-el.orig/arch/mips/kernel/ptrace.c 2018-01-10 20:11:52.000000000 +0000
+++ linux-stable-el/arch/mips/kernel/ptrace.c 2018-01-10 20:13:16.212944000 +0000
@@ -530,6 +530,9 @@ static int fpr_set(struct task_struct *t
BUG_ON(count % sizeof(elf_fpreg_t));
+ if (pos + count > sizeof(elf_fpregset_t))
+ return -EIO;
+
if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
err = fpr_set_fpa(target, &pos, &count, &kbuf, &ubuf);
else
Fix a commit 72b22bbad1e7 ("MIPS: Don't assume 64-bit FP registers for
FP regset") public API regression, then activated by commit 1db1af84d6df
("MIPS: Basic MSA context switching support"), that caused the FCSR
register not to be read or written for CONFIG_CPU_HAS_MSA kernel
configurations (regardless of actual presence or absence of the MSA
feature in a given processor) with ptrace(2) PTRACE_GETREGSET and
PTRACE_SETREGSET requests nor recorded in core dumps.
This is because with !CONFIG_CPU_HAS_MSA configurations the whole of
`elf_fpregset_t' array is bulk-copied as it is, which includes the FCSR
in one half of the last, 33rd slot, whereas with CONFIG_CPU_HAS_MSA
configurations array elements are copied individually, and then only the
leading 32 FGR slots while the remaining slot is ignored.
Correct the code then such that only FGR slots are copied in the
respective !MSA and MSA helpers an then the FCSR slot is handled
separately in common code. Use `ptrace_setfcr31' to update the FCSR
too, so that the read-only mask is respected.
Retrieving a correct value of FCSR is important in debugging not only
for the human to be able to get the right interpretation of the
situation, but for correct operation of GDB as well. This is because
the condition code bits in FSCR are used by GDB to determine the
location to place a breakpoint at when single-stepping through an FPU
branch instruction. If such a breakpoint is placed incorrectly (i.e.
with the condition reversed), then it will be missed, likely causing the
debuggee to run away from the control of GDB and consequently breaking
the process of investigation.
Fortunately GDB continues using the older PTRACE_GETFPREGS ptrace(2)
request which is unaffected, so the regression only really hits with
post-mortem debug sessions using a core dump file, in which case
execution, and consequently single-stepping through branches is not
possible. Of course core files created by buggy kernels out there will
have the value of FCSR recorded clobbered, but such core files cannot be
corrected and the person using them simply will have to be aware that
the value of FCSR retrieved is not reliable.
Which also means we can likely get away without defining a replacement
API which would ensure a correct value of FSCR to be retrieved, or none
at all.
This is based on previous work by Alex Smith, extensively rewritten.
Signed-off-by: Alex Smith <alex(a)alex-smith.me.uk>
Signed-off-by: James Hogan <james.hogan(a)mips.com>
Signed-off-by: Maciej W. Rozycki <macro(a)mips.com>
Fixes: 72b22bbad1e7 ("MIPS: Don't assume 64-bit FP registers for FP regset")
Cc: Paul Burton <Paul.Burton(a)mips.com>
Cc: Dave Martin <Dave.Martin(a)arm.com>
Cc: linux-mips(a)linux-mips.org
Cc: linux-kernel(a)vger.kernel.org
Cc: stable(a)vger.kernel.org # v3.15+
Patchwork: https://patchwork.linux-mips.org/patch/17928/
Signed-off-by: Ralf Baechle <ralf(a)linux-mips.org>
---
Hi,
This is a version of commit be07a6a11883 for 3.18-stable and before. It
updates code added like this:
- ptrace_setfcr31(target, fcr31);
+ target->thread.fpu.fcr31 = fcr31 & ~FPU_CSR_ALL_X;
because there is no `ptrace_setfcr31' helper in 3.18. This is equivalent
to the original commit in terms of functionality as at version 3.18.
Please apply.
Maciej
---
arch/mips/kernel/ptrace.c | 47 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 36 insertions(+), 11 deletions(-)
linux-mips-nt-prfpreg-fcsr.diff
Index: linux-stable-el/arch/mips/kernel/ptrace.c
===================================================================
--- linux-stable-el.orig/arch/mips/kernel/ptrace.c 2018-01-10 20:03:43.000000000 +0000
+++ linux-stable-el/arch/mips/kernel/ptrace.c 2018-01-10 20:11:52.407204000 +0000
@@ -403,7 +403,7 @@ static int gpr64_set(struct task_struct
/*
* Copy the floating-point context to the supplied NT_PRFPREG buffer,
* !CONFIG_CPU_HAS_MSA variant. FP context's general register slots
- * correspond 1:1 to buffer slots.
+ * correspond 1:1 to buffer slots. Only general registers are copied.
*/
static int fpr_get_fpa(struct task_struct *target,
unsigned int *pos, unsigned int *count,
@@ -411,13 +411,14 @@ static int fpr_get_fpa(struct task_struc
{
return user_regset_copyout(pos, count, kbuf, ubuf,
&target->thread.fpu,
- 0, sizeof(elf_fpregset_t));
+ 0, NUM_FPU_REGS * sizeof(elf_fpreg_t));
}
/*
* Copy the floating-point context to the supplied NT_PRFPREG buffer,
* CONFIG_CPU_HAS_MSA variant. Only lower 64 bits of FP context's
- * general register slots are copied to buffer slots.
+ * general register slots are copied to buffer slots. Only general
+ * registers are copied.
*/
static int fpr_get_msa(struct task_struct *target,
unsigned int *pos, unsigned int *count,
@@ -439,20 +440,29 @@ static int fpr_get_msa(struct task_struc
return 0;
}
-/* Copy the floating-point context to the supplied NT_PRFPREG buffer. */
+/*
+ * Copy the floating-point context to the supplied NT_PRFPREG buffer.
+ * Choose the appropriate helper for general registers, and then copy
+ * the FCSR register separately.
+ */
static int fpr_get(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
void *kbuf, void __user *ubuf)
{
+ const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
int err;
- /* XXX fcr31 */
-
if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
err = fpr_get_fpa(target, &pos, &count, &kbuf, &ubuf);
else
err = fpr_get_msa(target, &pos, &count, &kbuf, &ubuf);
+ if (err)
+ return err;
+
+ err = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fpu.fcr31,
+ fcr31_pos, fcr31_pos + sizeof(u32));
return err;
}
@@ -460,7 +470,7 @@ static int fpr_get(struct task_struct *t
/*
* Copy the supplied NT_PRFPREG buffer to the floating-point context,
* !CONFIG_CPU_HAS_MSA variant. Buffer slots correspond 1:1 to FP
- * context's general register slots.
+ * context's general register slots. Only general registers are copied.
*/
static int fpr_set_fpa(struct task_struct *target,
unsigned int *pos, unsigned int *count,
@@ -468,13 +478,14 @@ static int fpr_set_fpa(struct task_struc
{
return user_regset_copyin(pos, count, kbuf, ubuf,
&target->thread.fpu,
- 0, sizeof(elf_fpregset_t));
+ 0, NUM_FPU_REGS * sizeof(elf_fpreg_t));
}
/*
* Copy the supplied NT_PRFPREG buffer to the floating-point context,
* CONFIG_CPU_HAS_MSA variant. Buffer slots are copied to lower 64
- * bits only of FP context's general register slots.
+ * bits only of FP context's general register slots. Only general
+ * registers are copied.
*/
static int fpr_set_msa(struct task_struct *target,
unsigned int *pos, unsigned int *count,
@@ -499,6 +510,8 @@ static int fpr_set_msa(struct task_struc
/*
* Copy the supplied NT_PRFPREG buffer to the floating-point context.
+ * Choose the appropriate helper for general registers, and then copy
+ * the FCSR register separately.
*
* We optimize for the case where `count % sizeof(elf_fpreg_t) == 0',
* which is supposed to have been guaranteed by the kernel before
@@ -511,16 +524,28 @@ static int fpr_set(struct task_struct *t
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
+ const int fcr31_pos = NUM_FPU_REGS * sizeof(elf_fpreg_t);
+ u32 fcr31;
int err;
BUG_ON(count % sizeof(elf_fpreg_t));
- /* XXX fcr31 */
-
if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
err = fpr_set_fpa(target, &pos, &count, &kbuf, &ubuf);
else
err = fpr_set_msa(target, &pos, &count, &kbuf, &ubuf);
+ if (err)
+ return err;
+
+ if (count > 0) {
+ err = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &fcr31,
+ fcr31_pos, fcr31_pos + sizeof(u32));
+ if (err)
+ return err;
+
+ target->thread.fpu.fcr31 = fcr31 & ~FPU_CSR_ALL_X;
+ }
return err;
}
Update commit d614fd58a283 ("mips/ptrace: Preserve previous registers
for short regset write") bug and consistently consume all data supplied
to `fpr_set_msa' with the ptrace(2) PTRACE_SETREGSET request, such that
a zero data buffer counter is returned where insufficient data has been
given to fill a whole number of FP general registers.
In reality this is not going to happen, as the caller is supposed to
only supply data covering a whole number of registers and it is verified
in `ptrace_regset' and again asserted in `fpr_set', however structuring
code such that the presence of trailing partial FP general register data
causes `fpr_set_msa' to return with a non-zero data buffer counter makes
it appear that this trailing data will be used if there are subsequent
writes made to FP registers, which is going to be the case with the FCSR
once the missing write to that register has been fixed.
Fixes: d614fd58a283 ("mips/ptrace: Preserve previous registers for short regset write")
Signed-off-by: Maciej W. Rozycki <macro(a)mips.com>
Cc: James Hogan <james.hogan(a)mips.com>
Cc: Paul Burton <Paul.Burton(a)mips.com>
Cc: Alex Smith <alex(a)alex-smith.me.uk>
Cc: Dave Martin <Dave.Martin(a)arm.com>
Cc: linux-mips(a)linux-mips.org
Cc: linux-kernel(a)vger.kernel.org
Cc: stable(a)vger.kernel.org # v4.11+
Patchwork: https://patchwork.linux-mips.org/patch/17927/
Signed-off-by: Ralf Baechle <ralf(a)linux-mips.org>
---
Hi,
This is a (mechanically regenerated) version of commit 80b3ffce0196 for
3.18-stable and before. No functional changes. Please apply.
Maciej
---
arch/mips/kernel/ptrace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
linux-mips-nt-prfpreg-count.diff
Index: linux-stable-el/arch/mips/kernel/ptrace.c
===================================================================
--- linux-stable-el.orig/arch/mips/kernel/ptrace.c 2018-01-10 20:27:12.485956000 +0000
+++ linux-stable-el/arch/mips/kernel/ptrace.c 2018-01-10 20:27:13.744971000 +0000
@@ -485,7 +485,7 @@ static int fpr_set_msa(struct task_struc
int err;
BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t));
- for (i = 0; i < NUM_FPU_REGS && *count >= sizeof(elf_fpreg_t); i++) {
+ for (i = 0; i < NUM_FPU_REGS && *count > 0; i++) {
err = user_regset_copyin(pos, count, kbuf, ubuf,
&fpr_val, i * sizeof(elf_fpreg_t),
(i + 1) * sizeof(elf_fpreg_t));
Complement commit d614fd58a283 ("mips/ptrace: Preserve previous
registers for short regset write") and ensure that no partial register
write attempt is made with PTRACE_SETREGSET, as we do not preinitialize
any temporaries used to hold incoming register data and consequently
random data could be written.
It is the responsibility of the caller, such as `ptrace_regset', to
arrange for writes to span whole registers only, so here we only assert
that it has indeed happened.
Signed-off-by: Maciej W. Rozycki <macro(a)mips.com>
Fixes: 72b22bbad1e7 ("MIPS: Don't assume 64-bit FP registers for FP regset")
Cc: James Hogan <james.hogan(a)mips.com>
Cc: Paul Burton <Paul.Burton(a)mips.com>
Cc: Alex Smith <alex(a)alex-smith.me.uk>
Cc: Dave Martin <Dave.Martin(a)arm.com>
Cc: linux-mips(a)linux-mips.org
Cc: linux-kernel(a)vger.kernel.org
Cc: stable(a)vger.kernel.org # v3.15+
Patchwork: https://patchwork.linux-mips.org/patch/17926/
Signed-off-by: Ralf Baechle <ralf(a)linux-mips.org>
---
Hi,
This is a (mechanically regenerated) version of commit dc24d0edf33c for
3.18-stable and before. No functional changes. Please apply.
Maciej
---
arch/mips/kernel/ptrace.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
linux-mips-nt-prfpreg-size-bug.diff
Index: linux-stable-el/arch/mips/kernel/ptrace.c
===================================================================
--- linux-stable-el.orig/arch/mips/kernel/ptrace.c 2018-01-10 20:13:31.900045000 +0000
+++ linux-stable-el/arch/mips/kernel/ptrace.c 2018-01-10 20:13:33.337064000 +0000
@@ -497,7 +497,15 @@ static int fpr_set_msa(struct task_struc
return 0;
}
-/* Copy the supplied NT_PRFPREG buffer to the floating-point context. */
+/*
+ * Copy the supplied NT_PRFPREG buffer to the floating-point context.
+ *
+ * We optimize for the case where `count % sizeof(elf_fpreg_t) == 0',
+ * which is supposed to have been guaranteed by the kernel before
+ * calling us, e.g. in `ptrace_regset'. We enforce that requirement,
+ * so that we can safely avoid preinitializing temporaries for
+ * partial register writes.
+ */
static int fpr_set(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
@@ -505,6 +513,8 @@ static int fpr_set(struct task_struct *t
{
int err;
+ BUG_ON(count % sizeof(elf_fpreg_t));
+
/* XXX fcr31 */
if (sizeof(target->thread.fpu.fpr[0]) == sizeof(elf_fpreg_t))
This patch series fixes an issue with HS/FS 3-stage control read transfer where
DWC3 incorrectly check when to send ZLP.
Changes in v2:
- Separate from "usb: dwc3: Add new updates for DWC_usb31" patch series
- Add 'Cc' to stable mailing list
Thinh Nguyen (2):
usb: dwc3: gadget: Set maxpacket size for ep0 IN
usb: dwc3: ep0: Reset TRB counter for ep0 IN
drivers/usb/dwc3/ep0.c | 7 ++++++-
drivers/usb/dwc3/gadget.c | 2 ++
2 files changed, 8 insertions(+), 1 deletion(-)
--
2.11.0
From: "Leo (Sunpeng) Li" <sunpeng.li(a)amd.com>
During a non-blocking commit, it is possible to return before the
commit_tail work is queued (-ERESTARTSYS, for example).
Since a reference on the crtc commit object is obtained for the pending
vblank event when preparing the commit, the above situation will leave
us with an extra reference.
Therefore, if the commit_tail worker has not consumed the event at the
end of a commit, release it's reference.
Changes since v1:
- Also check for state->event->base.completion being set, to
handle the case where stall_checks() fails in setup_crtc_commit().
Fixes: 24835e442f28 ("drm: reference count event->completion")
Cc: <stable(a)vger.kernel.org> # v4.11+
Signed-off-by: Leo (Sunpeng) Li <sunpeng.li(a)amd.com>
Acked-by: Harry Wentland <harry.wentland(a)amd.com> #v1
Signed-off-by: Maarten Lankhorst <maarten.lankhorst(a)linux.intel.com>
---
drivers/gpu/drm/drm_atomic_helper.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index b16f1d69a0bb..1d43f3e85a7d 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -3327,6 +3327,15 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
{
if (state->commit) {
+ /*
+ * In the event that a non-blocking commit returns
+ * -ERESTARTSYS before the commit_tail work is queued, we will
+ * have an extra reference to the commit object. Release it, if
+ * the event has not been consumed by the worker.
+ */
+ if (state->event && state->event->base.completion)
+ drm_crtc_commit_put(state->commit);
+
kfree(state->commit->event);
state->commit->event = NULL;
drm_crtc_commit_put(state->commit);
--
2.15.1
From: Long Li <longli(a)microsoft.com>
The original patch was made for stable 4.1 and was Acked on 08/22/2017, but for
some reason it never made it to the stable tree.
Change from v1:
Changed comment that this patch is for linux-stable 4.1 and all prior stable
kernels.
storvsc checks the SG list for gaps before passing them to Hyper-v device.
If there are gaps, data is copied to a bounce buffer and a continuous data
buffer is passed to Hyper-V.
The check on gaps assumes SG list is continuous, and not chained. This is
not always true. Failing the check may result in incorrect I/O data
passed to the Hyper-v device.
This code path is not used post Linux 4.1.
Signed-off-by: Long Li <longli(a)microsoft.com>
Acked-by: Martin K. Petersen <martin.petersen(a)oracle.com>
---
drivers/scsi/storvsc_drv.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 6c52d14..14dc5c6 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -584,17 +584,18 @@ static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count)
for (i = 0; i < sg_count; i++) {
if (i == 0) {
/* make sure 1st one does not have hole */
- if (sgl[i].offset + sgl[i].length != PAGE_SIZE)
+ if (sgl->offset + sgl->length != PAGE_SIZE)
return i;
} else if (i == sg_count - 1) {
/* make sure last one does not have hole */
- if (sgl[i].offset != 0)
+ if (sgl->offset != 0)
return i;
} else {
/* make sure no hole in the middle */
- if (sgl[i].length != PAGE_SIZE || sgl[i].offset != 0)
+ if (sgl->length != PAGE_SIZE || sgl->offset != 0)
return i;
}
+ sgl = sg_next(sgl);
}
return -1;
}
--
2.7.4
The patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable(a)vger.kernel.org>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
>From 57d72e159b60456c8bb281736c02ddd3164037aa Mon Sep 17 00:00:00 2001
From: Jean-Philippe Brucker <jean-philippe.brucker(a)arm.com>
Date: Thu, 14 Dec 2017 11:03:01 +0000
Subject: [PATCH] iommu/arm-smmu-v3: Don't free page table ops twice
Kasan reports a double free when finalise_stage_fn fails: the io_pgtable
ops are freed by arm_smmu_domain_finalise and then again by
arm_smmu_domain_free. Prevent this by leaving pgtbl_ops empty on failure.
Cc: <stable(a)vger.kernel.org>
Fixes: 48ec83bcbcf5 ("iommu/arm-smmu: Add initial driver support for ARM SMMUv3 devices")
Reviewed-by: Robin Murphy <robin.murphy(a)arm.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker(a)arm.com>
Signed-off-by: Will Deacon <will.deacon(a)arm.com>
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index f122071688fd..db4281d0e269 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1698,13 +1698,15 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
domain->pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
domain->geometry.aperture_end = (1UL << ias) - 1;
domain->geometry.force_aperture = true;
- smmu_domain->pgtbl_ops = pgtbl_ops;
ret = finalise_stage_fn(smmu_domain, &pgtbl_cfg);
- if (ret < 0)
+ if (ret < 0) {
free_io_pgtable_ops(pgtbl_ops);
+ return ret;
+ }
- return ret;
+ smmu_domain->pgtbl_ops = pgtbl_ops;
+ return 0;
}
static __le64 *arm_smmu_get_step_for_sid(struct arm_smmu_device *smmu, u32 sid)
This is a note to let you know that I've just added the patch titled
iommu/arm-smmu-v3: Don't free page table ops twice
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
The filename of the patch is:
iommu-arm-smmu-v3-don-t-free-page-table-ops-twice.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable(a)vger.kernel.org> know about it.
>From 57d72e159b60456c8bb281736c02ddd3164037aa Mon Sep 17 00:00:00 2001
From: Jean-Philippe Brucker <jean-philippe.brucker(a)arm.com>
Date: Thu, 14 Dec 2017 11:03:01 +0000
Subject: iommu/arm-smmu-v3: Don't free page table ops twice
From: Jean-Philippe Brucker <jean-philippe.brucker(a)arm.com>
commit 57d72e159b60456c8bb281736c02ddd3164037aa upstream.
Kasan reports a double free when finalise_stage_fn fails: the io_pgtable
ops are freed by arm_smmu_domain_finalise and then again by
arm_smmu_domain_free. Prevent this by leaving pgtbl_ops empty on failure.
Fixes: 48ec83bcbcf5 ("iommu/arm-smmu: Add initial driver support for ARM SMMUv3 devices")
Reviewed-by: Robin Murphy <robin.murphy(a)arm.com>
Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker(a)arm.com>
Signed-off-by: Will Deacon <will.deacon(a)arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
---
drivers/iommu/arm-smmu-v3.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -1541,13 +1541,15 @@ static int arm_smmu_domain_finalise(stru
return -ENOMEM;
arm_smmu_ops.pgsize_bitmap = pgtbl_cfg.pgsize_bitmap;
- smmu_domain->pgtbl_ops = pgtbl_ops;
ret = finalise_stage_fn(smmu_domain, &pgtbl_cfg);
- if (IS_ERR_VALUE(ret))
+ if (IS_ERR_VALUE(ret)) {
free_io_pgtable_ops(pgtbl_ops);
+ return ret;
+ }
- return ret;
+ smmu_domain->pgtbl_ops = pgtbl_ops;
+ return 0;
}
static struct arm_smmu_group *arm_smmu_group_get(struct device *dev)
Patches currently in stable-queue which might be from jean-philippe.brucker(a)arm.com are
queue-4.4/iommu-arm-smmu-v3-don-t-free-page-table-ops-twice.patch
If we return 1 from our post_reset handler, then our disconnect handler
will be called immediately afterwards. Since pre_reset blocks all scsi
requests our disconnect handler will then hang in the scsi_remove_host
call.
This is esp. bad because our disconnect handler hanging for ever also
stops the USB subsys from enumerating any new USB devices, causes commands
like lsusb to hang, etc.
In practice this happens when unplugging some uas devices because the hub
code may see the device as needing a warm-reset and calls usb_reset_device
before seeing the disconnect. In this case uas_configure_endpoints fails
with -ENODEV. We do not want to print an error for this, so this commit
also silences the shost_printk for -ENODEV.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1531966
Cc: stable(a)vger.kernel.org
Fixes: 8d51444cdd06 ("uas: Not being able to alloc streams ... is an error")
Signed-off-by: Hans de Goede <hdegoede(a)redhat.com>
---
drivers/usb/storage/uas.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 5d04c40ee40a..5471422aa1ab 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -1077,9 +1077,13 @@ static int uas_post_reset(struct usb_interface *intf)
err = uas_configure_endpoints(devinfo);
if (err) {
- shost_printk(KERN_ERR, shost,
- "%s: alloc streams error %d after reset",
- __func__, err);
+ if (err != -ENODEV) {
+ shost_printk(KERN_ERR, shost,
+ "%s: alloc streams error %d after reset",
+ __func__, err);
+ }
+ /* So that scsi_remove_host in uas_disconnect does not hang */
+ scsi_unblock_requests(shost);
return 1;
}
--
2.14.3