]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ALSA: ac97: Copy string more safely
authorTakashi Iwai <tiwai@suse.de>
Thu, 10 Jul 2025 10:07:22 +0000 (12:07 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 11 Jul 2025 07:53:35 +0000 (09:53 +0200)
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 <tiwai@suse.de>
Link: https://patch.msgid.link/20250710100727.22653-101-tiwai@suse.de
sound/pci/ac97/ac97_codec.c
sound/pci/ac97/ac97_local.h
sound/pci/ac97/ac97_proc.c

index 588c094080beae64324b1f7ddf6ecc060a82e630..cd60c856a92e90431e834235b2c3e9a553a260b5 100644 (file)
@@ -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;
 
index 8eeae2dec552a778fedb2f374b0e20ab0f0bee4f..965284eb4b3360a9b6a557ebefbdb0da7588d99c 100644 (file)
@@ -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);
 
index 518834964b7b4269956fb9059b4c1494d05ba3dd..2df3ba9a08dc5b2237c0bbbd2ca51776bb1601c8 100644 (file)
@@ -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)