ALSA: rawmidi: Fix potential Spectre v1 vulnerability [Linux 3.16.72]

This Linux kernel change "ALSA: rawmidi: Fix potential Spectre v1 vulnerability" is included in the Linux 3.16.72 release. This change is authored by Gustavo A. R. Silva <gustavo [at] embeddedor.com> on Wed Mar 20 16:15:24 2019 -0500. The commit for this change in Linux stable tree is 748cfcf (patch) which is from upstream commit 2b1d9c8. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 2b1d9c8.

ALSA: rawmidi: Fix potential Spectre v1 vulnerability

commit 2b1d9c8f87235f593826b9cf46ec10247741fff9 upstream.

info->stream is indirectly controlled by user-space, hence leading to
a potential exploitation of the Spectre variant 1 vulnerability.

This issue was detected with the help of Smatch:

sound/core/rawmidi.c:604 __snd_rawmidi_info_select() warn: potential spectre issue 'rmidi->streams' [r] (local cap)

Fix this by sanitizing info->stream before using it to index
rmidi->streams.

Notice that given that speculation windows are large, the policy is
to kill the speculation on the first load and not worry if it can be
completed with a dependent load/store [1].

[1] https://lore.kernel.org/lkml/[email protected]/

Signed-off-by: Gustavo A. R. Silva <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: Ben Hutchings <[email protected]>

There are 2 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 sound/core/rawmidi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 2bd5b85..09e05c0 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -29,6 +29,7 @@
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/nospec.h>
 #include <sound/rawmidi.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -601,6 +602,7 @@ static int __snd_rawmidi_info_select(struct snd_card *card,
        return -ENXIO;
    if (info->stream < 0 || info->stream > 1)
        return -EINVAL;
+   info->stream = array_index_nospec(info->stream, 2);
    pstr = &rmidi->streams[info->stream];
    if (pstr->substream_count == 0)
        return -ENOENT;

Leave a Reply

Your email address will not be published. Required fields are marked *