[PATCH v3] ALSA: asihpi: detect truncated control names

Pengpeng Hou
2026-03-28T10:28:18Z

asihpi_ctl_init() builds mixer control names in the fixed 44-byte
hpi_ctl->name buffer with sprintf().

This is not only a defensive cleanup. The current in-tree name tables and
format strings can already exceed 44 bytes. For example,

"Bitstream 0 Internal 0 Monitor Playback Volume"

is 46 characters before the trailing NUL, so the current sprintf() call
writes past the end of hpi_ctl->name.

The generated control name is used as the ALSA control element key, so
blindly truncating it is not sufficient. Switch the formatting to
snprintf() and emit an error if truncation happens, showing the
truncated name while still keeping the write bounded to hpi_ctl->name.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
v3:
- use snprintf() instead of scnprintf()
- check the return value and report truncated control names

v2:
- clarify that the current in-tree strings can already overflow the buffer
- use scnprintf() instead of sprintf()
- drop the unrelated trailing whitespace change

sound/pci/asihpi/asihpi.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index 3a64d0562803..b7010d83e89c 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -1362,6 +1362,7 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
struct hpi_control *hpi_ctl,
char *name)
{
+ int len;
char *dir;
memset(snd_control, 0, sizeof(*snd_control));
snd_control->name = hpi_ctl->name;
@@ -1384,23 +1385,30 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control,
dir = "Playback "; /* PCM Playback source, or output node */

if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
- sprintf(hpi_ctl->name, "%s %d %s %d %s%s",
- asihpi_src_names[hpi_ctl->src_node_type],
- hpi_ctl->src_node_index,
- asihpi_dst_names[hpi_ctl->dst_node_type],
- hpi_ctl->dst_node_index,
- dir, name);
+ len = snprintf(hpi_ctl->name, sizeof(hpi_ctl->name),
+ "%s %d %s %d %s%s",
+ asihpi_src_names[hpi_ctl->src_node_type],
+ hpi_ctl->src_node_index,
+ asihpi_dst_names[hpi_ctl->dst_node_type],
+ hpi_ctl->dst_node_index,
+ dir, name);
else if (hpi_ctl->dst_node_type) {
- sprintf(hpi_ctl->name, "%s %d %s%s",
- asihpi_dst_names[hpi_ctl->dst_node_type],
- hpi_ctl->dst_node_index,
- dir, name);
+ len = snprintf(hpi_ctl->name, sizeof(hpi_ctl->name),
+ "%s %d %s%s",
+ asihpi_dst_names[hpi_ctl->dst_node_type],
+ hpi_ctl->dst_node_index,
+ dir, name);
} else {
- sprintf(hpi_ctl->name, "%s %d %s%s",
- asihpi_src_names[hpi_ctl->src_node_type],
- hpi_ctl->src_node_index,
- dir, name);
+ len = snprintf(hpi_ctl->name, sizeof(hpi_ctl->name),
+ "%s %d %s%s",
+ asihpi_src_names[hpi_ctl->src_node_type],
+ hpi_ctl->src_node_index,
+ dir, name);
}
+
+ if (len >= sizeof(hpi_ctl->name))
+ pr_err("asihpi: truncated control name: %s\n",
+ hpi_ctl->name);
}

/*------------------------------------------------------------
--
2.50.1 (Apple Git-155)