Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20250710100727.22653-103-tiwai@suse.de

+48 -38
+6 -5
sound/usb/card.c
··· 616 616 usb_string(dev, dev->descriptor.iProduct, 617 617 card->shortname, sizeof(card->shortname)) <= 0) { 618 618 /* no name available from anywhere, so use ID */ 619 - sprintf(card->shortname, "USB Device %#04x:%#04x", 620 - USB_ID_VENDOR(chip->usb_id), 621 - USB_ID_PRODUCT(chip->usb_id)); 619 + scnprintf(card->shortname, sizeof(card->shortname), 620 + "USB Device %#04x:%#04x", 621 + USB_ID_VENDOR(chip->usb_id), 622 + USB_ID_PRODUCT(chip->usb_id)); 622 623 } 623 624 624 625 strim(card->shortname); ··· 758 757 card->private_free = snd_usb_audio_free; 759 758 760 759 strscpy(card->driver, "USB-Audio"); 761 - sprintf(component, "USB%04x:%04x", 762 - USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id)); 760 + scnprintf(component, sizeof(component), "USB%04x:%04x", 761 + USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id)); 763 762 snd_component_add(card, component); 764 763 765 764 usb_audio_make_shortname(dev, chip, quirk);
+2 -1
sound/usb/midi2.c
··· 1058 1058 fill_ump_ep_name(ump, dev, dev->descriptor.iProduct); 1059 1059 /* fill fallback name */ 1060 1060 if (!*ump->info.name) 1061 - sprintf(ump->info.name, "USB MIDI %d", rmidi->index); 1061 + scnprintf(ump->info.name, sizeof(ump->info.name), 1062 + "USB MIDI %d", rmidi->index); 1062 1063 /* copy as rawmidi name if not set */ 1063 1064 if (!*ump->core.name) 1064 1065 strscpy(ump->core.name, ump->info.name,
+11 -11
sound/usb/mixer.c
··· 674 674 return 0; 675 675 switch (iterm->type >> 16) { 676 676 case UAC3_SELECTOR_UNIT: 677 - strcpy(name, "Selector"); 677 + strscpy(name, "Selector", maxlen); 678 678 return 8; 679 679 case UAC3_PROCESSING_UNIT: 680 - strcpy(name, "Process Unit"); 680 + strscpy(name, "Process Unit", maxlen); 681 681 return 12; 682 682 case UAC3_EXTENSION_UNIT: 683 - strcpy(name, "Ext Unit"); 683 + strscpy(name, "Ext Unit", maxlen); 684 684 return 8; 685 685 case UAC3_MIXER_UNIT: 686 - strcpy(name, "Mixer"); 686 + strscpy(name, "Mixer", maxlen); 687 687 return 5; 688 688 default: 689 - return sprintf(name, "Unit %d", iterm->id); 689 + return scnprintf(name, maxlen, "Unit %d", iterm->id); 690 690 } 691 691 } 692 692 693 693 switch (iterm->type & 0xff00) { 694 694 case 0x0100: 695 - strcpy(name, "PCM"); 695 + strscpy(name, "PCM", maxlen); 696 696 return 3; 697 697 case 0x0200: 698 - strcpy(name, "Mic"); 698 + strscpy(name, "Mic", maxlen); 699 699 return 3; 700 700 case 0x0400: 701 - strcpy(name, "Headset"); 701 + strscpy(name, "Headset", maxlen); 702 702 return 7; 703 703 case 0x0500: 704 - strcpy(name, "Phone"); 704 + strscpy(name, "Phone", maxlen); 705 705 return 5; 706 706 } 707 707 708 708 for (names = iterm_names; names->type; names++) { 709 709 if (names->type == iterm->type) { 710 - strcpy(name, names->name); 710 + strscpy(name, names->name, maxlen); 711 711 return strlen(names->name); 712 712 } 713 713 } ··· 2804 2804 len = get_term_name(state->chip, &iterm, namelist[i], 2805 2805 MAX_ITEM_NAME_LEN, 0); 2806 2806 if (! len) 2807 - sprintf(namelist[i], "Input %u", i); 2807 + scnprintf(namelist[i], MAX_ITEM_NAME_LEN, "Input %u", i); 2808 2808 } 2809 2809 2810 2810 kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval);
+18 -13
sound/usb/mixer_scarlett.c
··· 357 357 return changed; 358 358 } 359 359 360 - static void scarlett_generate_name(int i, char *dst, int offsets[]) 360 + static void scarlett_generate_name(int i, char *dst, size_t size, int offsets[]) 361 361 { 362 362 if (i > offsets[SCARLETT_OFFSET_MIX]) 363 - sprintf(dst, "Mix %c", 364 - 'A'+(i - offsets[SCARLETT_OFFSET_MIX] - 1)); 363 + scnprintf(dst, size, "Mix %c", 364 + 'A'+(i - offsets[SCARLETT_OFFSET_MIX] - 1)); 365 365 else if (i > offsets[SCARLETT_OFFSET_ADAT]) 366 - sprintf(dst, "ADAT %d", i - offsets[SCARLETT_OFFSET_ADAT]); 366 + scnprintf(dst, size, "ADAT %d", i - offsets[SCARLETT_OFFSET_ADAT]); 367 367 else if (i > offsets[SCARLETT_OFFSET_SPDIF]) 368 - sprintf(dst, "SPDIF %d", i - offsets[SCARLETT_OFFSET_SPDIF]); 368 + scnprintf(dst, size, "SPDIF %d", i - offsets[SCARLETT_OFFSET_SPDIF]); 369 369 else if (i > offsets[SCARLETT_OFFSET_ANALOG]) 370 - sprintf(dst, "Analog %d", i - offsets[SCARLETT_OFFSET_ANALOG]); 370 + scnprintf(dst, size, "Analog %d", i - offsets[SCARLETT_OFFSET_ANALOG]); 371 371 else if (i > offsets[SCARLETT_OFFSET_PCM]) 372 - sprintf(dst, "PCM %d", i - offsets[SCARLETT_OFFSET_PCM]); 372 + scnprintf(dst, size, "PCM %d", i - offsets[SCARLETT_OFFSET_PCM]); 373 373 else 374 - sprintf(dst, "Off"); 374 + scnprintf(dst, size, "Off"); 375 375 } 376 376 377 377 static int scarlett_ctl_enum_dynamic_info(struct snd_kcontrol *kctl, ··· 391 391 /* generate name dynamically based on item number and offset info */ 392 392 scarlett_generate_name(uinfo->value.enumerated.item, 393 393 uinfo->value.enumerated.name, 394 + sizeof(uinfo->value.enumerated.name), 394 395 opt->offsets); 395 396 396 397 return 0; ··· 877 876 return err; 878 877 break; 879 878 case SCARLETT_SWITCH_IMPEDANCE: 880 - sprintf(mx, "Input %d Impedance Switch", ctl->num); 879 + scnprintf(mx, sizeof(mx), 880 + "Input %d Impedance Switch", ctl->num); 881 881 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum, 882 882 scarlett_ctl_enum_resume, 0x01, 883 883 0x09, ctl->num, USB_MIXER_S16, 1, mx, ··· 887 885 return err; 888 886 break; 889 887 case SCARLETT_SWITCH_PAD: 890 - sprintf(mx, "Input %d Pad Switch", ctl->num); 888 + scnprintf(mx, sizeof(mx), 889 + "Input %d Pad Switch", ctl->num); 891 890 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum, 892 891 scarlett_ctl_enum_resume, 0x01, 893 892 0x0b, ctl->num, USB_MIXER_S16, 1, mx, ··· 897 894 return err; 898 895 break; 899 896 case SCARLETT_SWITCH_GAIN: 900 - sprintf(mx, "Input %d Gain Switch", ctl->num); 897 + scnprintf(mx, sizeof(mx), 898 + "Input %d Gain Switch", ctl->num); 901 899 err = add_new_ctl(mixer, &usb_scarlett_ctl_enum, 902 900 scarlett_ctl_enum_resume, 0x01, 903 901 0x08, ctl->num, USB_MIXER_S16, 1, mx, ··· 964 960 return err; 965 961 966 962 for (o = 0; o < info->matrix_out; o++) { 967 - sprintf(mx, "Matrix %02d Mix %c Playback Volume", i+1, 968 - o+'A'); 963 + scnprintf(mx, sizeof(mx), 964 + "Matrix %02d Mix %c Playback Volume", i+1, 965 + o+'A'); 969 966 err = add_new_ctl(mixer, &usb_scarlett_ctl, 970 967 scarlett_ctl_resume, 0x3c, 0x00, 971 968 (i << 3) + (o & 0x07), USB_MIXER_S16,
+8 -6
sound/usb/mixer_scarlett2.c
··· 7396 7396 7397 7397 if (port_type == SCARLETT2_PORT_TYPE_MIX && 7398 7398 item >= private->num_mix_out) 7399 - sprintf(uinfo->value.enumerated.name, 7400 - port->dsp_src_descr, 7401 - item - private->num_mix_out + 1); 7399 + scnprintf(uinfo->value.enumerated.name, 7400 + sizeof(uinfo->value.enumerated.name), 7401 + port->dsp_src_descr, 7402 + item - private->num_mix_out + 1); 7402 7403 else 7403 - sprintf(uinfo->value.enumerated.name, 7404 - port->src_descr, 7405 - item + port->src_num_offset); 7404 + scnprintf(uinfo->value.enumerated.name, 7405 + sizeof(uinfo->value.enumerated.name), 7406 + port->src_descr, 7407 + item + port->src_num_offset); 7406 7408 7407 7409 return 0; 7408 7410 }
+1 -1
sound/usb/proc.c
··· 231 231 char name[32]; 232 232 struct snd_card *card = stream->chip->card; 233 233 234 - sprintf(name, "stream%d", stream->pcm_index); 234 + scnprintf(name, sizeof(name), "stream%d", stream->pcm_index); 235 235 snd_card_ro_proc_new(card, name, stream, proc_pcm_format_read); 236 236 } 237 237
+2 -1
sound/usb/stream.c
··· 536 536 pcm->private_free = snd_usb_audio_pcm_free; 537 537 pcm->info_flags = 0; 538 538 if (chip->pcm_devs > 0) 539 - sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs); 539 + scnprintf(pcm->name, sizeof(pcm->name), "USB Audio #%d", 540 + chip->pcm_devs); 540 541 else 541 542 strscpy(pcm->name, "USB Audio"); 542 543