On Mon, Nov 16, 2020 at 11:23:43AM -0800, Andrey Smirnov wrote: > On Mon, Nov 16, 2020 at 12:44 AM Lukas Wunner <lukas@xxxxxxxxx> wrote: > > If the call to devm_spi_register_master() fails on probe of the GPIO SPI > > driver, the spi_master struct is erroneously not freed: > > > > After allocating the spi_master, its reference count is 1. The driver > > unconditionally decrements the reference count on unbind using a devm > > action. Before calling devm_spi_register_master(), the driver > > unconditionally increments the reference count because on success, > > that function will decrement the reference count on unbind. However on > > failure, devm_spi_register_master() does *not* decrement the reference > > count, so the spi_master is leaked. > > Not sure I fully understand this. On failure > devm_spi_register_master() will return a negative error code which > should result in probe failure and release of devres resource, right? Yes, but that just decrements the refcount from 2 to 1: /* refcount initialized to 1 */ master = spi_alloc_master(dev, sizeof(*spi_gpio)); ... /* refcount incremented to 2 */ return devm_spi_register_master(&pdev->dev, spi_master_get(master)); ... /* on failure of devm_spi_register_master(), refcount decremented to 1 by devres action */ spi_gpio_put() > > The issue was introduced by commits 8b797490b4db ("spi: gpio: Make sure > > spi_master_put() is called in every error path") and 79567c1a321e ("spi: > > gpio: Use devm_spi_register_master()"), which sought to plug leaks > > introduced by 9b00bc7b901f ("spi: spi-gpio: Rewrite to use GPIO > > descriptors") but missed this remaining leak. > > That extra spi_master_get() that might be problematic was present in > the code before 8b797490b4db ("spi: gpio: Make sure spi_master_put() > is called in every error path") and I think was first introduced in > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers?h=v5.9-rc4&id=702a4879ec337463f858c8ab467482cce260bf18 > > Or am I missing something? The extra spi_master_get() was introduced by 79567c1a321e. I don't see it in spi-gpio.c before that commit. Its quite possible that I missed something myself, nobody's perfect. But just from code inspection it seems wrong the way it is right now. Shout if I failed to explain it properly and I'll try again. :) Thanks, Lukas