ALSA: emu10k1: Pass destination size to copy_string()

copy_string() copies the bus and input/output names into fixed-size
arrays of struct snd_emu10k1_fx8010_info using strcpy() and sprintf(),
and it has no information about the size of the destination buffer.

All source strings are static and shorter than the 32-byte destination
arrays (the longest one is 20 characters), so this is safe today, but the
safety should not depend on the contents of the name tables. The earlier
strcpy() to strscpy() conversions skipped this function because dst is a
plain pointer.

Pass the destination size to copy_string() and use strscpy() and
snprintf() instead.

No functional changes intended.

Testing: compile-tested only with clang (W=1) and sparse (C=1). The
function is reached only through the SNDRV_EMU10K1_IOCTL_INFO ioctl of
the EMU10K1 hardware, which is not available under QEMU.

Link: https://github.com/KSPP/linux/issues/88
Signed-off-by: Andrey Zakharov <dedemorow@gmail.com>
Link: https://patch.msgid.link/20261023105027.53135-1-dedemorow@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Andrey Zakharov 2026-10-23 13:50:27 +03:00 committed by Takashi Iwai
parent 0d01f90b07
commit e4a21e95c5

View File

@ -2423,12 +2423,12 @@ static int snd_emu10k1_fx8010_open(struct snd_hwdep * hw, struct file *file)
return 0;
}
static void copy_string(char *dst, const char *src, const char *null, int idx)
static void copy_string(char *dst, size_t size, const char *src, const char *null, int idx)
{
if (src == NULL)
sprintf(dst, "%s %02X", null, idx);
snprintf(dst, size, "%s %02X", null, idx);
else
strcpy(dst, src);
strscpy(dst, src, size);
}
static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
@ -2446,12 +2446,16 @@ static void snd_emu10k1_fx8010_info(struct snd_emu10k1 *emu,
extin_mask = emu->audigy ? ~0 : emu->fx8010.extin_mask;
extout_mask = emu->audigy ? ~0 : emu->fx8010.extout_mask;
for (res = 0; res < 16; res++, fxbus++, extin++, extout++) {
copy_string(info->fxbus_names[res], *fxbus, "FXBUS", res);
copy_string(info->extin_names[res], extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
copy_string(info->fxbus_names[res], sizeof(info->fxbus_names[res]),
*fxbus, "FXBUS", res);
copy_string(info->extin_names[res], sizeof(info->extin_names[res]),
extin_mask & (1 << res) ? *extin : NULL, "Unused", res);
copy_string(info->extout_names[res], sizeof(info->extout_names[res]),
extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
}
for (res = 16; res < 32; res++, extout++)
copy_string(info->extout_names[res], extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
copy_string(info->extout_names[res], sizeof(info->extout_names[res]),
extout_mask & (1 << res) ? *extout : NULL, "Unused", res);
info->gpr_controls = emu->fx8010.gpr_count;
}