ALSA: pcm: oss: Fix setup list UAF on proc write error

snd_pcm_oss_proc_write() links a newly allocated setup entry into the
OSS setup list before duplicating the task name. If the task-name
allocation fails, the error path frees the already linked entry and
leaves setup_list pointing at freed memory.

A later OSS device open can then walk the stale list entry in
snd_pcm_oss_look_for_setup() and dereference freed memory.

Allocate the task name and initialize the setup entry before publishing
the entry on setup_list. Also fetch the initial proc read iterator only
after taking setup_mutex, so all setup_list traversal follows the same
list lifetime rules.

Reported-by: syzbot+8e498074a794999eb41c@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/6a1062b7.170a0220.35b2b7.0003.GAE@google.com
Closes: https://syzkaller.appspot.com/bug?extid=8e498074a794999eb41c
Fixes: 060d77b9c0 ("[ALSA] Fix / clean up PCM-OSS setup hooks")
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
Link: https://patch.msgid.link/20260522-alsa-pcm-oss-setup-uaf-v1-1-40bdcc4d17e8@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Cássio Gabriel 2026-05-22 22:09:40 -03:00 committed by Takashi Iwai
parent a0d9e8df2e
commit 4cc54bdd54

View File

@ -2974,8 +2974,10 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
struct snd_pcm_str *pstr = entry->private_data;
struct snd_pcm_oss_setup *setup = pstr->oss.setup_list;
struct snd_pcm_oss_setup *setup;
guard(mutex)(&pstr->oss.setup_mutex);
setup = pstr->oss.setup_list;
while (setup) {
snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
setup->task_name,
@ -3060,6 +3062,13 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
buffer->error = -ENOMEM;
return;
}
template.task_name = kstrdup(task_name, GFP_KERNEL);
if (!template.task_name) {
kfree(setup);
buffer->error = -ENOMEM;
return;
}
*setup = template;
if (pstr->oss.setup_list == NULL)
pstr->oss.setup_list = setup;
else {
@ -3067,12 +3076,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
setup1->next; setup1 = setup1->next);
setup1->next = setup;
}
template.task_name = kstrdup(task_name, GFP_KERNEL);
if (! template.task_name) {
kfree(setup);
buffer->error = -ENOMEM;
return;
}
continue;
}
*setup = template;
}