diff options
author | Takashi Iwai <tiwai@suse.de> | 2018-04-24 07:50:50 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-05-01 15:13:07 -0700 |
commit | 69bd3f023770c0d6b223e7418a73246a38b60365 (patch) | |
tree | 7e3026feb0b68e01e9facf86d6e580993c65dfcd /sound/pci/hda/hda_hwdep.c | |
parent | 1e0130b609174a97331e17631883bded42852224 (diff) |
ALSA: hda: Hardening for potential Spectre v1
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>
Diffstat (limited to 'sound/pci/hda/hda_hwdep.c')
-rw-r--r-- | sound/pci/hda/hda_hwdep.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index 57df06e76968..cc009a4a3d1d 100644 --- 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_codec *codec, 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; |