@@ -251,10 +251,8 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,
return -EOPNOTSUPP;
data_ptrs = kmalloc_array(nmsgs, sizeof(u8 __user *), GFP_KERNEL);
- if (data_ptrs == NULL) {
- kfree(msgs);
+ if (data_ptrs == NULL)
return -ENOMEM;
- }
res = 0;
for (i = 0; i < nmsgs; i++) {
@@ -302,7 +300,6 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,
for (j = 0; j < i; ++j)
kfree(msgs[j].buf);
kfree(data_ptrs);
- kfree(msgs);
return res;
}
@@ -316,7 +313,6 @@ static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,
kfree(msgs[i].buf);
}
kfree(data_ptrs);
- kfree(msgs);
return res;
}
@@ -446,6 +442,7 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case I2C_RDWR: {
struct i2c_rdwr_ioctl_data rdwr_arg;
struct i2c_msg *rdwr_pa;
+ int res;
if (copy_from_user(&rdwr_arg,
(struct i2c_rdwr_ioctl_data __user *)arg,
@@ -467,7 +464,9 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (IS_ERR(rdwr_pa))
return PTR_ERR(rdwr_pa);
- return i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa);
+ res = i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa);
+ kfree(rdwr_pa);
+ return res;
}
case I2C_SMBUS: {
@@ -540,7 +539,7 @@ static long compat_i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned lo
struct i2c_rdwr_ioctl_data32 rdwr_arg;
struct i2c_msg32 __user *p;
struct i2c_msg *rdwr_pa;
- int i;
+ int i, res;
if (copy_from_user(&rdwr_arg,
(struct i2c_rdwr_ioctl_data32 __user *)arg,
@@ -573,7 +572,9 @@ static long compat_i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned lo
};
}
- return i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa);
+ res = i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa);
+ kfree(rdwr_pa);
+ return res;
}
case I2C_SMBUS: {
struct i2c_smbus_ioctl_data32 data32;
Early return in i2cdev_ioctl_rdwr() failed to free the memory allocated by the caller. Move freeing the memory to the function where it has been allocated to prevent similar leaks in the future. Fixes: 97ca843f6ad3 ("i2c: dev: Check for I2C_FUNC_I2C before calling i2c_transfer") Signed-off-by: Igor Pylypiv <ipylypiv@google.com> --- drivers/i2c/i2c-dev.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)