3.16.60-rc1 review patch.  If anyone has any objections, please let me know.

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

From: Takashi Iwai <ti...@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.carpen...@oracle.com>
Signed-off-by: Takashi Iwai <ti...@suse.de>
[bwh: Backported to 3.16: adjust context]
Signed-off-by: Ben Hutchings <b...@decadent.org.uk>
---
 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
@@ -35,6 +35,7 @@ Common Linux HPI ioctl and module probe/
 #include <linux/pci.h>
 #include <linux/stringify.h>
 #include <linux/module.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,

Reply via email to