Commit dac1acc3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'sound-4.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "A collection of small fixes, all deserved for stable.

  Two are about core API fixes for the bugs that were triggered by
  ever-growing fuzzers, while others are driver-specific fixes"

* tag 'sound-4.17-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: pcm: Check PCM state at xfern compat ioctl
  ALSA: aloop: Add missing cable lock to ctl API callbacks
  ALSA: dice: fix kernel NULL pointer dereference due to invalid calculation for array index
  ALSA: seq: Fix races at MIDI encoding in snd_virmidi_output_trigger()
  ALSA: hda - Fix incorrect usage of IS_REACHABLE()
parents 15042698 f13876e2
...@@ -423,6 +423,8 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, ...@@ -423,6 +423,8 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
return -ENOTTY; return -ENOTTY;
if (substream->stream != dir) if (substream->stream != dir)
return -EINVAL; return -EINVAL;
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN)
return -EBADFD;
if ((ch = substream->runtime->channels) > 128) if ((ch = substream->runtime->channels) > 128)
return -EINVAL; return -EINVAL;
......
...@@ -174,12 +174,12 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, ...@@ -174,12 +174,12 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
} }
return; return;
} }
spin_lock_irqsave(&substream->runtime->lock, flags);
if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) {
if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0)
return; goto out;
vmidi->event.type = SNDRV_SEQ_EVENT_NONE; vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
} }
spin_lock_irqsave(&substream->runtime->lock, flags);
while (1) { while (1) {
count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf)); count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf));
if (count <= 0) if (count <= 0)
......
...@@ -831,9 +831,11 @@ static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol, ...@@ -831,9 +831,11 @@ static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol,
{ {
struct loopback *loopback = snd_kcontrol_chip(kcontrol); struct loopback *loopback = snd_kcontrol_chip(kcontrol);
mutex_lock(&loopback->cable_lock);
ucontrol->value.integer.value[0] = ucontrol->value.integer.value[0] =
loopback->setup[kcontrol->id.subdevice] loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].rate_shift; [kcontrol->id.device].rate_shift;
mutex_unlock(&loopback->cable_lock);
return 0; return 0;
} }
...@@ -865,9 +867,11 @@ static int loopback_notify_get(struct snd_kcontrol *kcontrol, ...@@ -865,9 +867,11 @@ static int loopback_notify_get(struct snd_kcontrol *kcontrol,
{ {
struct loopback *loopback = snd_kcontrol_chip(kcontrol); struct loopback *loopback = snd_kcontrol_chip(kcontrol);
mutex_lock(&loopback->cable_lock);
ucontrol->value.integer.value[0] = ucontrol->value.integer.value[0] =
loopback->setup[kcontrol->id.subdevice] loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].notify; [kcontrol->id.device].notify;
mutex_unlock(&loopback->cable_lock);
return 0; return 0;
} }
...@@ -879,12 +883,14 @@ static int loopback_notify_put(struct snd_kcontrol *kcontrol, ...@@ -879,12 +883,14 @@ static int loopback_notify_put(struct snd_kcontrol *kcontrol,
int change = 0; int change = 0;
val = ucontrol->value.integer.value[0] ? 1 : 0; val = ucontrol->value.integer.value[0] ? 1 : 0;
mutex_lock(&loopback->cable_lock);
if (val != loopback->setup[kcontrol->id.subdevice] if (val != loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].notify) { [kcontrol->id.device].notify) {
loopback->setup[kcontrol->id.subdevice] loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].notify = val; [kcontrol->id.device].notify = val;
change = 1; change = 1;
} }
mutex_unlock(&loopback->cable_lock);
return change; return change;
} }
...@@ -892,15 +898,18 @@ static int loopback_active_get(struct snd_kcontrol *kcontrol, ...@@ -892,15 +898,18 @@ static int loopback_active_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
struct loopback *loopback = snd_kcontrol_chip(kcontrol); struct loopback *loopback = snd_kcontrol_chip(kcontrol);
struct loopback_cable *cable = loopback->cables struct loopback_cable *cable;
[kcontrol->id.subdevice][kcontrol->id.device ^ 1];
unsigned int val = 0; unsigned int val = 0;
mutex_lock(&loopback->cable_lock);
cable = loopback->cables[kcontrol->id.subdevice][kcontrol->id.device ^ 1];
if (cable != NULL) { if (cable != NULL) {
unsigned int running = cable->running ^ cable->pause; unsigned int running = cable->running ^ cable->pause;
val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0; val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0;
} }
mutex_unlock(&loopback->cable_lock);
ucontrol->value.integer.value[0] = val; ucontrol->value.integer.value[0] = val;
return 0; return 0;
} }
...@@ -943,9 +952,11 @@ static int loopback_rate_get(struct snd_kcontrol *kcontrol, ...@@ -943,9 +952,11 @@ static int loopback_rate_get(struct snd_kcontrol *kcontrol,
{ {
struct loopback *loopback = snd_kcontrol_chip(kcontrol); struct loopback *loopback = snd_kcontrol_chip(kcontrol);
mutex_lock(&loopback->cable_lock);
ucontrol->value.integer.value[0] = ucontrol->value.integer.value[0] =
loopback->setup[kcontrol->id.subdevice] loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].rate; [kcontrol->id.device].rate;
mutex_unlock(&loopback->cable_lock);
return 0; return 0;
} }
...@@ -965,9 +976,11 @@ static int loopback_channels_get(struct snd_kcontrol *kcontrol, ...@@ -965,9 +976,11 @@ static int loopback_channels_get(struct snd_kcontrol *kcontrol,
{ {
struct loopback *loopback = snd_kcontrol_chip(kcontrol); struct loopback *loopback = snd_kcontrol_chip(kcontrol);
mutex_lock(&loopback->cable_lock);
ucontrol->value.integer.value[0] = ucontrol->value.integer.value[0] =
loopback->setup[kcontrol->id.subdevice] loopback->setup[kcontrol->id.subdevice]
[kcontrol->id.device].channels; [kcontrol->id.device].channels;
mutex_unlock(&loopback->cable_lock);
return 0; return 0;
} }
......
...@@ -773,8 +773,6 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context, ...@@ -773,8 +773,6 @@ static void amdtp_stream_first_callback(struct fw_iso_context *context,
u32 cycle; u32 cycle;
unsigned int packets; unsigned int packets;
s->max_payload_length = amdtp_stream_get_max_payload(s);
/* /*
* For in-stream, first packet has come. * For in-stream, first packet has come.
* For out-stream, prepared to transmit first packet * For out-stream, prepared to transmit first packet
...@@ -879,6 +877,9 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed) ...@@ -879,6 +877,9 @@ int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed)
amdtp_stream_update(s); amdtp_stream_update(s);
if (s->direction == AMDTP_IN_STREAM)
s->max_payload_length = amdtp_stream_get_max_payload(s);
if (s->flags & CIP_NO_HEADER) if (s->flags & CIP_NO_HEADER)
s->tag = TAG_NO_CIP_HEADER; s->tag = TAG_NO_CIP_HEADER;
else else
......
...@@ -3832,7 +3832,7 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, ...@@ -3832,7 +3832,7 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec,
} }
} }
#if IS_REACHABLE(INPUT) #if IS_REACHABLE(CONFIG_INPUT)
static void gpio2_mic_hotkey_event(struct hda_codec *codec, static void gpio2_mic_hotkey_event(struct hda_codec *codec,
struct hda_jack_callback *event) struct hda_jack_callback *event)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment