Commit 256cc1f1 authored by Felix Gu's avatar Felix Gu Committed by Alexandre Belloni
Browse files

i3c: dw: Fix memory leak in dw_i3c_master_i3c_xfers()



The dw_i3c_master_i3c_xfers() function allocates memory for the xfer
structure using dw_i3c_master_alloc_xfer(). If pm_runtime_resume_and_get()
fails, the function returns without freeing the allocated xfer, resulting
in a memory leak.

Since dw_i3c_master_free_xfer() is a thin wrapper around kfree(), use
the __free(kfree) cleanup attribute to handle the free automatically on
all exit paths.

Fixes: 62fe9d06 ("i3c: dw: Add power management support")
Signed-off-by: default avatarFelix Gu <ustc.gu@gmail.com>
Reviewed-by: default avatarFrank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260404-dw-i3c-2-v3-1-8f7d146549c1@gmail.com


Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
parent 57c91ca3
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/err.h>
@@ -924,7 +925,6 @@ static int dw_i3c_master_i3c_xfers(struct i3c_dev_desc *dev,
	struct i3c_master_controller *m = i3c_dev_get_master(dev);
	struct dw_i3c_master *master = to_dw_i3c_master(m);
	unsigned int nrxwords = 0, ntxwords = 0;
	struct dw_i3c_xfer *xfer;
	int i, ret = 0;

	if (!i3c_nxfers)
@@ -944,7 +944,7 @@ static int dw_i3c_master_i3c_xfers(struct i3c_dev_desc *dev,
	    nrxwords > master->caps.datafifodepth)
		return -EOPNOTSUPP;

	xfer = dw_i3c_master_alloc_xfer(master, i3c_nxfers);
	struct dw_i3c_xfer *xfer __free(kfree) = dw_i3c_master_alloc_xfer(master, i3c_nxfers);
	if (!xfer)
		return -ENOMEM;

@@ -995,7 +995,6 @@ static int dw_i3c_master_i3c_xfers(struct i3c_dev_desc *dev,
	}

	ret = xfer->ret;
	dw_i3c_master_free_xfer(xfer);

	pm_runtime_put_autosuspend(master->dev);
	return ret;