From: Alif Zakuan Yuslaimi <[email protected]>

dm_i3c_read/write indexed master->i3cdev[] without checking the device
number or a NULL slot, which can crash on a bad index. Reject out-of-
range and empty slots with -EINVAL.

On detach, clear the matching i3cdev[] entry so a later transfer cannot
reuse a stale descriptor pointer. Leave num_i3cdevs unchanged so the
existing dense listing path keeps its prior meaning.

Signed-off-by: Alif Zakuan Yuslaimi <[email protected]>
---
 drivers/i3c/master/dw-i3c-master.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/i3c/master/dw-i3c-master.c 
b/drivers/i3c/master/dw-i3c-master.c
index 25933adf010..e5a437781fc 100644
--- a/drivers/i3c/master/dw-i3c-master.c
+++ b/drivers/i3c/master/dw-i3c-master.c
@@ -826,6 +826,7 @@ static void dw_i3c_master_detach_i3c_dev(struct 
i3c_dev_desc *dev)
               DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
 
        i3c_dev_set_master_data(dev, NULL);
+       master->i3cdev[data->index] = NULL;
        master->addrs[data->index] = 0;
        master->free_pos |= BIT(data->index);
        kfree(data);
@@ -1014,9 +1015,14 @@ static int dw_i3c_master_priv_read(struct udevice *dev, 
u32 dev_number,
                                   u8 *buf, u32 buf_size)
 {
        struct dw_i3c_master *master = dev_get_priv(dev);
-       struct i3c_dev_desc *i3cdev = master->i3cdev[dev_number];
+       struct i3c_dev_desc *i3cdev;
        struct i3c_priv_xfer i3c_xfers;
 
+       if (dev_number >= ARRAY_SIZE(master->i3cdev) ||
+           !master->i3cdev[dev_number])
+               return -EINVAL;
+
+       i3cdev = master->i3cdev[dev_number];
        i3c_xfers.data.in = buf;
        i3c_xfers.len = buf_size;
        i3c_xfers.rnw = I3C_MSG_READ;
@@ -1028,9 +1034,14 @@ static int dw_i3c_master_priv_write(struct udevice *dev, 
u32 dev_number,
                                    u8 *buf, u32 buf_size)
 {
        struct dw_i3c_master *master = dev_get_priv(dev);
-       struct i3c_dev_desc *i3cdev = master->i3cdev[dev_number];
+       struct i3c_dev_desc *i3cdev;
        struct i3c_priv_xfer i3c_xfers;
 
+       if (dev_number >= ARRAY_SIZE(master->i3cdev) ||
+           !master->i3cdev[dev_number])
+               return -EINVAL;
+
+       i3cdev = master->i3cdev[dev_number];
        i3c_xfers.data.out = buf;
        i3c_xfers.len = buf_size;
        i3c_xfers.rnw = I3C_MSG_WRITE;
-- 
2.43.7

Reply via email to