[PATCH 7/7] ALSA: usb-audio: replace strlcat() in longname construction
From: Mahad Ibrahim
Date: Fri Aug 07 2026 - 07:48:35 EST
card->longname was assembled from a chain of strlcat() calls covering
the vendor or manufacturer name, the short name, the USB path and the
speed suffix. The return value of one of them was reused as the
offset for usb_make_path().
Keep the current length in len and write each piece at that offset,
with scnprintf() where a format is involved and strscpy() for the
plain speed suffixes. len is taken again after strim(), which
shortens the string in place, and again after usb_make_path(), which
writes into the buffer directly. Both would otherwise leave the
offset pointing at the wrong byte.
As in the hiface conversion, len now counts characters written rather
than requested, so the bounds check before usb_make_path() is always
true; in the truncated case it writes only the NUL terminator that is
already there. The strings produced for every combination of vendor,
manufacturer, short name and link speed are byte for byte the same as
before.
Signed-off-by: Mahad Ibrahim <mahad.ibrahim.dev@xxxxxxxxx>
---
sound/usb/card.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 24112e491779..3c15a6862046 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -651,7 +651,7 @@ static void usb_audio_make_longname(struct usb_device *dev,
struct snd_card *card = chip->card;
const struct usb_audio_device_name *preset;
const char *s = NULL;
- int len;
+ int len = 0;
preset = lookup_device_name(chip->usb_id);
@@ -675,32 +675,39 @@ static void usb_audio_make_longname(struct usb_device *dev,
if (*card->longname) {
strim(card->longname);
+ len = strlen(card->longname);
if (*card->longname)
- strlcat(card->longname, " ", sizeof(card->longname));
+ len += scnprintf(card->longname + len,
+ sizeof(card->longname) - len, " ");
}
- strlcat(card->longname, card->shortname, sizeof(card->longname));
-
- len = strlcat(card->longname, " at ", sizeof(card->longname));
+ len += scnprintf(card->longname + len, sizeof(card->longname) - len,
+ "%s at ", card->shortname);
if (len < sizeof(card->longname))
usb_make_path(dev, card->longname + len, sizeof(card->longname) - len);
+ len = strlen(card->longname);
switch (snd_usb_get_speed(dev)) {
case USB_SPEED_LOW:
- strlcat(card->longname, ", low speed", sizeof(card->longname));
+ strscpy(card->longname + len, ", low speed",
+ sizeof(card->longname) - len);
break;
case USB_SPEED_FULL:
- strlcat(card->longname, ", full speed", sizeof(card->longname));
+ strscpy(card->longname + len, ", full speed",
+ sizeof(card->longname) - len);
break;
case USB_SPEED_HIGH:
- strlcat(card->longname, ", high speed", sizeof(card->longname));
+ strscpy(card->longname + len, ", high speed",
+ sizeof(card->longname) - len);
break;
case USB_SPEED_SUPER:
- strlcat(card->longname, ", super speed", sizeof(card->longname));
+ strscpy(card->longname + len, ", super speed",
+ sizeof(card->longname) - len);
break;
case USB_SPEED_SUPER_PLUS:
- strlcat(card->longname, ", super speed plus", sizeof(card->longname));
+ strscpy(card->longname + len, ", super speed plus",
+ sizeof(card->longname) - len);
break;
default:
break;
--
2.54.0