|
Takashi Iwai |
c7c3df |
From b088b53e20c7d09b5ab84c5688e609f478e5c417 Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
c7c3df |
From: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
c7c3df |
Date: Fri, 5 Jan 2018 16:15:33 +0100
|
|
Takashi Iwai |
c7c3df |
Subject: [PATCH] ALSA: aloop: Fix inconsistent format due to incomplete rule
|
|
Takashi Iwai |
c7c3df |
Git-commit: b088b53e20c7d09b5ab84c5688e609f478e5c417
|
|
Takashi Iwai |
c7c3df |
Patch-mainline: v4.15-rc8
|
|
Takashi Iwai |
c7c3df |
References: bsc#1051510
|
|
Takashi Iwai |
c7c3df |
|
|
Takashi Iwai |
c7c3df |
The extra hw constraint rule for the formats the aloop driver
|
|
Takashi Iwai |
c7c3df |
introduced has a slight flaw, where it doesn't return a positive value
|
|
Takashi Iwai |
c7c3df |
when the mask got changed. It came from the fact that it's basically
|
|
Takashi Iwai |
c7c3df |
a copy&paste from snd_hw_constraint_mask64(). The original code is
|
|
Takashi Iwai |
c7c3df |
supposed to be a single-shot and it modifies the mask bits only once
|
|
Takashi Iwai |
c7c3df |
and never after, while what we need for aloop is the dynamic hw rule
|
|
Takashi Iwai |
c7c3df |
that limits the mask bits.
|
|
Takashi Iwai |
c7c3df |
|
|
Takashi Iwai |
c7c3df |
This difference results in the inconsistent state, as the hw_refine
|
|
Takashi Iwai |
c7c3df |
doesn't apply the dependencies fully. The worse and surprisingly
|
|
Takashi Iwai |
c7c3df |
result is that it causes a crash in OSS emulation when multiple
|
|
Takashi Iwai |
c7c3df |
full-duplex reads/writes are performed concurrently (I leave why it
|
|
Takashi Iwai |
c7c3df |
triggers Oops to readers as a homework).
|
|
Takashi Iwai |
c7c3df |
|
|
Takashi Iwai |
c7c3df |
For fixing this, replace a few open-codes with the standard
|
|
Takashi Iwai |
c7c3df |
snd_mask_*() macros.
|
|
Takashi Iwai |
c7c3df |
|
|
Takashi Iwai |
c7c3df |
Reported-by: syzbot+3902b5220e8ca27889ca@syzkaller.appspotmail.com
|
|
Takashi Iwai |
c7c3df |
Fixes: b1c73fc8e697 ("ALSA: snd-aloop: Fix hw_params restrictions and checking")
|
|
Takashi Iwai |
c7c3df |
Cc: <stable@vger.kernel.org>
|
|
Takashi Iwai |
c7c3df |
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
c7c3df |
|
|
Takashi Iwai |
c7c3df |
---
|
|
Takashi Iwai |
c7c3df |
sound/drivers/aloop.c | 13 ++++++-------
|
|
Takashi Iwai |
c7c3df |
1 file changed, 6 insertions(+), 7 deletions(-)
|
|
Takashi Iwai |
c7c3df |
|
|
Takashi Iwai |
c7c3df |
--- a/sound/drivers/aloop.c
|
|
Takashi Iwai |
c7c3df |
+++ b/sound/drivers/aloop.c
|
|
Takashi Iwai |
c7c3df |
@@ -39,6 +39,7 @@
|
|
Takashi Iwai |
c7c3df |
#include <sound/core.h>
|
|
Takashi Iwai |
c7c3df |
#include <sound/control.h>
|
|
Takashi Iwai |
c7c3df |
#include <sound/pcm.h>
|
|
Takashi Iwai |
c7c3df |
+#include <sound/pcm_params.h>
|
|
Takashi Iwai |
c7c3df |
#include <sound/info.h>
|
|
Takashi Iwai |
c7c3df |
#include <sound/initval.h>
|
|
Takashi Iwai |
c7c3df |
|
|
Takashi Iwai |
c7c3df |
@@ -622,14 +623,12 @@ static int rule_format(struct snd_pcm_hw
|
|
Takashi Iwai |
c7c3df |
{
|
|
Takashi Iwai |
c7c3df |
|
|
Takashi Iwai |
c7c3df |
struct snd_pcm_hardware *hw = rule->private;
|
|
Takashi Iwai |
c7c3df |
- struct snd_mask *maskp = hw_param_mask(params, rule->var);
|
|
Takashi Iwai |
c7c3df |
+ struct snd_mask m;
|
|
Takashi Iwai |
c7c3df |
|
|
Takashi Iwai |
c7c3df |
- maskp->bits[0] &= (u_int32_t)hw->formats;
|
|
Takashi Iwai |
c7c3df |
- maskp->bits[1] &= (u_int32_t)(hw->formats >> 32);
|
|
Takashi Iwai |
c7c3df |
- memset(maskp->bits + 2, 0, (SNDRV_MASK_MAX-64) / 8); /* clear rest */
|
|
Takashi Iwai |
c7c3df |
- if (! maskp->bits[0] && ! maskp->bits[1])
|
|
Takashi Iwai |
c7c3df |
- return -EINVAL;
|
|
Takashi Iwai |
c7c3df |
- return 0;
|
|
Takashi Iwai |
c7c3df |
+ snd_mask_none(&m);
|
|
Takashi Iwai |
c7c3df |
+ m.bits[0] = (u_int32_t)hw->formats;
|
|
Takashi Iwai |
c7c3df |
+ m.bits[1] = (u_int32_t)(hw->formats >> 32);
|
|
Takashi Iwai |
c7c3df |
+ return snd_mask_refine(hw_param_mask(params, rule->var), &m);
|
|
Takashi Iwai |
c7c3df |
}
|
|
Takashi Iwai |
c7c3df |
|
|
Takashi Iwai |
c7c3df |
static int rule_rate(struct snd_pcm_hw_params *params,
|