]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: usb-audio: Copy string more safely
authorTakashi Iwai <tiwai@suse.de>
Thu, 10 Jul 2025 10:07:24 +0000 (12:07 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 11 Jul 2025 07:53:36 +0000 (09:53 +0200)
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
sound/usb/card.c
sound/usb/midi2.c
sound/usb/mixer.c
sound/usb/mixer_scarlett.c
sound/usb/mixer_scarlett2.c
sound/usb/proc.c
sound/usb/stream.c

index 630ce40ed2c95d0e55faa50ca273546fa21320c2..10d9b72855970956ef61a84d9e199e7068170b31 100644 (file)
@@ -616,9 +616,10 @@ 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",
-                       USB_ID_VENDOR(chip->usb_id),
-                       USB_ID_PRODUCT(chip->usb_id));
+               scnprintf(card->shortname, sizeof(card->shortname),
+                         "USB Device %#04x:%#04x",
+                         USB_ID_VENDOR(chip->usb_id),
+                         USB_ID_PRODUCT(chip->usb_id));
        }
 
        strim(card->shortname);
@@ -757,8 +758,8 @@ 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",
-               USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
+       scnprintf(component, sizeof(component), "USB%04x:%04x",
+                 USB_ID_VENDOR(chip->usb_id), USB_ID_PRODUCT(chip->usb_id));
        snd_component_add(card, component);
 
        usb_audio_make_shortname(dev, chip, quirk);
index 692dfc3c182f0e39cf4db386181fbc31a262c811..030569fda416fff1b2872c50169ea5ed99d5248b 100644 (file)
@@ -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,
index a7cd7d51e66b5b2ec1e222015cb3422d6c3e05b7..63b300bc67ba9b8d46cf6d7c0f1e8dfd54ad9c3f 100644 (file)
@@ -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);
index ff548041679bbe9fe18187d334901146baf9caa1..8babfa3f7c458cc8695bb2cff42455e5dea65577 100644 (file)
@@ -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",
-                       'A'+(i - offsets[SCARLETT_OFFSET_MIX] - 1));
+               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,8 +964,9 @@ 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,
-                               o+'A');
+                       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,
                                          (i << 3) + (o & 0x07), USB_MIXER_S16,
index 93589e86828a3e7a8ebf455a6a498a6e5f4e26a3..49eeb1444dce23fd97afb57140074f333c78bb20 100644 (file)
@@ -7396,13 +7396,15 @@ 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,
-                                       port->dsp_src_descr,
-                                       item - private->num_mix_out + 1);
+                               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,
-                                       port->src_descr,
-                                       item + port->src_num_offset);
+                               scnprintf(uinfo->value.enumerated.name,
+                                         sizeof(uinfo->value.enumerated.name),
+                                         port->src_descr,
+                                         item + port->src_num_offset);
 
                        return 0;
                }
index e9bbaea7b2fa36e35bea2a8f7be6b52d140da0da..c8b967bd7065ee60f3273d3b40be1662e2274116 100644 (file)
@@ -231,7 +231,7 @@ void snd_usb_proc_pcm_format_add(struct snd_usb_stream *stream)
        char name[32];
        struct snd_card *card = stream->chip->card;
 
-       sprintf(name, "stream%d", stream->pcm_index);
+       scnprintf(name, sizeof(name), "stream%d", stream->pcm_index);
        snd_card_ro_proc_new(card, name, stream, proc_pcm_format_read);
 }
 
index 749498fbf9cb29522d00f40e24ced4baa43c0f87..ad6ced78063471808dee637a7d8f482b9c095a25 100644 (file)
@@ -536,7 +536,8 @@ static int __snd_usb_add_audio_stream(struct snd_usb_audio *chip,
        pcm->private_free = snd_usb_audio_pcm_free;
        pcm->info_flags = 0;
        if (chip->pcm_devs > 0)
-               sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs);
+               scnprintf(pcm->name, sizeof(pcm->name), "USB Audio #%d",
+                         chip->pcm_devs);
        else
                strscpy(pcm->name, "USB Audio");