| From foo@baz Sat Jul 28 12:10:33 CEST 2018 |
| From: Wenwen Wang <wang6495@umn.edu> |
| Date: Mon, 7 May 2018 19:54:01 -0500 |
| Subject: scsi: 3w-xxxx: fix a missing-check bug |
| |
| From: Wenwen Wang <wang6495@umn.edu> |
| |
| [ Upstream commit 9899e4d3523faaef17c67141aa80ff2088f17871 ] |
| |
| In tw_chrdev_ioctl(), the length of the data buffer is firstly copied |
| from the userspace pointer 'argp' and saved to the kernel object |
| 'data_buffer_length'. Then a security check is performed on it to make |
| sure that the length is not more than 'TW_MAX_IOCTL_SECTORS * |
| 512'. Otherwise, an error code -EINVAL is returned. If the security |
| check is passed, the entire ioctl command is copied again from the |
| 'argp' pointer and saved to the kernel object 'tw_ioctl'. Then, various |
| operations are performed on 'tw_ioctl' according to the 'cmd'. Given |
| that the 'argp' pointer resides in userspace, a malicious userspace |
| process can race to change the buffer length between the two |
| copies. This way, the user can bypass the security check and inject |
| invalid data buffer length. This can cause potential security issues in |
| the following execution. |
| |
| This patch checks for capable(CAP_SYS_ADMIN) in tw_chrdev_open() to |
| avoid the above issues. |
| |
| Signed-off-by: Wenwen Wang <wang6495@umn.edu> |
| Acked-by: Adam Radford <aradford@gmail.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/scsi/3w-xxxx.c | 3 +++ |
| 1 file changed, 3 insertions(+) |
| |
| --- a/drivers/scsi/3w-xxxx.c |
| +++ b/drivers/scsi/3w-xxxx.c |
| @@ -1034,6 +1034,9 @@ static int tw_chrdev_open(struct inode * |
| |
| dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n"); |
| |
| + if (!capable(CAP_SYS_ADMIN)) |
| + return -EACCES; |
| + |
| minor_number = iminor(inode); |
| if (minor_number >= tw_device_extension_count) |
| return -ENODEV; |