From: Takashi Iwai Date: Thu, 10 Jul 2025 10:07:22 +0000 (+0200) Subject: ALSA: ac97: Copy string more safely X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=926359588170882ab39c578774a989a5237a3747;p=thirdparty%2Fkernel%2Flinux.git ALSA: ac97: Copy string more safely snd_ac97_get_name() blindly assumes that the name buffer is large enough, but we should be more careful. Pass the max buffer length and allow trimming to the size. Only a cosmetic safety matter, no functional changes intended. Signed-off-by: Takashi Iwai Link: https://patch.msgid.link/20250710100727.22653-101-tiwai@suse.de --- diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 588c094080bea..cd60c856a92e9 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -1840,7 +1840,8 @@ static const struct ac97_codec_id *look_for_codec_id(const struct ac97_codec_id return NULL; } -void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int modem) +void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, + size_t maxlen, int modem) { const struct ac97_codec_id *pid; @@ -1852,7 +1853,7 @@ void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int m if (! pid) return; - strcpy(name, pid->name); + strscpy(name, pid->name, maxlen); if (ac97 && pid->patch) { if ((modem && (pid->flags & AC97_MODEM_PATCH)) || (! modem && ! (pid->flags & AC97_MODEM_PATCH))) @@ -1861,8 +1862,8 @@ void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int m pid = look_for_codec_id(snd_ac97_codec_ids, id); if (pid) { - strcat(name, " "); - strcat(name, pid->name); + strlcat(name, " ", maxlen); + strlcat(name, pid->name, maxlen); if (pid->mask != 0xffffffff) sprintf(name + strlen(name), " rev %u", id & ~pid->mask); if (ac97 && pid->patch) { @@ -1870,8 +1871,10 @@ void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int m (! modem && ! (pid->flags & AC97_MODEM_PATCH))) pid->patch(ac97); } - } else - sprintf(name + strlen(name), " id %x", id & 0xff); + } else { + int l = strlen(name); + snprintf(name + l, maxlen - l, " id %x", id & 0xff); + } } /** @@ -2295,8 +2298,8 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, /* additional initializations */ if (bus->ops->init) bus->ops->init(ac97); - snd_ac97_get_name(ac97, ac97->id, name, !ac97_is_audio(ac97)); - snd_ac97_get_name(NULL, ac97->id, name, !ac97_is_audio(ac97)); // ac97->id might be changed in the special setup code + snd_ac97_get_name(ac97, ac97->id, name, sizeof(name), !ac97_is_audio(ac97)); + snd_ac97_get_name(NULL, ac97->id, name, sizeof(name), !ac97_is_audio(ac97)); // ac97->id might be changed in the special setup code if (! ac97->build_ops) ac97->build_ops = &null_build_ops; diff --git a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h index 8eeae2dec552a..965284eb4b336 100644 --- a/sound/pci/ac97/ac97_local.h +++ b/sound/pci/ac97/ac97_local.h @@ -8,7 +8,7 @@ */ void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, - int modem); + size_t maxlen, int modem); int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value); diff --git a/sound/pci/ac97/ac97_proc.c b/sound/pci/ac97/ac97_proc.c index 518834964b7b4..2df3ba9a08dc5 100644 --- a/sound/pci/ac97/ac97_proc.c +++ b/sound/pci/ac97/ac97_proc.c @@ -98,7 +98,7 @@ static void snd_ac97_proc_read_main(struct snd_ac97 *ac97, struct snd_info_buffe static const char *spdif_rates_cs4205[4] = { " Rate=48kHz", " Rate=44.1kHz", " Rate=res", " Rate=res" }; static const char *double_rate_slots[4] = { "10/11", "7/8", "reserved", "reserved" }; - snd_ac97_get_name(NULL, ac97->id, name, 0); + snd_ac97_get_name(NULL, ac97->id, name, sizeof(name), 0); snd_iprintf(buffer, "%d-%d/%d: %s\n\n", ac97->addr, ac97->num, subidx, name); if ((ac97->scaps & AC97_SCAP_AUDIO) == 0)