Commit f0ebbe9b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "A collection of small fixes for USB-audio, HD-audio and cs46xx.

  The USB-audio fixes are for out-of-bound accesses and a regression in
  the recent cleanup, while HD-audio fixes are usual device-specific
  quirks"

* tag 'sound-5.0-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound:
  ALSA: hda/realtek - Disable headset Mic VREF for headset mode of ALC225
  ALSA: hda/realtek - Add unplug function into unplug state of Headset Mode for ALC225
  ALSA: usb-audio: fix CM6206 register definitions
  ALSA: cs46xx: Potential NULL dereference in probe
  ALSA: hda/realtek - Support Dell headset mode for New AIO platform
  ALSA: usb-audio: Fix an out-of-bound read in create_composite_quirks
  ALSA: usb-audio: Always check descriptor sizes in parser code
  ALSA: usb-audio: Check mixer unit descriptors more strictly
  ALSA: usb-audio: Avoid access before bLength check in build_audio_procunit()
parents e7446be4 d1dd4211
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -903,6 +903,9 @@ int cs46xx_dsp_proc_done (struct snd_cs46xx *chip)
	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
	int i;

	if (!ins)
		return 0;

	snd_info_free_entry(ins->proc_sym_info_entry);
	ins->proc_sym_info_entry = NULL;

+17 −1
Original line number Diff line number Diff line
@@ -4102,6 +4102,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
	case 0x10ec0295:
	case 0x10ec0289:
	case 0x10ec0299:
		alc_process_coef_fw(codec, alc225_pre_hsmode);
		alc_process_coef_fw(codec, coef0225);
		break;
	case 0x10ec0867:
@@ -5440,6 +5441,13 @@ static void alc_fixup_headset_jack(struct hda_codec *codec,
	}
}

static void alc_fixup_disable_mic_vref(struct hda_codec *codec,
				  const struct hda_fixup *fix, int action)
{
	if (action == HDA_FIXUP_ACT_PRE_PROBE)
		snd_hda_codec_set_pin_target(codec, 0x19, PIN_VREFHIZ);
}

/* for hda_fixup_thinkpad_acpi() */
#include "thinkpad_helper.c"

@@ -5549,6 +5557,7 @@ enum {
	ALC293_FIXUP_LENOVO_SPK_NOISE,
	ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
	ALC255_FIXUP_DELL_SPK_NOISE,
	ALC225_FIXUP_DISABLE_MIC_VREF,
	ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
	ALC295_FIXUP_DISABLE_DAC3,
	ALC280_FIXUP_HP_HEADSET_MIC,
@@ -6268,6 +6277,12 @@ static const struct hda_fixup alc269_fixups[] = {
		.chained = true,
		.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
	},
	[ALC225_FIXUP_DISABLE_MIC_VREF] = {
		.type = HDA_FIXUP_FUNC,
		.v.func = alc_fixup_disable_mic_vref,
		.chained = true,
		.chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
	},
	[ALC225_FIXUP_DELL1_MIC_NO_PRESENCE] = {
		.type = HDA_FIXUP_VERBS,
		.v.verbs = (const struct hda_verb[]) {
@@ -6277,7 +6292,7 @@ static const struct hda_fixup alc269_fixups[] = {
			{}
		},
		.chained = true,
		.chain_id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE
		.chain_id = ALC225_FIXUP_DISABLE_MIC_VREF
	},
	[ALC280_FIXUP_HP_HEADSET_MIC] = {
		.type = HDA_FIXUP_FUNC,
@@ -6584,6 +6599,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
	SND_PCI_QUIRK(0x1028, 0x0871, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
	SND_PCI_QUIRK(0x1028, 0x0872, "Dell Precision 3630", ALC255_FIXUP_DELL_HEADSET_MIC),
	SND_PCI_QUIRK(0x1028, 0x0873, "Dell Precision 3930", ALC255_FIXUP_DUMMY_LINEOUT_VERB),
	SND_PCI_QUIRK(0x1028, 0x0935, "Dell", ALC274_FIXUP_DELL_AIO_LINEOUT_VERB),
	SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
	SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
+1 −1
Original line number Diff line number Diff line
@@ -246,7 +246,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
		h1 = snd_usb_find_csint_desc(host_iface->extra,
							 host_iface->extralen,
							 NULL, UAC_HEADER);
		if (!h1) {
		if (!h1 || h1->bLength < sizeof(*h1)) {
			dev_err(&dev->dev, "cannot find UAC_HEADER\n");
			return -EINVAL;
		}
+23 −6
Original line number Diff line number Diff line
@@ -753,8 +753,9 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
				       struct uac_mixer_unit_descriptor *desc)
{
	int mu_channels;
	void *c;

	if (desc->bLength < 11)
	if (desc->bLength < sizeof(*desc))
		return -EINVAL;
	if (!desc->bNrInPins)
		return -EINVAL;
@@ -763,6 +764,8 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
	case UAC_VERSION_1:
	case UAC_VERSION_2:
	default:
		if (desc->bLength < sizeof(*desc) + desc->bNrInPins + 1)
			return 0; /* no bmControls -> skip */
		mu_channels = uac_mixer_unit_bNrChannels(desc);
		break;
	case UAC_VERSION_3:
@@ -772,7 +775,11 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
	}

	if (!mu_channels)
		return -EINVAL;
		return 0;

	c = uac_mixer_unit_bmControls(desc, state->mixer->protocol);
	if (c - (void *)desc + (mu_channels - 1) / 8 >= desc->bLength)
		return 0; /* no bmControls -> skip */

	return mu_channels;
}
@@ -944,7 +951,7 @@ static int check_input_term(struct mixer_build *state, int id,
				struct uac_mixer_unit_descriptor *d = p1;

				err = uac_mixer_unit_get_channels(state, d);
				if (err < 0)
				if (err <= 0)
					return err;

				term->channels = err;
@@ -2068,11 +2075,15 @@ static int parse_audio_input_terminal(struct mixer_build *state, int unitid,

	if (state->mixer->protocol == UAC_VERSION_2) {
		struct uac2_input_terminal_descriptor *d_v2 = raw_desc;
		if (d_v2->bLength < sizeof(*d_v2))
			return -EINVAL;
		control = UAC2_TE_CONNECTOR;
		term_id = d_v2->bTerminalID;
		bmctls = le16_to_cpu(d_v2->bmControls);
	} else if (state->mixer->protocol == UAC_VERSION_3) {
		struct uac3_input_terminal_descriptor *d_v3 = raw_desc;
		if (d_v3->bLength < sizeof(*d_v3))
			return -EINVAL;
		control = UAC3_TE_INSERTION;
		term_id = d_v3->bTerminalID;
		bmctls = le32_to_cpu(d_v3->bmControls);
@@ -2118,7 +2129,7 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid,
		if (err < 0)
			continue;
		/* no bmControls field (e.g. Maya44) -> ignore */
		if (desc->bLength <= 10 + input_pins)
		if (!num_outs)
			continue;
		err = check_input_term(state, desc->baSourceID[pin], &iterm);
		if (err < 0)
@@ -2314,7 +2325,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid,
				char *name)
{
	struct uac_processing_unit_descriptor *desc = raw_desc;
	int num_ins = desc->bNrInPins;
	int num_ins;
	struct usb_mixer_elem_info *cval;
	struct snd_kcontrol *kctl;
	int i, err, nameid, type, len;
@@ -2329,7 +2340,13 @@ static int build_audio_procunit(struct mixer_build *state, int unitid,
		0, NULL, default_value_info
	};

	if (desc->bLength < 13 || desc->bLength < 13 + num_ins ||
	if (desc->bLength < 13) {
		usb_audio_err(state->chip, "invalid %s descriptor (id %d)\n", name, unitid);
		return -EINVAL;
	}

	num_ins = desc->bNrInPins;
	if (desc->bLength < 13 + num_ins ||
	    desc->bLength < num_ins + uac_processing_unit_bControlSize(desc, state->mixer->protocol)) {
		usb_audio_err(state->chip, "invalid %s descriptor (id %d)\n", name, unitid);
		return -EINVAL;
+6 −0
Original line number Diff line number Diff line
@@ -3326,6 +3326,9 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
					}
				}
			},
			{
				.ifnum = -1
			},
		}
	}
},
@@ -3369,6 +3372,9 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
					}
				}
			},
			{
				.ifnum = -1
			},
		}
	}
},
Loading