--- /dev/null
+From f9d94b57e30fd1575b4935045b32d738668aa74b Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 24 Apr 2018 08:01:48 +0200
+Subject: ALSA: asihpi: Hardening for potential Spectre v1
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit f9d94b57e30fd1575b4935045b32d738668aa74b upstream.
+
+As recently Smatch suggested, a couple of places in ASIHPI driver may
+expand the array directly from the user-space value with speculation:
+ sound/pci/asihpi/hpimsginit.c:70 hpi_init_response() warn: potential spectre issue 'res_size' (local cap)
+ sound/pci/asihpi/hpioctl.c:189 asihpi_hpi_ioctl() warn: potential spectre issue 'adapters'
+
+This patch puts array_index_nospec() for hardening against them.
+
+BugLink: https://marc.info/?l=linux-kernel&m=152411496503418&w=2
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/asihpi/hpimsginit.c | 13 +++++++++----
+ sound/pci/asihpi/hpioctl.c | 4 +++-
+ 2 files changed, 12 insertions(+), 5 deletions(-)
+
+--- a/sound/pci/asihpi/hpimsginit.c
++++ b/sound/pci/asihpi/hpimsginit.c
+@@ -23,6 +23,7 @@
+
+ #include "hpi_internal.h"
+ #include "hpimsginit.h"
++#include <linux/nospec.h>
+
+ /* The actual message size for each object type */
+ static u16 msg_size[HPI_OBJ_MAXINDEX + 1] = HPI_MESSAGE_SIZE_BY_OBJECT;
+@@ -39,10 +40,12 @@ static void hpi_init_message(struct hpi_
+ {
+ u16 size;
+
+- if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
++ if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
++ object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
+ size = msg_size[object];
+- else
++ } else {
+ size = sizeof(*phm);
++ }
+
+ memset(phm, 0, size);
+ phm->size = size;
+@@ -66,10 +69,12 @@ void hpi_init_response(struct hpi_respon
+ {
+ u16 size;
+
+- if ((object > 0) && (object <= HPI_OBJ_MAXINDEX))
++ if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
++ object = array_index_nospec(object, HPI_OBJ_MAXINDEX + 1);
+ size = res_size[object];
+- else
++ } else {
+ size = sizeof(*phr);
++ }
+
+ memset(phr, 0, sizeof(*phr));
+ phr->size = size;
+--- a/sound/pci/asihpi/hpioctl.c
++++ b/sound/pci/asihpi/hpioctl.c
+@@ -33,6 +33,7 @@
+ #include <linux/stringify.h>
+ #include <linux/module.h>
+ #include <linux/vmalloc.h>
++#include <linux/nospec.h>
+
+ #ifdef MODULE_FIRMWARE
+ MODULE_FIRMWARE("asihpi/dsp5000.bin");
+@@ -182,7 +183,8 @@ long asihpi_hpi_ioctl(struct file *file,
+ struct hpi_adapter *pa = NULL;
+
+ if (hm->h.adapter_index < ARRAY_SIZE(adapters))
+- pa = &adapters[hm->h.adapter_index];
++ pa = &adapters[array_index_nospec(hm->h.adapter_index,
++ ARRAY_SIZE(adapters))];
+
+ if (!pa || !pa->adapter || !pa->adapter->type) {
+ hpi_init_response(&hr->r0, hm->h.object,
--- /dev/null
+From 088e861edffb84879cf0c0d1b02eda078c3a0ffe Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 24 Apr 2018 07:45:56 +0200
+Subject: ALSA: control: Hardening for potential Spectre v1
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 088e861edffb84879cf0c0d1b02eda078c3a0ffe upstream.
+
+As recently Smatch suggested, a few places in ALSA control core codes
+may expand the array directly from the user-space value with
+speculation:
+
+ sound/core/control.c:1003 snd_ctl_elem_lock() warn: potential spectre issue 'kctl->vd'
+ sound/core/control.c:1031 snd_ctl_elem_unlock() warn: potential spectre issue 'kctl->vd'
+ sound/core/control.c:844 snd_ctl_elem_info() warn: potential spectre issue 'kctl->vd'
+ sound/core/control.c:891 snd_ctl_elem_read() warn: potential spectre issue 'kctl->vd'
+ sound/core/control.c:939 snd_ctl_elem_write() warn: potential spectre issue 'kctl->vd'
+
+Although all these seem doing only the first load without further
+reference, we may want to stay in a safer side, so hardening with
+array_index_nospec() would still make sense.
+
+In this patch, we put array_index_nospec() to the common
+snd_ctl_get_ioff*() helpers instead of each caller. These helpers are
+also referred from some drivers, too, and basically all usages are to
+calculate the array index from the user-space value, hence it's better
+to cover there.
+
+BugLink: https://marc.info/?l=linux-kernel&m=152411496503418&w=2
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/sound/control.h | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/include/sound/control.h
++++ b/include/sound/control.h
+@@ -22,6 +22,7 @@
+ *
+ */
+
++#include <linux/nospec.h>
+ #include <sound/asound.h>
+
+ #define snd_kcontrol_chip(kcontrol) ((kcontrol)->private_data)
+@@ -147,12 +148,14 @@ int snd_ctl_get_preferred_subdevice(stru
+
+ static inline unsigned int snd_ctl_get_ioffnum(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
+ {
+- return id->numid - kctl->id.numid;
++ unsigned int ioff = id->numid - kctl->id.numid;
++ return array_index_nospec(ioff, kctl->count);
+ }
+
+ static inline unsigned int snd_ctl_get_ioffidx(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
+ {
+- return id->index - kctl->id.index;
++ unsigned int ioff = id->index - kctl->id.index;
++ return array_index_nospec(ioff, kctl->count);
+ }
+
+ static inline unsigned int snd_ctl_get_ioff(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id)
--- /dev/null
+From f853dcaae2f5bbe021161e421bd1576845bae8f6 Mon Sep 17 00:00:00 2001
+From: David Henningsson <diwic@ubuntu.com>
+Date: Sat, 21 Apr 2018 14:57:40 +0200
+Subject: ALSA: core: Report audio_tstamp in snd_pcm_sync_ptr
+
+From: David Henningsson <diwic@ubuntu.com>
+
+commit f853dcaae2f5bbe021161e421bd1576845bae8f6 upstream.
+
+It looks like a simple mistake that this struct member
+was forgotten.
+
+Audio_tstamp isn't used much, and on some archs (such as x86) this
+ioctl is not used by default, so that might be the reason why this
+has slipped for so long.
+
+Fixes: 4eeaaeaea1ce ("ALSA: core: add hooks for audio timestamps")
+Signed-off-by: David Henningsson <diwic@ubuntu.com>
+Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Cc: <stable@vger.kernel.org> # v3.8+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/pcm_native.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -2729,6 +2729,7 @@ static int snd_pcm_sync_ptr(struct snd_p
+ sync_ptr.s.status.hw_ptr = status->hw_ptr;
+ sync_ptr.s.status.tstamp = status->tstamp;
+ sync_ptr.s.status.suspended_state = status->suspended_state;
++ sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
+ snd_pcm_stream_unlock_irq(substream);
+ if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
+ return -EFAULT;
--- /dev/null
+From 69fa6f19b95597618ab30438a27b67ad93daa7c7 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 24 Apr 2018 07:50:50 +0200
+Subject: ALSA: hda: Hardening for potential Spectre v1
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 69fa6f19b95597618ab30438a27b67ad93daa7c7 upstream.
+
+As recently Smatch suggested, one place in HD-audio hwdep ioctl codes
+may expand the array directly from the user-space value with
+speculation:
+ sound/pci/hda/hda_local.h:467 get_wcaps() warn: potential spectre issue 'codec->wcaps'
+
+As get_wcaps() itself is a fairly frequently called inline function,
+and there is only one single call with a user-space value, we replace
+only the latter one to open-code locally with array_index_nospec()
+hardening in this patch.
+
+BugLink: https://marc.info/?l=linux-kernel&m=152411496503418&w=2
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_hwdep.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/sound/pci/hda/hda_hwdep.c
++++ b/sound/pci/hda/hda_hwdep.c
+@@ -21,6 +21,7 @@
+ #include <linux/init.h>
+ #include <linux/slab.h>
+ #include <linux/compat.h>
++#include <linux/nospec.h>
+ #include <sound/core.h>
+ #include "hda_codec.h"
+ #include "hda_local.h"
+@@ -51,7 +52,16 @@ static int get_wcap_ioctl(struct hda_cod
+
+ if (get_user(verb, &arg->verb))
+ return -EFAULT;
+- res = get_wcaps(codec, verb >> 24);
++ /* open-code get_wcaps(verb>>24) with nospec */
++ verb >>= 24;
++ if (verb < codec->core.start_nid ||
++ verb >= codec->core.start_nid + codec->core.num_nodes) {
++ res = 0;
++ } else {
++ verb -= codec->core.start_nid;
++ verb = array_index_nospec(verb, codec->core.num_nodes);
++ res = codec->wcaps[verb];
++ }
+ if (put_user(res, &arg->res))
+ return -EFAULT;
+ return 0;
--- /dev/null
+From ea04a1dbf8b1d6af759d58e705636fde48583f8f Mon Sep 17 00:00:00 2001
+From: Kailang Yang <kailang@realtek.com>
+Date: Wed, 25 Apr 2018 15:31:52 +0800
+Subject: ALSA: hda/realtek - Add some fixes for ALC233
+
+From: Kailang Yang <kailang@realtek.com>
+
+commit ea04a1dbf8b1d6af759d58e705636fde48583f8f upstream.
+
+Fill COEF to change EAPD to verb control.
+Assigned codec type.
+
+This is an additional fix over 92f974df3460 ("ALSA: hda/realtek - New
+vendor ID for ALC233").
+
+[ More notes:
+ according to Kailang, the chip is 10ec:0235 bonding for ALC233b,
+ which is equivalent with ALC255. It's only used for Lenovo.
+ The chip needs no alc_process_coef_fw() for headset unlike ALC255. ]
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -329,6 +329,7 @@ static void alc_fill_eapd_coef(struct hd
+ break;
+ case 0x10ec0225:
+ case 0x10ec0233:
++ case 0x10ec0235:
+ case 0x10ec0236:
+ case 0x10ec0255:
+ case 0x10ec0256:
+@@ -6359,6 +6360,7 @@ static int patch_alc269(struct hda_codec
+ case 0x10ec0298:
+ spec->codec_variant = ALC269_TYPE_ALC298;
+ break;
++ case 0x10ec0235:
+ case 0x10ec0255:
+ spec->codec_variant = ALC269_TYPE_ALC255;
+ break;
--- /dev/null
+From ab3b8e5159b5335c81ba2d09ee5054d4a1b5a7a6 Mon Sep 17 00:00:00 2001
+From: Kailang Yang <kailang@realtek.com>
+Date: Wed, 25 Apr 2018 16:05:27 +0800
+Subject: ALSA: hda/realtek - Update ALC255 depop optimize
+
+From: Kailang Yang <kailang@realtek.com>
+
+commit ab3b8e5159b5335c81ba2d09ee5054d4a1b5a7a6 upstream.
+
+Add ALC255 its own depop functions for alc_init and alc_shutup.
+Assign it to ALC256 usage.
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6363,6 +6363,8 @@ static int patch_alc269(struct hda_codec
+ case 0x10ec0235:
+ case 0x10ec0255:
+ spec->codec_variant = ALC269_TYPE_ALC255;
++ spec->shutup = alc256_shutup;
++ spec->init_hook = alc256_init;
+ break;
+ case 0x10ec0236:
+ case 0x10ec0256:
--- /dev/null
+From 10513142a7114d251670361ad40cba2c61403406 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 24 Apr 2018 08:03:14 +0200
+Subject: ALSA: hdspm: Hardening for potential Spectre v1
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 10513142a7114d251670361ad40cba2c61403406 upstream.
+
+As recently Smatch suggested, a couple of places in HDSP MADI driver
+may expand the array directly from the user-space value with
+speculation:
+ sound/pci/rme9652/hdspm.c:5717 snd_hdspm_channel_info() warn: potential spectre issue 'hdspm->channel_map_out' (local cap)
+ sound/pci/rme9652/hdspm.c:5734 snd_hdspm_channel_info() warn: potential spectre issue 'hdspm->channel_map_in' (local cap)
+
+This patch puts array_index_nospec() for hardening against them.
+
+BugLink: https://marc.info/?l=linux-kernel&m=152411496503418&w=2
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/rme9652/hdspm.c | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+--- a/sound/pci/rme9652/hdspm.c
++++ b/sound/pci/rme9652/hdspm.c
+@@ -137,6 +137,7 @@
+ #include <linux/pci.h>
+ #include <linux/math64.h>
+ #include <linux/io.h>
++#include <linux/nospec.h>
+
+ #include <sound/core.h>
+ #include <sound/control.h>
+@@ -5692,40 +5693,43 @@ static int snd_hdspm_channel_info(struct
+ struct snd_pcm_channel_info *info)
+ {
+ struct hdspm *hdspm = snd_pcm_substream_chip(substream);
++ unsigned int channel = info->channel;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+- if (snd_BUG_ON(info->channel >= hdspm->max_channels_out)) {
++ if (snd_BUG_ON(channel >= hdspm->max_channels_out)) {
+ dev_info(hdspm->card->dev,
+ "snd_hdspm_channel_info: output channel out of range (%d)\n",
+- info->channel);
++ channel);
+ return -EINVAL;
+ }
+
+- if (hdspm->channel_map_out[info->channel] < 0) {
++ channel = array_index_nospec(channel, hdspm->max_channels_out);
++ if (hdspm->channel_map_out[channel] < 0) {
+ dev_info(hdspm->card->dev,
+ "snd_hdspm_channel_info: output channel %d mapped out\n",
+- info->channel);
++ channel);
+ return -EINVAL;
+ }
+
+- info->offset = hdspm->channel_map_out[info->channel] *
++ info->offset = hdspm->channel_map_out[channel] *
+ HDSPM_CHANNEL_BUFFER_BYTES;
+ } else {
+- if (snd_BUG_ON(info->channel >= hdspm->max_channels_in)) {
++ if (snd_BUG_ON(channel >= hdspm->max_channels_in)) {
+ dev_info(hdspm->card->dev,
+ "snd_hdspm_channel_info: input channel out of range (%d)\n",
+- info->channel);
++ channel);
+ return -EINVAL;
+ }
+
+- if (hdspm->channel_map_in[info->channel] < 0) {
++ channel = array_index_nospec(channel, hdspm->max_channels_in);
++ if (hdspm->channel_map_in[channel] < 0) {
+ dev_info(hdspm->card->dev,
+ "snd_hdspm_channel_info: input channel %d mapped out\n",
+- info->channel);
++ channel);
+ return -EINVAL;
+ }
+
+- info->offset = hdspm->channel_map_in[info->channel] *
++ info->offset = hdspm->channel_map_in[channel] *
+ HDSPM_CHANNEL_BUFFER_BYTES;
+ }
+
--- /dev/null
+From f526afcd8f71945c23ce581d7864ace93de8a4f7 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 24 Apr 2018 08:04:41 +0200
+Subject: ALSA: rme9652: Hardening for potential Spectre v1
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit f526afcd8f71945c23ce581d7864ace93de8a4f7 upstream.
+
+As recently Smatch suggested, one place in RME9652 driver may expand
+the array directly from the user-space value with speculation:
+ sound/pci/rme9652/rme9652.c:2074 snd_rme9652_channel_info() warn: potential spectre issue 'rme9652->channel_map' (local cap)
+
+This patch puts array_index_nospec() for hardening against it.
+
+BugLink: https://marc.info/?l=linux-kernel&m=152411496503418&w=2
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/rme9652/rme9652.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/sound/pci/rme9652/rme9652.c
++++ b/sound/pci/rme9652/rme9652.c
+@@ -26,6 +26,7 @@
+ #include <linux/pci.h>
+ #include <linux/module.h>
+ #include <linux/io.h>
++#include <linux/nospec.h>
+
+ #include <sound/core.h>
+ #include <sound/control.h>
+@@ -2036,9 +2037,10 @@ static int snd_rme9652_channel_info(stru
+ if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS))
+ return -EINVAL;
+
+- if ((chn = rme9652->channel_map[info->channel]) < 0) {
++ chn = rme9652->channel_map[array_index_nospec(info->channel,
++ RME9652_NCHANNELS)];
++ if (chn < 0)
+ return -EINVAL;
+- }
+
+ info->offset = chn * RME9652_CHANNEL_BUFFER_BYTES;
+ info->first = 0;
--- /dev/null
+From f5e94b4c6ebdabe0f602d796e0430180927521a0 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 24 Apr 2018 07:26:59 +0200
+Subject: ALSA: seq: oss: Fix unbalanced use lock for synth MIDI device
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit f5e94b4c6ebdabe0f602d796e0430180927521a0 upstream.
+
+When get_synthdev() is called for a MIDI device, it returns the fixed
+midi_synth_dev without the use refcounting. OTOH, the caller is
+supposed to unreference unconditionally after the usage, so this would
+lead to unbalanced refcount.
+
+This patch corrects the behavior and keep up the refcount balance also
+for the MIDI synth device.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/seq/oss/seq_oss_synth.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/sound/core/seq/oss/seq_oss_synth.c
++++ b/sound/core/seq/oss/seq_oss_synth.c
+@@ -363,10 +363,14 @@ get_synthdev(struct seq_oss_devinfo *dp,
+ return NULL;
+ if (! dp->synths[dev].opened)
+ return NULL;
+- if (dp->synths[dev].is_midi)
+- return &midi_synth_dev;
+- if ((rec = get_sdev(dev)) == NULL)
+- return NULL;
++ if (dp->synths[dev].is_midi) {
++ rec = &midi_synth_dev;
++ snd_use_lock_use(&rec->use_lock);
++ } else {
++ rec = get_sdev(dev);
++ if (!rec)
++ return NULL;
++ }
+ if (! rec->opened) {
+ snd_use_lock_free(&rec->use_lock);
+ return NULL;
--- /dev/null
+From 8d218dd8116695ecda7164f97631c069938aa22e Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 24 Apr 2018 07:31:54 +0200
+Subject: ALSA: seq: oss: Hardening for potential Spectre v1
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 8d218dd8116695ecda7164f97631c069938aa22e upstream.
+
+As Smatch recently suggested, a few places in OSS sequencer codes may
+expand the array directly from the user-space value with speculation,
+namely there are a significant amount of references to either
+info->ch[] or dp->synths[] array:
+
+ sound/core/seq/oss/seq_oss_event.c:315 note_on_event() warn: potential spectre issue 'info->ch' (local cap)
+ sound/core/seq/oss/seq_oss_event.c:362 note_off_event() warn: potential spectre issue 'info->ch' (local cap)
+ sound/core/seq/oss/seq_oss_synth.c:470 snd_seq_oss_synth_load_patch() warn: potential spectre issue 'dp->synths' (local cap)
+ sound/core/seq/oss/seq_oss_event.c:293 note_on_event() warn: potential spectre issue 'dp->synths'
+ sound/core/seq/oss/seq_oss_event.c:353 note_off_event() warn: potential spectre issue 'dp->synths'
+ sound/core/seq/oss/seq_oss_synth.c:506 snd_seq_oss_synth_sysex() warn: potential spectre issue 'dp->synths'
+ sound/core/seq/oss/seq_oss_synth.c:580 snd_seq_oss_synth_ioctl() warn: potential spectre issue 'dp->synths'
+
+Although all these seem doing only the first load without further
+reference, we may want to stay in a safer side, so hardening with
+array_index_nospec() would still make sense.
+
+We may put array_index_nospec() at each place, but here we take a
+different approach:
+
+- For dp->synths[], change the helpers to retrieve seq_oss_synthinfo
+ pointer directly instead of the array expansion at each place
+
+- For info->ch[], harden in a normal way, as there are only a couple
+ of places
+
+As a result, the existing helper, snd_seq_oss_synth_is_valid() is
+replaced with snd_seq_oss_synth_info(). Also, we cover MIDI device
+where a similar array expansion is done, too, although it wasn't
+reported by Smatch.
+
+BugLink: https://marc.info/?l=linux-kernel&m=152411496503418&w=2
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/seq/oss/seq_oss_event.c | 15 ++++---
+ sound/core/seq/oss/seq_oss_midi.c | 2
+ sound/core/seq/oss/seq_oss_synth.c | 75 ++++++++++++++++++++-----------------
+ sound/core/seq/oss/seq_oss_synth.h | 3 -
+ 4 files changed, 55 insertions(+), 40 deletions(-)
+
+--- a/sound/core/seq/oss/seq_oss_event.c
++++ b/sound/core/seq/oss/seq_oss_event.c
+@@ -26,6 +26,7 @@
+ #include <sound/seq_oss_legacy.h>
+ #include "seq_oss_readq.h"
+ #include "seq_oss_writeq.h"
++#include <linux/nospec.h>
+
+
+ /*
+@@ -287,10 +288,10 @@ note_on_event(struct seq_oss_devinfo *dp
+ {
+ struct seq_oss_synthinfo *info;
+
+- if (!snd_seq_oss_synth_is_valid(dp, dev))
++ info = snd_seq_oss_synth_info(dp, dev);
++ if (!info)
+ return -ENXIO;
+
+- info = &dp->synths[dev];
+ switch (info->arg.event_passing) {
+ case SNDRV_SEQ_OSS_PROCESS_EVENTS:
+ if (! info->ch || ch < 0 || ch >= info->nr_voices) {
+@@ -298,6 +299,7 @@ note_on_event(struct seq_oss_devinfo *dp
+ return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
+ }
+
++ ch = array_index_nospec(ch, info->nr_voices);
+ if (note == 255 && info->ch[ch].note >= 0) {
+ /* volume control */
+ int type;
+@@ -347,10 +349,10 @@ note_off_event(struct seq_oss_devinfo *d
+ {
+ struct seq_oss_synthinfo *info;
+
+- if (!snd_seq_oss_synth_is_valid(dp, dev))
++ info = snd_seq_oss_synth_info(dp, dev);
++ if (!info)
+ return -ENXIO;
+
+- info = &dp->synths[dev];
+ switch (info->arg.event_passing) {
+ case SNDRV_SEQ_OSS_PROCESS_EVENTS:
+ if (! info->ch || ch < 0 || ch >= info->nr_voices) {
+@@ -358,6 +360,7 @@ note_off_event(struct seq_oss_devinfo *d
+ return set_note_event(dp, dev, SNDRV_SEQ_EVENT_NOTEON, ch, note, vel, ev);
+ }
+
++ ch = array_index_nospec(ch, info->nr_voices);
+ if (info->ch[ch].note >= 0) {
+ note = info->ch[ch].note;
+ info->ch[ch].vel = 0;
+@@ -381,7 +384,7 @@ note_off_event(struct seq_oss_devinfo *d
+ static int
+ set_note_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int note, int vel, struct snd_seq_event *ev)
+ {
+- if (! snd_seq_oss_synth_is_valid(dp, dev))
++ if (!snd_seq_oss_synth_info(dp, dev))
+ return -ENXIO;
+
+ ev->type = type;
+@@ -399,7 +402,7 @@ set_note_event(struct seq_oss_devinfo *d
+ static int
+ set_control_event(struct seq_oss_devinfo *dp, int dev, int type, int ch, int param, int val, struct snd_seq_event *ev)
+ {
+- if (! snd_seq_oss_synth_is_valid(dp, dev))
++ if (!snd_seq_oss_synth_info(dp, dev))
+ return -ENXIO;
+
+ ev->type = type;
+--- a/sound/core/seq/oss/seq_oss_midi.c
++++ b/sound/core/seq/oss/seq_oss_midi.c
+@@ -29,6 +29,7 @@
+ #include "../seq_lock.h"
+ #include <linux/init.h>
+ #include <linux/slab.h>
++#include <linux/nospec.h>
+
+
+ /*
+@@ -315,6 +316,7 @@ get_mididev(struct seq_oss_devinfo *dp,
+ {
+ if (dev < 0 || dev >= dp->max_mididev)
+ return NULL;
++ dev = array_index_nospec(dev, dp->max_mididev);
+ return get_mdev(dev);
+ }
+
+--- a/sound/core/seq/oss/seq_oss_synth.c
++++ b/sound/core/seq/oss/seq_oss_synth.c
+@@ -26,6 +26,7 @@
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/slab.h>
++#include <linux/nospec.h>
+
+ /*
+ * constants
+@@ -339,17 +340,13 @@ snd_seq_oss_synth_cleanup(struct seq_oss
+ dp->max_synthdev = 0;
+ }
+
+-/*
+- * check if the specified device is MIDI mapped device
+- */
+-static int
+-is_midi_dev(struct seq_oss_devinfo *dp, int dev)
++static struct seq_oss_synthinfo *
++get_synthinfo_nospec(struct seq_oss_devinfo *dp, int dev)
+ {
+ if (dev < 0 || dev >= dp->max_synthdev)
+- return 0;
+- if (dp->synths[dev].is_midi)
+- return 1;
+- return 0;
++ return NULL;
++ dev = array_index_nospec(dev, SNDRV_SEQ_OSS_MAX_SYNTH_DEVS);
++ return &dp->synths[dev];
+ }
+
+ /*
+@@ -359,11 +356,13 @@ static struct seq_oss_synth *
+ get_synthdev(struct seq_oss_devinfo *dp, int dev)
+ {
+ struct seq_oss_synth *rec;
+- if (dev < 0 || dev >= dp->max_synthdev)
++ struct seq_oss_synthinfo *info = get_synthinfo_nospec(dp, dev);
++
++ if (!info)
+ return NULL;
+- if (! dp->synths[dev].opened)
++ if (!info->opened)
+ return NULL;
+- if (dp->synths[dev].is_midi) {
++ if (info->is_midi) {
+ rec = &midi_synth_dev;
+ snd_use_lock_use(&rec->use_lock);
+ } else {
+@@ -406,10 +405,8 @@ snd_seq_oss_synth_reset(struct seq_oss_d
+ struct seq_oss_synth *rec;
+ struct seq_oss_synthinfo *info;
+
+- if (snd_BUG_ON(dev < 0 || dev >= dp->max_synthdev))
+- return;
+- info = &dp->synths[dev];
+- if (! info->opened)
++ info = get_synthinfo_nospec(dp, dev);
++ if (!info || !info->opened)
+ return;
+ if (info->sysex)
+ info->sysex->len = 0; /* reset sysex */
+@@ -458,12 +455,14 @@ snd_seq_oss_synth_load_patch(struct seq_
+ const char __user *buf, int p, int c)
+ {
+ struct seq_oss_synth *rec;
++ struct seq_oss_synthinfo *info;
+ int rc;
+
+- if (dev < 0 || dev >= dp->max_synthdev)
++ info = get_synthinfo_nospec(dp, dev);
++ if (!info)
+ return -ENXIO;
+
+- if (is_midi_dev(dp, dev))
++ if (info->is_midi)
+ return 0;
+ if ((rec = get_synthdev(dp, dev)) == NULL)
+ return -ENXIO;
+@@ -471,24 +470,25 @@ snd_seq_oss_synth_load_patch(struct seq_
+ if (rec->oper.load_patch == NULL)
+ rc = -ENXIO;
+ else
+- rc = rec->oper.load_patch(&dp->synths[dev].arg, fmt, buf, p, c);
++ rc = rec->oper.load_patch(&info->arg, fmt, buf, p, c);
+ snd_use_lock_free(&rec->use_lock);
+ return rc;
+ }
+
+ /*
+- * check if the device is valid synth device
++ * check if the device is valid synth device and return the synth info
+ */
+-int
+-snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev)
++struct seq_oss_synthinfo *
++snd_seq_oss_synth_info(struct seq_oss_devinfo *dp, int dev)
+ {
+ struct seq_oss_synth *rec;
++
+ rec = get_synthdev(dp, dev);
+ if (rec) {
+ snd_use_lock_free(&rec->use_lock);
+- return 1;
++ return get_synthinfo_nospec(dp, dev);
+ }
+- return 0;
++ return NULL;
+ }
+
+
+@@ -503,16 +503,18 @@ snd_seq_oss_synth_sysex(struct seq_oss_d
+ int i, send;
+ unsigned char *dest;
+ struct seq_oss_synth_sysex *sysex;
++ struct seq_oss_synthinfo *info;
+
+- if (! snd_seq_oss_synth_is_valid(dp, dev))
++ info = snd_seq_oss_synth_info(dp, dev);
++ if (!info)
+ return -ENXIO;
+
+- sysex = dp->synths[dev].sysex;
++ sysex = info->sysex;
+ if (sysex == NULL) {
+ sysex = kzalloc(sizeof(*sysex), GFP_KERNEL);
+ if (sysex == NULL)
+ return -ENOMEM;
+- dp->synths[dev].sysex = sysex;
++ info->sysex = sysex;
+ }
+
+ send = 0;
+@@ -557,10 +559,12 @@ snd_seq_oss_synth_sysex(struct seq_oss_d
+ int
+ snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev)
+ {
+- if (! snd_seq_oss_synth_is_valid(dp, dev))
++ struct seq_oss_synthinfo *info = snd_seq_oss_synth_info(dp, dev);
++
++ if (!info)
+ return -EINVAL;
+- snd_seq_oss_fill_addr(dp, ev, dp->synths[dev].arg.addr.client,
+- dp->synths[dev].arg.addr.port);
++ snd_seq_oss_fill_addr(dp, ev, info->arg.addr.client,
++ info->arg.addr.port);
+ return 0;
+ }
+
+@@ -572,16 +576,18 @@ int
+ snd_seq_oss_synth_ioctl(struct seq_oss_devinfo *dp, int dev, unsigned int cmd, unsigned long addr)
+ {
+ struct seq_oss_synth *rec;
++ struct seq_oss_synthinfo *info;
+ int rc;
+
+- if (is_midi_dev(dp, dev))
++ info = get_synthinfo_nospec(dp, dev);
++ if (!info || info->is_midi)
+ return -ENXIO;
+ if ((rec = get_synthdev(dp, dev)) == NULL)
+ return -ENXIO;
+ if (rec->oper.ioctl == NULL)
+ rc = -ENXIO;
+ else
+- rc = rec->oper.ioctl(&dp->synths[dev].arg, cmd, addr);
++ rc = rec->oper.ioctl(&info->arg, cmd, addr);
+ snd_use_lock_free(&rec->use_lock);
+ return rc;
+ }
+@@ -593,7 +599,10 @@ snd_seq_oss_synth_ioctl(struct seq_oss_d
+ int
+ snd_seq_oss_synth_raw_event(struct seq_oss_devinfo *dp, int dev, unsigned char *data, struct snd_seq_event *ev)
+ {
+- if (! snd_seq_oss_synth_is_valid(dp, dev) || is_midi_dev(dp, dev))
++ struct seq_oss_synthinfo *info;
++
++ info = snd_seq_oss_synth_info(dp, dev);
++ if (!info || info->is_midi)
+ return -ENXIO;
+ ev->type = SNDRV_SEQ_EVENT_OSS;
+ memcpy(ev->data.raw8.d, data, 8);
+--- a/sound/core/seq/oss/seq_oss_synth.h
++++ b/sound/core/seq/oss/seq_oss_synth.h
+@@ -37,7 +37,8 @@ void snd_seq_oss_synth_cleanup(struct se
+ void snd_seq_oss_synth_reset(struct seq_oss_devinfo *dp, int dev);
+ int snd_seq_oss_synth_load_patch(struct seq_oss_devinfo *dp, int dev, int fmt,
+ const char __user *buf, int p, int c);
+-int snd_seq_oss_synth_is_valid(struct seq_oss_devinfo *dp, int dev);
++struct seq_oss_synthinfo *snd_seq_oss_synth_info(struct seq_oss_devinfo *dp,
++ int dev);
+ int snd_seq_oss_synth_sysex(struct seq_oss_devinfo *dp, int dev, unsigned char *buf,
+ struct snd_seq_event *ev);
+ int snd_seq_oss_synth_addr(struct seq_oss_devinfo *dp, int dev, struct snd_seq_event *ev);
--- /dev/null
+From 6510bbc88e3258631831ade49033537081950605 Mon Sep 17 00:00:00 2001
+From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
+Date: Thu, 1 Mar 2018 14:39:39 +0100
+Subject: mtd: cfi: cmdset_0001: Do not allow read/write to suspend erase block.
+
+From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
+
+commit 6510bbc88e3258631831ade49033537081950605 upstream.
+
+Currently it is possible to read and/or write to suspend EB's.
+Writing /dev/mtdX or /dev/mtdblockX from several processes may
+break the flash state machine.
+
+Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/chips/cfi_cmdset_0001.c | 16 +++++++++++-----
+ include/linux/mtd/flashchip.h | 1 +
+ 2 files changed, 12 insertions(+), 5 deletions(-)
+
+--- a/drivers/mtd/chips/cfi_cmdset_0001.c
++++ b/drivers/mtd/chips/cfi_cmdset_0001.c
+@@ -831,21 +831,25 @@ static int chip_ready (struct map_info *
+ (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
+ goto sleep;
+
++ /* Do not allow suspend iff read/write to EB address */
++ if ((adr & chip->in_progress_block_mask) ==
++ chip->in_progress_block_addr)
++ goto sleep;
+
+ /* Erase suspend */
+- map_write(map, CMD(0xB0), adr);
++ map_write(map, CMD(0xB0), chip->in_progress_block_addr);
+
+ /* If the flash has finished erasing, then 'erase suspend'
+ * appears to make some (28F320) flash devices switch to
+ * 'read' mode. Make sure that we switch to 'read status'
+ * mode so we get the right data. --rmk
+ */
+- map_write(map, CMD(0x70), adr);
++ map_write(map, CMD(0x70), chip->in_progress_block_addr);
+ chip->oldstate = FL_ERASING;
+ chip->state = FL_ERASE_SUSPENDING;
+ chip->erase_suspended = 1;
+ for (;;) {
+- status = map_read(map, adr);
++ status = map_read(map, chip->in_progress_block_addr);
+ if (map_word_andequal(map, status, status_OK, status_OK))
+ break;
+
+@@ -1041,8 +1045,8 @@ static void put_chip(struct map_info *ma
+ sending the 0x70 (Read Status) command to an erasing
+ chip and expecting it to be ignored, that's what we
+ do. */
+- map_write(map, CMD(0xd0), adr);
+- map_write(map, CMD(0x70), adr);
++ map_write(map, CMD(0xd0), chip->in_progress_block_addr);
++ map_write(map, CMD(0x70), chip->in_progress_block_addr);
+ chip->oldstate = FL_READY;
+ chip->state = FL_ERASING;
+ break;
+@@ -1933,6 +1937,8 @@ static int __xipram do_erase_oneblock(st
+ map_write(map, CMD(0xD0), adr);
+ chip->state = FL_ERASING;
+ chip->erase_suspended = 0;
++ chip->in_progress_block_addr = adr;
++ chip->in_progress_block_mask = ~(len - 1);
+
+ ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
+ adr, len,
+--- a/include/linux/mtd/flashchip.h
++++ b/include/linux/mtd/flashchip.h
+@@ -85,6 +85,7 @@ struct flchip {
+ unsigned int write_suspended:1;
+ unsigned int erase_suspended:1;
+ unsigned long in_progress_block_addr;
++ unsigned long in_progress_block_mask;
+
+ struct mutex mutex;
+ wait_queue_head_t wq; /* Wait on here when we're waiting for the chip
--- /dev/null
+From 46a16a2283f9e678a4e26829175e0c37a5191860 Mon Sep 17 00:00:00 2001
+From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
+Date: Thu, 1 Mar 2018 14:39:40 +0100
+Subject: mtd: cfi: cmdset_0001: Workaround Micron Erase suspend bug.
+
+From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
+
+commit 46a16a2283f9e678a4e26829175e0c37a5191860 upstream.
+
+Some Micron chips does not work well wrt Erase suspend for
+boot blocks. This avoids the issue by not allowing Erase suspend
+for the boot blocks for the 28F00AP30(1GBit) chip.
+
+Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/chips/cfi_cmdset_0001.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/drivers/mtd/chips/cfi_cmdset_0001.c
++++ b/drivers/mtd/chips/cfi_cmdset_0001.c
+@@ -45,6 +45,7 @@
+ #define I82802AB 0x00ad
+ #define I82802AC 0x00ac
+ #define PF38F4476 0x881c
++#define M28F00AP30 0x8963
+ /* STMicroelectronics chips */
+ #define M50LPW080 0x002F
+ #define M50FLW080A 0x0080
+@@ -375,6 +376,17 @@ static void cfi_fixup_major_minor(struct
+ extp->MinorVersion = '1';
+ }
+
++static int cfi_is_micron_28F00AP30(struct cfi_private *cfi, struct flchip *chip)
++{
++ /*
++ * Micron(was Numonyx) 1Gbit bottom boot are buggy w.r.t
++ * Erase Supend for their small Erase Blocks(0x8000)
++ */
++ if (cfi->mfr == CFI_MFR_INTEL && cfi->id == M28F00AP30)
++ return 1;
++ return 0;
++}
++
+ static inline struct cfi_pri_intelext *
+ read_pri_intelext(struct map_info *map, __u16 adr)
+ {
+@@ -836,6 +848,11 @@ static int chip_ready (struct map_info *
+ chip->in_progress_block_addr)
+ goto sleep;
+
++ /* do not suspend small EBs, buggy Micron Chips */
++ if (cfi_is_micron_28F00AP30(cfi, chip) &&
++ (chip->in_progress_block_mask == ~(0x8000-1)))
++ goto sleep;
++
+ /* Erase suspend */
+ map_write(map, CMD(0xB0), chip->in_progress_block_addr);
+
--- /dev/null
+From 7b70eb14392a7cf505f9b358d06c33b5af73d1e7 Mon Sep 17 00:00:00 2001
+From: Joakim Tjernlund <joakim.tjernlund@infinera.com>
+Date: Thu, 1 Mar 2018 14:39:41 +0100
+Subject: mtd: cfi: cmdset_0002: Do not allow read/write to suspend erase block.
+
+From: Joakim Tjernlund <joakim.tjernlund@infinera.com>
+
+commit 7b70eb14392a7cf505f9b358d06c33b5af73d1e7 upstream.
+
+Currently it is possible to read and/or write to suspend EB's.
+Writing /dev/mtdX or /dev/mtdblockX from several processes may
+break the flash state machine.
+
+Taken from cfi_cmdset_0001 driver.
+
+Signed-off-by: Joakim Tjernlund <joakim.tjernlund@infinera.com>
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/chips/cfi_cmdset_0002.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/mtd/chips/cfi_cmdset_0002.c
++++ b/drivers/mtd/chips/cfi_cmdset_0002.c
+@@ -812,9 +812,10 @@ static int get_chip(struct map_info *map
+ (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
+ goto sleep;
+
+- /* We could check to see if we're trying to access the sector
+- * that is currently being erased. However, no user will try
+- * anything like that so we just wait for the timeout. */
++ /* Do not allow suspend iff read/write to EB address */
++ if ((adr & chip->in_progress_block_mask) ==
++ chip->in_progress_block_addr)
++ goto sleep;
+
+ /* Erase suspend */
+ /* It's harmless to issue the Erase-Suspend and Erase-Resume
+@@ -2263,6 +2264,7 @@ static int __xipram do_erase_chip(struct
+ chip->state = FL_ERASING;
+ chip->erase_suspended = 0;
+ chip->in_progress_block_addr = adr;
++ chip->in_progress_block_mask = ~(map->size - 1);
+
+ INVALIDATE_CACHE_UDELAY(map, chip,
+ adr, map->size,
+@@ -2352,6 +2354,7 @@ static int __xipram do_erase_oneblock(st
+ chip->state = FL_ERASING;
+ chip->erase_suspended = 0;
+ chip->in_progress_block_addr = adr;
++ chip->in_progress_block_mask = ~(len - 1);
+
+ INVALIDATE_CACHE_UDELAY(map, chip,
+ adr, len,
alsa-dice-fix-oui-for-tc-group.patch
alsa-dice-fix-error-path-to-destroy-initialized-stream-data.patch
alsa-opl3-hardening-for-potential-spectre-v1.patch
+alsa-asihpi-hardening-for-potential-spectre-v1.patch
+alsa-hdspm-hardening-for-potential-spectre-v1.patch
+alsa-rme9652-hardening-for-potential-spectre-v1.patch
+alsa-control-hardening-for-potential-spectre-v1.patch
+alsa-core-report-audio_tstamp-in-snd_pcm_sync_ptr.patch
+alsa-seq-oss-fix-unbalanced-use-lock-for-synth-midi-device.patch
+alsa-seq-oss-hardening-for-potential-spectre-v1.patch
+alsa-hda-hardening-for-potential-spectre-v1.patch
+alsa-hda-realtek-add-some-fixes-for-alc233.patch
+alsa-hda-realtek-update-alc255-depop-optimize.patch
+mtd-cfi-cmdset_0001-do-not-allow-read-write-to-suspend-erase-block.patch
+mtd-cfi-cmdset_0001-workaround-micron-erase-suspend-bug.patch
+mtd-cfi-cmdset_0002-do-not-allow-read-write-to-suspend-erase-block.patch