Skip to content

Commit 7dd7f39

Browse files
tavianatorbroonie
authored andcommitted
ASoC: SOF: Intel: hda: Fix UAF when reloading module
hda_generic_machine_select() appends -idisp to the tplg filename by allocating a new string with devm_kasprintf(), then stores the string right back into the global variable snd_soc_acpi_intel_hda_machines. When the module is unloaded, this memory is freed, resulting in a global variable pointing to freed memory. Reloading the module then triggers a use-after-free: BUG: KFENCE: use-after-free read in string+0x48/0xe0 Use-after-free read at 0x00000000967e0109 (in kfence-kernel-patches#99): string+0x48/0xe0 vsnprintf+0x329/0x6e0 devm_kvasprintf+0x54/0xb0 devm_kasprintf+0x58/0x80 hda_machine_select.cold+0x198/0x17a2 [snd_sof_intel_hda_generic] sof_probe_work+0x7f/0x600 [snd_sof] process_one_work+0x17b/0x330 worker_thread+0x2ce/0x3f0 kthread+0xcf/0x100 ret_from_fork+0x31/0x50 ret_from_fork_asm+0x1a/0x30 kfence-kernel-patches#99: 0x00000000198a940f-0x00000000ace47d9d, size=64, cache=kmalloc-64 allocated by task 333 on cpu 8 at 17.798069s (130.453553s ago): devm_kmalloc+0x52/0x120 devm_kvasprintf+0x66/0xb0 devm_kasprintf+0x58/0x80 hda_machine_select.cold+0x198/0x17a2 [snd_sof_intel_hda_generic] sof_probe_work+0x7f/0x600 [snd_sof] process_one_work+0x17b/0x330 worker_thread+0x2ce/0x3f0 kthread+0xcf/0x100 ret_from_fork+0x31/0x50 ret_from_fork_asm+0x1a/0x30 freed by task 1543 on cpu 4 at 141.586686s (6.665010s ago): release_nodes+0x43/0xb0 devres_release_all+0x90/0xf0 device_unbind_cleanup+0xe/0x70 device_release_driver_internal+0x1c1/0x200 driver_detach+0x48/0x90 bus_remove_driver+0x6d/0xf0 pci_unregister_driver+0x42/0xb0 __do_sys_delete_module+0x1d1/0x310 do_syscall_64+0x82/0x190 entry_SYSCALL_64_after_hwframe+0x76/0x7e Fix it by copying the match array with devm_kmemdup_array() before we modify it. Fixes: 5458411 ("ASoC: SOF: Intel: hda: refactoring topology name fixup for HDA mach") Suggested-by: Peter Ujfalusi <[email protected]> Acked-by: Peter Ujfalusi <[email protected]> Signed-off-by: Tavian Barnes <[email protected]> Link: https://patch.msgid.link/570b15570b274520a0d9052f4e0f064a29c950ef.1747229716.git.tavianator@tavianator.com Signed-off-by: Mark Brown <[email protected]>
1 parent 6052f05 commit 7dd7f39

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

sound/soc/sof/intel/hda.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1049,7 +1049,21 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev,
10491049
if (!*mach && codec_num <= 2) {
10501050
bool tplg_fixup = false;
10511051

1052-
hda_mach = snd_soc_acpi_intel_hda_machines;
1052+
/*
1053+
* make a local copy of the match array since we might
1054+
* be modifying it
1055+
*/
1056+
hda_mach = devm_kmemdup_array(sdev->dev,
1057+
snd_soc_acpi_intel_hda_machines,
1058+
2, /* we have one entry + sentinel in the array */
1059+
sizeof(snd_soc_acpi_intel_hda_machines[0]),
1060+
GFP_KERNEL);
1061+
if (!hda_mach) {
1062+
dev_err(bus->dev,
1063+
"%s: failed to duplicate the HDA match table\n",
1064+
__func__);
1065+
return;
1066+
}
10531067

10541068
dev_info(bus->dev, "using HDA machine driver %s now\n",
10551069
hda_mach->drv_name);

0 commit comments

Comments
 (0)