Commit 53beb4d0 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: usb-audio: Copy string more safely



Replace strcpy() and sprintf() usages in the USB audio drivers with
the safer versions (strscpy() and scnprintf()) with the proper max
size evaluation.  Only for safety, no actual behavior change.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20250710100727.22653-103-tiwai@suse.de
parent f15be4dc
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -616,7 +616,8 @@ static void usb_audio_make_shortname(struct usb_device *dev,
	    usb_string(dev, dev->descriptor.iProduct,
		       card->shortname, sizeof(card->shortname)) <= 0) {
		/* no name available from anywhere, so use ID */
		sprintf(card->shortname, "USB Device %#04x:%#04x",
		scnprintf(card->shortname, sizeof(card->shortname),
			  "USB Device %#04x:%#04x",
			  USB_ID_VENDOR(chip->usb_id),
			  USB_ID_PRODUCT(chip->usb_id));
	}
@@ -757,7 +758,7 @@ static int snd_usb_audio_create(struct usb_interface *intf,
	card->private_free = snd_usb_audio_free;

	strscpy(card->driver, "USB-Audio");
	sprintf(component, "USB%04x:%04x",
	scnprintf(component, sizeof(component), "USB%04x:%04x",
		  USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
	snd_component_add(card, component);

+2 −1
Original line number Diff line number Diff line
@@ -1058,7 +1058,8 @@ static void set_fallback_rawmidi_names(struct snd_usb_midi2_interface *umidi)
			fill_ump_ep_name(ump, dev, dev->descriptor.iProduct);
		/* fill fallback name */
		if (!*ump->info.name)
			sprintf(ump->info.name, "USB MIDI %d", rmidi->index);
			scnprintf(ump->info.name, sizeof(ump->info.name),
				  "USB MIDI %d", rmidi->index);
		/* copy as rawmidi name if not set */
		if (!*ump->core.name)
			strscpy(ump->core.name, ump->info.name,
+11 −11
Original line number Diff line number Diff line
@@ -674,40 +674,40 @@ static int get_term_name(struct snd_usb_audio *chip, struct usb_audio_term *iter
			return 0;
		switch (iterm->type >> 16) {
		case UAC3_SELECTOR_UNIT:
			strcpy(name, "Selector");
			strscpy(name, "Selector", maxlen);
			return 8;
		case UAC3_PROCESSING_UNIT:
			strcpy(name, "Process Unit");
			strscpy(name, "Process Unit", maxlen);
			return 12;
		case UAC3_EXTENSION_UNIT:
			strcpy(name, "Ext Unit");
			strscpy(name, "Ext Unit", maxlen);
			return 8;
		case UAC3_MIXER_UNIT:
			strcpy(name, "Mixer");
			strscpy(name, "Mixer", maxlen);
			return 5;
		default:
			return sprintf(name, "Unit %d", iterm->id);
			return scnprintf(name, maxlen, "Unit %d", iterm->id);
		}
	}

	switch (iterm->type & 0xff00) {
	case 0x0100:
		strcpy(name, "PCM");
		strscpy(name, "PCM", maxlen);
		return 3;
	case 0x0200:
		strcpy(name, "Mic");
		strscpy(name, "Mic", maxlen);
		return 3;
	case 0x0400:
		strcpy(name, "Headset");
		strscpy(name, "Headset", maxlen);
		return 7;
	case 0x0500:
		strcpy(name, "Phone");
		strscpy(name, "Phone", maxlen);
		return 5;
	}

	for (names = iterm_names; names->type; names++) {
		if (names->type == iterm->type) {
			strcpy(name, names->name);
			strscpy(name, names->name, maxlen);
			return strlen(names->name);
		}
	}
@@ -2804,7 +2804,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid,
			len = get_term_name(state->chip, &iterm, namelist[i],
					    MAX_ITEM_NAME_LEN, 0);
		if (! len)
			sprintf(namelist[i], "Input %u", i);
			scnprintf(namelist[i], MAX_ITEM_NAME_LEN, "Input %u", i);
	}

	kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval);
+18 −13
Original line number Diff line number Diff line
@@ -357,21 +357,21 @@ static int scarlett_ctl_put(struct snd_kcontrol *kctl,
	return changed;
}

static void scarlett_generate_name(int i, char *dst, int offsets[])
static void scarlett_generate_name(int i, char *dst, size_t size, int offsets[])
{
	if (i > offsets[SCARLETT_OFFSET_MIX])
		sprintf(dst, "Mix %c",
		scnprintf(dst, size, "Mix %c",
			  'A'+(i - offsets[SCARLETT_OFFSET_MIX] - 1));
	else if (i > offsets[SCARLETT_OFFSET_ADAT])
		sprintf(dst, "ADAT %d", i - offsets[SCARLETT_OFFSET_ADAT]);
		scnprintf(dst, size, "ADAT %d", i - offsets[SCARLETT_OFFSET_ADAT]);
	else if (i > offsets[SCARLETT_OFFSET_SPDIF])
		sprintf(dst, "SPDIF %d", i - offsets[SCARLETT_OFFSET_SPDIF]);
		scnprintf(dst, size, "SPDIF %d", i - offsets[SCARLETT_OFFSET_SPDIF]);
	else if (i > offsets[SCARLETT_OFFSET_ANALOG])
		sprintf(dst, "Analog %d", i - offsets[SCARLETT_OFFSET_ANALOG]);
		scnprintf(dst, size, "Analog %d", i - offsets[SCARLETT_OFFSET_ANALOG]);
	else if (i > offsets[SCARLETT_OFFSET_PCM])
		sprintf(dst, "PCM %d", i - offsets[SCARLETT_OFFSET_PCM]);
		scnprintf(dst, size, "PCM %d", i - offsets[SCARLETT_OFFSET_PCM]);
	else
		sprintf(dst, "Off");
		scnprintf(dst, size, "Off");
}

static int scarlett_ctl_enum_dynamic_info(struct snd_kcontrol *kctl,
@@ -391,6 +391,7 @@ static int scarlett_ctl_enum_dynamic_info(struct snd_kcontrol *kctl,
	/* generate name dynamically based on item number and offset info */
	scarlett_generate_name(uinfo->value.enumerated.item,
			       uinfo->value.enumerated.name,
			       sizeof(uinfo->value.enumerated.name),
			       opt->offsets);

	return 0;
@@ -876,7 +877,8 @@ static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer,
				return err;
			break;
		case SCARLETT_SWITCH_IMPEDANCE:
			sprintf(mx, "Input %d Impedance Switch", ctl->num);
			scnprintf(mx, sizeof(mx),
				  "Input %d Impedance Switch", ctl->num);
			err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
					  scarlett_ctl_enum_resume, 0x01,
					  0x09, ctl->num, USB_MIXER_S16, 1, mx,
@@ -885,7 +887,8 @@ static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer,
				return err;
			break;
		case SCARLETT_SWITCH_PAD:
			sprintf(mx, "Input %d Pad Switch", ctl->num);
			scnprintf(mx, sizeof(mx),
				  "Input %d Pad Switch", ctl->num);
			err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
					  scarlett_ctl_enum_resume, 0x01,
					  0x0b, ctl->num, USB_MIXER_S16, 1, mx,
@@ -894,7 +897,8 @@ static int scarlett_controls_create_generic(struct usb_mixer_interface *mixer,
				return err;
			break;
		case SCARLETT_SWITCH_GAIN:
			sprintf(mx, "Input %d Gain Switch", ctl->num);
			scnprintf(mx, sizeof(mx),
				  "Input %d Gain Switch", ctl->num);
			err = add_new_ctl(mixer, &usb_scarlett_ctl_enum,
					  scarlett_ctl_enum_resume, 0x01,
					  0x08, ctl->num, USB_MIXER_S16, 1, mx,
@@ -960,7 +964,8 @@ int snd_scarlett_controls_create(struct usb_mixer_interface *mixer)
			return err;

		for (o = 0; o < info->matrix_out; o++) {
			sprintf(mx, "Matrix %02d Mix %c Playback Volume", i+1,
			scnprintf(mx, sizeof(mx),
				  "Matrix %02d Mix %c Playback Volume", i+1,
				  o+'A');
			err = add_new_ctl(mixer, &usb_scarlett_ctl,
					  scarlett_ctl_resume, 0x3c, 0x00,
+8 −6
Original line number Diff line number Diff line
@@ -7396,11 +7396,13 @@ static int scarlett2_mux_src_enum_ctl_info(struct snd_kcontrol *kctl,

			if (port_type == SCARLETT2_PORT_TYPE_MIX &&
			    item >= private->num_mix_out)
				sprintf(uinfo->value.enumerated.name,
				scnprintf(uinfo->value.enumerated.name,
					  sizeof(uinfo->value.enumerated.name),
					  port->dsp_src_descr,
					  item - private->num_mix_out + 1);
			else
				sprintf(uinfo->value.enumerated.name,
				scnprintf(uinfo->value.enumerated.name,
					  sizeof(uinfo->value.enumerated.name),
					  port->src_descr,
					  item + port->src_num_offset);

Loading