Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: dev: Fix memory leak when underlying adapter does not support I2C

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>
[wsa: replaced '== NULL' with '!']
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

authored by

Igor Pylypiv and committed by
Wolfram Sang
48730a9d 433c6916

+9 -8
+9 -8
drivers/i2c/i2c-dev.c
··· 251 251 return -EOPNOTSUPP; 252 252 253 253 data_ptrs = kmalloc_array(nmsgs, sizeof(u8 __user *), GFP_KERNEL); 254 - if (data_ptrs == NULL) { 255 - kfree(msgs); 254 + if (!data_ptrs) 256 255 return -ENOMEM; 257 - } 258 256 259 257 res = 0; 260 258 for (i = 0; i < nmsgs; i++) { ··· 300 302 for (j = 0; j < i; ++j) 301 303 kfree(msgs[j].buf); 302 304 kfree(data_ptrs); 303 - kfree(msgs); 304 305 return res; 305 306 } 306 307 ··· 313 316 kfree(msgs[i].buf); 314 317 } 315 318 kfree(data_ptrs); 316 - kfree(msgs); 317 319 return res; 318 320 } 319 321 ··· 442 446 case I2C_RDWR: { 443 447 struct i2c_rdwr_ioctl_data rdwr_arg; 444 448 struct i2c_msg *rdwr_pa; 449 + int res; 445 450 446 451 if (copy_from_user(&rdwr_arg, 447 452 (struct i2c_rdwr_ioctl_data __user *)arg, ··· 464 467 if (IS_ERR(rdwr_pa)) 465 468 return PTR_ERR(rdwr_pa); 466 469 467 - return i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa); 470 + res = i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa); 471 + kfree(rdwr_pa); 472 + return res; 468 473 } 469 474 470 475 case I2C_SMBUS: { ··· 539 540 struct i2c_rdwr_ioctl_data32 rdwr_arg; 540 541 struct i2c_msg32 __user *p; 541 542 struct i2c_msg *rdwr_pa; 542 - int i; 543 + int i, res; 543 544 544 545 if (copy_from_user(&rdwr_arg, 545 546 (struct i2c_rdwr_ioctl_data32 __user *)arg, ··· 572 573 }; 573 574 } 574 575 575 - return i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa); 576 + res = i2cdev_ioctl_rdwr(client, rdwr_arg.nmsgs, rdwr_pa); 577 + kfree(rdwr_pa); 578 + return res; 576 579 } 577 580 case I2C_SMBUS: { 578 581 struct i2c_smbus_ioctl_data32 data32;