aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWu Fengguang <fengguang.wu@intel.com>2009-07-17 04:49:19 -0400
committerTakashi Iwai <tiwai@suse.de>2009-07-17 05:18:21 -0400
commit6430aeeb30b478d4ef25f988b1fde6f6ae83adb5 (patch)
treed9888582ec7a4bb9c6e7f3a52be543c408c2d742
parent9176b672c29baaa94cdff4eedf1350a3b553d9ea (diff)
ALSA: hda - add bounds checking for the codec command fields
A recent bug involves passing auto detected >0x7f NID to codec command, creating an invalid codec addr field, and finally lead to cmd timeout and fall back into single command mode. Jaroslav fixed that bug in alc880_parse_auto_config(). It would be safer to further check the bounds of all cmd fields. Cc: Jaroslav Kysela <perex@perex.cz> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_codec.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index ec352c6ae49a..d9d326297834 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -150,7 +150,14 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
150{ 150{
151 u32 val; 151 u32 val;
152 152
153 val = (u32)(codec->addr & 0x0f) << 28; 153 if ((codec->addr & ~0xf) | (direct & ~1) | (nid & ~0x7f) |
154 (verb & ~0xfff) | (parm & ~0xff)) {
155 printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n",
156 codec->addr, direct, nid, verb, parm);
157 return ~0;
158 }
159
160 val = (u32)codec->addr << 28;
154 val |= (u32)direct << 27; 161 val |= (u32)direct << 27;
155 val |= (u32)nid << 20; 162 val |= (u32)nid << 20;
156 val |= verb << 8; 163 val |= verb << 8;
@@ -167,6 +174,9 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
167 struct hda_bus *bus = codec->bus; 174 struct hda_bus *bus = codec->bus;
168 int err; 175 int err;
169 176
177 if (cmd == ~0)
178 return -1;
179
170 if (res) 180 if (res)
171 *res = -1; 181 *res = -1;
172 again: 182 again: