stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Takashi Iwai <tiwai@suse.de>
Subject: [PATCH 3.18 25/46] ALSA: aloop: Fix racy hw constraints adjustment
Date: Mon, 15 Jan 2018 13:33:33 +0100	[thread overview]
Message-ID: <20180115123330.290335712@linuxfoundation.org> (raw)
In-Reply-To: <20180115123327.303455538@linuxfoundation.org>

3.18-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <tiwai@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@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@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;

  parent reply	other threads:[~2018-01-15 12:33 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-15 12:33 [PATCH 3.18 00/46] 3.18.92-stable review Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 01/46] kernel/acct.c: fix the acct->needcheck check in check_free_space() Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 02/46] crypto: n2 - cure use after free Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 03/46] fscache: Fix the default for fscache_maybe_release_page() Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 04/46] kernel/signal.c: protect the traced SIGNAL_UNKILLABLE tasks from SIGKILL Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 05/46] kernel/signal.c: protect the SIGNAL_UNKILLABLE tasks from !sig_kernel_only() signals Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 06/46] kernel/signal.c: remove the no longer needed SIGNAL_UNKILLABLE check in complete_signal() Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 07/46] Input: elantech - add new icbody type 15 Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 08/46] can: gs_usb: fix return value of the "set_bittiming" callback Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 09/46] IB/srpt: Disable RDMA access by the initiator Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 10/46] MIPS: Factor out NT_PRFPREG regset access helpers Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 11/46] MIPS: Guard against any partial write attempt with PTRACE_SETREGSET Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 12/46] MIPS: Consistently handle buffer counter " Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 13/46] MIPS: Fix an FCSR access API regression with NT_PRFPREG and MSA Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 14/46] MIPS: Disallow outsized PTRACE_SETREGSET NT_PRFPREG regset accesses Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 15/46] MIPS: Also verify sizeof `elf_fpreg_t with PTRACE_SETREGSET Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 16/46] perf/core: Fix concurrent sys_perf_event_open() vs. move_group race Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 17/46] kvm: vmx: Scrub hardware GPRs at VM-exit Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 18/46] x86/acpi: Handle SCI interrupts above legacy space gracefully Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 19/46] ALSA: pcm: Remove incorrect snd_BUG_ON() usages Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 20/46] ALSA: pcm: Add missing error checks in OSS emulation plugin builder Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 21/46] ALSA: pcm: Abort properly at pending signal in OSS read/write loops Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 22/46] ALSA: pcm: Allow aborting mutex lock at " Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 23/46] ALSA: aloop: Release cable upon open error path Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 24/46] ALSA: aloop: Fix inconsistent format due to incomplete rule Greg Kroah-Hartman
2018-01-15 12:33 ` Greg Kroah-Hartman [this message]
2018-01-15 12:33 ` [PATCH 3.18 26/46] x86/acpi: Reduce code duplication in mp_override_legacy_irq() Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 27/46] 8021q: fix a memory leak for VLAN 0 device Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 28/46] RDS: Heap OOB write in rds_message_alloc_sgs() Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 29/46] RDS: null pointer dereference in rds_atomic_free_op Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 30/46] sh_eth: fix TSU resource handling Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 31/46] sh_eth: fix SH7757 GEther initialization Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 32/46] net: stmmac: enable EEE in MII, GMII or RGMII only Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 33/46] crypto: algapi - fix NULL dereference in crypto_remove_spawns() Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 34/46] x86/microcode/intel: Extend BDW late-loading with a revision check Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 35/46] iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 36/46] target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 37/46] [PATCH] Revert "can: kvaser_usb: free buf in error paths" Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 39/46] USB: serial: cp210x: add new device ID ELV ALC 8xxx Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 40/46] usb: misc: usb3503: make sure reset is low for at least 100us Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 41/46] USB: fix usbmon BUG trigger Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 42/46] usbip: remove kernel addresses from usb device and urb debug msgs Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 43/46] staging: android: ashmem: fix a race condition in ASHMEM_SET_SIZE ioctl Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 44/46] Bluetooth: Prevent stack info leak from the EFS element Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 45/46] uas: ignore UAS for Norelsys NS1068(X) chips Greg Kroah-Hartman
2018-01-15 12:33 ` [PATCH 3.18 46/46] e1000e: Fix e1000_check_for_copper_link_ich8lan return value Greg Kroah-Hartman
2018-01-16 14:28 ` [PATCH 3.18 00/46] 3.18.92-stable review Guenter Roeck
2018-01-16 20:31 ` Shuah Khan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180115123330.290335712@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).