Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: ac97: fix a double free in snd_ac97_controller_register()

If ac97_add_adapter() fails, put_device() is the correct way to drop
the device reference. kfree() is not required.
Add kfree() if idr_alloc() fails and in ac97_adapter_release() to do
the cleanup.

Found by code review.

Fixes: 74426fbff66e ("ALSA: ac97: add an ac97 bus")
Cc: stable@vger.kernel.org
Signed-off-by: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
Link: https://patch.msgid.link/20251219162845.657525-1-lihaoxiang@isrc.iscas.ac.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Haoxiang Li and committed by
Takashi Iwai
830988b6 17753d17

+5 -5
+5 -5
sound/ac97/bus.c
··· 298 298 idr_remove(&ac97_adapter_idr, ac97_ctrl->nr); 299 299 dev_dbg(&ac97_ctrl->adap, "adapter unregistered by %s\n", 300 300 dev_name(ac97_ctrl->parent)); 301 + kfree(ac97_ctrl); 301 302 } 302 303 303 304 static const struct device_type ac97_adapter_type = { ··· 320 319 ret = device_register(&ac97_ctrl->adap); 321 320 if (ret) 322 321 put_device(&ac97_ctrl->adap); 323 - } 322 + } else 323 + kfree(ac97_ctrl); 324 + 324 325 if (!ret) { 325 326 list_add(&ac97_ctrl->controllers, &ac97_controllers); 326 327 dev_dbg(&ac97_ctrl->adap, "adapter registered by %s\n", ··· 364 361 ret = ac97_add_adapter(ac97_ctrl); 365 362 366 363 if (ret) 367 - goto err; 364 + return ERR_PTR(ret); 368 365 ac97_bus_reset(ac97_ctrl); 369 366 ac97_bus_scan(ac97_ctrl); 370 367 371 368 return ac97_ctrl; 372 - err: 373 - kfree(ac97_ctrl); 374 - return ERR_PTR(ret); 375 369 } 376 370 EXPORT_SYMBOL_GPL(snd_ac97_controller_register); 377 371