Re: [PATCH 11/12] iio: accel: kionix-kx022a: Prevent memory leak and fix state

Matti Vaittinen <[email protected]>
Newsgroups org.kernel.vger.linux-iio,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 17/08/2026 04:45, Jonathan Cameron wrote:
> On Mon, 10 Aug 2026 10:55:03 +0300
> Matti Vaittinen <[email protected]> wrote:
> 
>> From: Matti Vaittinen <[email protected]>
>>
>> The driver allocates memory for samples at buffer enable path. If regmap
>> operation fails in the kx022a_fifo_enable() at the buffer enable path, the
>> allocated memory is never freed. Furthermore, the state information and
>> previous hardware configuration(s) aren't undone, potentially leaving
>> WMI interrupts and buffers enabled, or driver state flags wrong.
>>
>> Free the memory and revert the hardware configuration and state flags on
>> error path.
>>
>> Signed-off-by: Matti Vaittinen <[email protected]>
>> Fixes: e7123a4dfcd7 ("iio: accel: kionix-kx022a: Refactor driver and add chip_info structure")
>> ---
>>   drivers/iio/accel/kionix-kx022a.c | 27 ++++++++++++++++++++++-----
>>   1 file changed, 22 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/iio/accel/kionix-kx022a.c b/drivers/iio/accel/kionix-kx022a.c
>> index 8a13f78aeab0..49e8b4b943da 100644
>> --- a/drivers/iio/accel/kionix-kx022a.c
>> +++ b/drivers/iio/accel/kionix-kx022a.c
>> @@ -980,26 +980,43 @@ static int kx022a_fifo_enable(struct kx022a_data *data)
>>   	guard(mutex)(&data->mutex);
>>   	ret = __kx022a_turn_on_off(data, false);
>>   	if (ret)
>> -		return ret;
>> +		goto err_free_out;
> 
> If we follow this path we are assuming that turn_on_off hasn't
> had any side effects in failing...
> 
> 
>>   
>>   	/* Update watermark to HW */
>>   	ret = kx022a_fifo_set_wmi(data);
>>   	if (ret)
>> -		return ret;
>> +		goto err_free_out;
>>   
>>   	/* Enable buffer */
>>   	ret = regmap_set_bits(data->regmap, data->chip_info->buf_cntl2,
>>   			      KX022A_MASK_BUF_EN);
>>   	if (ret)
>> -		return ret;
>> +		goto err_free_out;
>>   
>>   	data->state |= KX022A_STATE_FIFO;
>>   	ret = regmap_set_bits(data->regmap, data->ien_reg,
>>   			      KX022A_MASK_WMI);
>>   	if (ret)
>> -		return ret;
>> +		goto err_wmi_out;
>>   
>> -	return __kx022a_turn_on_off(data, true);
>> +	ret = __kx022a_turn_on_off(data, true);
>> +	if (ret)
>> +		goto err_on_out;
> 
> 
>> +
>> +	return ret;
>> +
>> +err_on_out:
>> +	regmap_clear_bits(data->regmap, data->ien_reg,
>> +			  KX022A_MASK_WMI);
>> +err_wmi_out:
>> +	regmap_clear_bits(data->regmap, data->chip_info->buf_cntl2,
>> +			  KX022A_MASK_BUF_EN);
>> +err_free_out:
>> +	kfree(data->fifo_buffer);
> 
> This thing is fine here.
> 
>> +	data->state &= ~KX022A_STATE_FIFO;
> 
> This should also only occur when we have set it in the first place -
> so under err_wmi_out:
> 
> 
>> +	__kx022a_turn_on_off(data, true);
> 
> So following path above we should not be calling this.  It might
> be safe to do so but it isn't logically correct.  It should be a few
> lines earlier.
> 
>> +
>> +	return ret;
>>   }
>>   
>>   static int kx022a_buffer_postenable(struct iio_dev *idev)
> 

Thanks Jonathan. I think you're right. I've no idea what I was thinking 
when writing this fix...

Yours,
	-- Matti

-- 
Matti Vaittinen
Linux kernel developer at ROHM Semiconductors
Oulu Finland

~~ When things go utterly wrong vim users can always type :help! ~~
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.