Blob Blame History Raw
From: Tom Rix <trix@redhat.com>
Date: Mon, 11 Apr 2022 13:47:56 -0400
Subject: scsi: sr: Do not leak information in ioctl
Git-commit: faad6cebded8e0fd902b672f220449b93db479eb
Patch-mainline: v5.18-rc4
References: git-fixes

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.

[lduncan: hand applied then refreshed.]

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>
Acked-by: Lee Duncan <lduncan@suse.com>
---
 drivers/scsi/sr_ioctl.c |   15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

--- a/drivers/scsi/sr_ioctl.c
+++ b/drivers/scsi/sr_ioctl.c
@@ -44,7 +44,7 @@ static int sr_read_tochdr(struct cdrom_d
 	int result;
 	unsigned char *buffer;
 
-	buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
+	buffer = kzalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
 	if (!buffer)
 		return -ENOMEM;
 
@@ -58,10 +58,13 @@ static int sr_read_tochdr(struct cdrom_d
 	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;
 }
@@ -74,7 +77,7 @@ static int sr_read_tocentry(struct cdrom
 	int result;
 	unsigned char *buffer;
 
-	buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
+	buffer = kzalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
 	if (!buffer)
 		return -ENOMEM;
 
@@ -89,6 +92,8 @@ static int sr_read_tocentry(struct cdrom
 	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;
@@ -101,6 +106,7 @@ static int sr_read_tocentry(struct cdrom
 		tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)
 			+ buffer[10]) << 8) + buffer[11];
 
+err:
 	kfree(buffer);
 	return result;
 }
@@ -383,7 +389,7 @@ int sr_get_mcn(struct cdrom_device_info
 {
 	Scsi_CD *cd = cdi->handle;
 	struct packet_command cgc;
-	char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
+	char *buffer = kzalloc(32, GFP_KERNEL | SR_GFP_DMA(cd));
 	int result;
 
 	if (!buffer)
@@ -399,10 +405,13 @@ int sr_get_mcn(struct cdrom_device_info
 	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;
 }