ALSA: hda - add bounds checking for the codec command fields
authorWu Fengguang <fengguang.wu@intel.com>
Fri, 17 Jul 2009 08:49:19 +0000 (16:49 +0800)
committerTakashi Iwai <tiwai@suse.de>
Fri, 17 Jul 2009 09:18:21 +0000 (11:18 +0200)
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>
sound/pci/hda/hda_codec.c

index ec352c6ae49a023e1b15a7ee867b8993056659d7..d9d326297834ed6346b8b129d63b4e2e66b84a16 100644 (file)
@@ -150,7 +150,14 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
 {
        u32 val;
 
-       val = (u32)(codec->addr & 0x0f) << 28;
+       if ((codec->addr & ~0xf) | (direct & ~1) | (nid & ~0x7f) |
+           (verb & ~0xfff) | (parm & ~0xff)) {
+               printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n",
+                      codec->addr, direct, nid, verb, parm);
+               return ~0;
+       }
+
+       val = (u32)codec->addr << 28;
        val |= (u32)direct << 27;
        val |= (u32)nid << 20;
        val |= verb << 8;
@@ -167,6 +174,9 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
        struct hda_bus *bus = codec->bus;
        int err;
 
+       if (cmd == ~0)
+               return -1;
+
        if (res)
                *res = -1;
  again: