Commit 92635958 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

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: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20250710100727.22653-101-tiwai@suse.de
parent a9b25e8a
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -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;

+1 −1
Original line number Diff line number Diff line
@@ -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);

+1 −1
Original line number Diff line number Diff line
@@ -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)