| From 31fb43134a12e83bbe2d00944d436e6db5bc7ac5 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 11 Apr 2022 13:47:56 -0400 |
| Subject: scsi: sr: Do not leak information in ioctl |
| |
| From: Tom Rix <trix@redhat.com> |
| |
| [ Upstream commit faad6cebded8e0fd902b672f220449b93db479eb ] |
| |
| sr_ioctl.c uses this pattern: |
| |
| result = sr_do_ioctl(cd, &cgc); |
| to-user = buffer[]; |
| kfree(buffer); |
| return result; |
| |
| Use of a buffer without checking leaks information. Check result and jump |
| over the use of buffer if there is an error. |
| |
| result = sr_do_ioctl(cd, &cgc); |
| if (result) |
| goto err; |
| to-user = buffer[]; |
| err: |
| kfree(buffer); |
| return result; |
| |
| Additionally, initialize the buffer to zero. |
| |
| This problem can be seen in the 2.4.0 kernel. |
| |
| Link: https://lore.kernel.org/r/20220411174756.2418435-1-trix@redhat.com |
| Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") |
| Reviewed-by: Christoph Hellwig <hch@lst.de> |
| Signed-off-by: Tom Rix <trix@redhat.com> |
| Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/scsi/sr_ioctl.c | 15 ++++++++++++--- |
| 1 file changed, 12 insertions(+), 3 deletions(-) |
| |
| diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c |
| index ddd00efc4882..fbdb5124d7f7 100644 |
| --- a/drivers/scsi/sr_ioctl.c |
| +++ b/drivers/scsi/sr_ioctl.c |
| @@ -41,7 +41,7 @@ static int sr_read_tochdr(struct cdrom_device_info *cdi, |
| int result; |
| unsigned char *buffer; |
| |
| - buffer = kmalloc(32, GFP_KERNEL); |
| + buffer = kzalloc(32, GFP_KERNEL); |
| if (!buffer) |
| return -ENOMEM; |
| |
| @@ -55,10 +55,13 @@ static int sr_read_tochdr(struct cdrom_device_info *cdi, |
| cgc.data_direction = DMA_FROM_DEVICE; |
| |
| result = sr_do_ioctl(cd, &cgc); |
| + if (result) |
| + goto err; |
| |
| tochdr->cdth_trk0 = buffer[2]; |
| tochdr->cdth_trk1 = buffer[3]; |
| |
| +err: |
| kfree(buffer); |
| return result; |
| } |
| @@ -71,7 +74,7 @@ static int sr_read_tocentry(struct cdrom_device_info *cdi, |
| int result; |
| unsigned char *buffer; |
| |
| - buffer = kmalloc(32, GFP_KERNEL); |
| + buffer = kzalloc(32, GFP_KERNEL); |
| if (!buffer) |
| return -ENOMEM; |
| |
| @@ -86,6 +89,8 @@ static int sr_read_tocentry(struct cdrom_device_info *cdi, |
| cgc.data_direction = DMA_FROM_DEVICE; |
| |
| result = sr_do_ioctl(cd, &cgc); |
| + if (result) |
| + goto err; |
| |
| tocentry->cdte_ctrl = buffer[5] & 0xf; |
| tocentry->cdte_adr = buffer[5] >> 4; |
| @@ -98,6 +103,7 @@ static int sr_read_tocentry(struct cdrom_device_info *cdi, |
| tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8) |
| + buffer[10]) << 8) + buffer[11]; |
| |
| +err: |
| kfree(buffer); |
| return result; |
| } |
| @@ -384,7 +390,7 @@ int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) |
| { |
| Scsi_CD *cd = cdi->handle; |
| struct packet_command cgc; |
| - char *buffer = kmalloc(32, GFP_KERNEL); |
| + char *buffer = kzalloc(32, GFP_KERNEL); |
| int result; |
| |
| if (!buffer) |
| @@ -400,10 +406,13 @@ int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) |
| cgc.data_direction = DMA_FROM_DEVICE; |
| cgc.timeout = IOCTL_TIMEOUT; |
| result = sr_do_ioctl(cd, &cgc); |
| + if (result) |
| + goto err; |
| |
| memcpy(mcn->medium_catalog_number, buffer + 9, 13); |
| mcn->medium_catalog_number[13] = 0; |
| |
| +err: |
| kfree(buffer); |
| return result; |
| } |
| -- |
| 2.35.1 |
| |