[PATCH 7/7] ALSA: usb-audio: replace strlcat() in longname construction
Mahad Ibrahim <[email protected]>
| Newsgroups | org.kernel.vger.linux-sound,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> --- 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