From 23e8ae295be89d8589c499e8e4e13a6631e96df8 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Thu, 9 Jul 2020 20:37:25 -0400 Subject: [PATCH] Fixes for 4.4 Signed-off-by: Sasha Levin --- ...si-mptscsih-fix-read-sense-data-size.patch | 50 ++++++++++++ queue-4.4/series | 3 + ...-potential-use-after-free-in-spidev_.patch | 76 +++++++++++++++++++ ...-race-between-spidev_release-and-spi.patch | 62 +++++++++++++++ 4 files changed, 191 insertions(+) create mode 100644 queue-4.4/scsi-mptscsih-fix-read-sense-data-size.patch create mode 100644 queue-4.4/spi-spidev-fix-a-potential-use-after-free-in-spidev_.patch create mode 100644 queue-4.4/spi-spidev-fix-a-race-between-spidev_release-and-spi.patch diff --git a/queue-4.4/scsi-mptscsih-fix-read-sense-data-size.patch b/queue-4.4/scsi-mptscsih-fix-read-sense-data-size.patch new file mode 100644 index 00000000000..742799fe46d --- /dev/null +++ b/queue-4.4/scsi-mptscsih-fix-read-sense-data-size.patch @@ -0,0 +1,50 @@ +From 03a3e7673b397d9a7b0134e7b2f9747faf84de4f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Jun 2020 17:04:46 +0200 +Subject: scsi: mptscsih: Fix read sense data size + +From: Tomas Henzl + +[ Upstream commit afe89f115e84edbc76d316759e206580a06c6973 ] + +The sense data buffer in sense_buf_pool is allocated with size of +MPT_SENSE_BUFFER_ALLOC(64) (multiplied by req_depth) while SNS_LEN(sc)(96) +is used when reading the data. That may lead to a read from unallocated +area, sometimes from another (unallocated) page. To fix this, limit the +read size to MPT_SENSE_BUFFER_ALLOC. + +Link: https://lore.kernel.org/r/20200616150446.4840-1-thenzl@redhat.com +Co-developed-by: Stanislav Saner +Signed-off-by: Stanislav Saner +Signed-off-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/message/fusion/mptscsih.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c +index 6c9fc11efb872..e77185e143ab7 100644 +--- a/drivers/message/fusion/mptscsih.c ++++ b/drivers/message/fusion/mptscsih.c +@@ -118,8 +118,6 @@ int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state); + int mptscsih_resume(struct pci_dev *pdev); + #endif + +-#define SNS_LEN(scp) SCSI_SENSE_BUFFERSIZE +- + + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ + /* +@@ -2427,7 +2425,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR + /* Copy the sense received into the scsi command block. */ + req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); + sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC)); +- memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc)); ++ memcpy(sc->sense_buffer, sense_data, MPT_SENSE_BUFFER_ALLOC); + + /* Log SMART data (asc = 0x5D, non-IM case only) if required. + */ +-- +2.25.1 + diff --git a/queue-4.4/series b/queue-4.4/series index 6f2e982ca83..72d6e38f8d2 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -1 +1,4 @@ kvm-s390-reduce-number-of-io-pins-to-1.patch +spi-spidev-fix-a-race-between-spidev_release-and-spi.patch +spi-spidev-fix-a-potential-use-after-free-in-spidev_.patch +scsi-mptscsih-fix-read-sense-data-size.patch diff --git a/queue-4.4/spi-spidev-fix-a-potential-use-after-free-in-spidev_.patch b/queue-4.4/spi-spidev-fix-a-potential-use-after-free-in-spidev_.patch new file mode 100644 index 00000000000..0214145ecae --- /dev/null +++ b/queue-4.4/spi-spidev-fix-a-potential-use-after-free-in-spidev_.patch @@ -0,0 +1,76 @@ +From 47be9956f815aded1ccbec15e4e1650f4a6ec286 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Jun 2020 11:21:25 +0800 +Subject: spi: spidev: fix a potential use-after-free in spidev_release() + +From: Zhenzhong Duan + +[ Upstream commit 06096cc6c5a84ced929634b0d79376b94c65a4bd ] + +If an spi device is unbounded from the driver before the release +process, there will be an NULL pointer reference when it's +referenced in spi_slave_abort(). + +Fix it by checking it's already freed before reference. + +Signed-off-by: Zhenzhong Duan +Link: https://lore.kernel.org/r/20200618032125.4650-2-zhenzhong.duan@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spidev.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c +index 80beb8406f200..7969f5484aee8 100644 +--- a/drivers/spi/spidev.c ++++ b/drivers/spi/spidev.c +@@ -635,15 +635,20 @@ err_find_dev: + static int spidev_release(struct inode *inode, struct file *filp) + { + struct spidev_data *spidev; ++ int dofree; + + mutex_lock(&device_list_lock); + spidev = filp->private_data; + filp->private_data = NULL; + ++ spin_lock_irq(&spidev->spi_lock); ++ /* ... after we unbound from the underlying device? */ ++ dofree = (spidev->spi == NULL); ++ spin_unlock_irq(&spidev->spi_lock); ++ + /* last close? */ + spidev->users--; + if (!spidev->users) { +- int dofree; + + kfree(spidev->tx_buffer); + spidev->tx_buffer = NULL; +@@ -651,19 +656,14 @@ static int spidev_release(struct inode *inode, struct file *filp) + kfree(spidev->rx_buffer); + spidev->rx_buffer = NULL; + +- spin_lock_irq(&spidev->spi_lock); +- if (spidev->spi) +- spidev->speed_hz = spidev->spi->max_speed_hz; +- +- /* ... after we unbound from the underlying device? */ +- dofree = (spidev->spi == NULL); +- spin_unlock_irq(&spidev->spi_lock); +- + if (dofree) + kfree(spidev); ++ else ++ spidev->speed_hz = spidev->spi->max_speed_hz; + } + #ifdef CONFIG_SPI_SLAVE +- spi_slave_abort(spidev->spi); ++ if (!dofree) ++ spi_slave_abort(spidev->spi); + #endif + mutex_unlock(&device_list_lock); + +-- +2.25.1 + diff --git a/queue-4.4/spi-spidev-fix-a-race-between-spidev_release-and-spi.patch b/queue-4.4/spi-spidev-fix-a-race-between-spidev_release-and-spi.patch new file mode 100644 index 00000000000..1432cfe40e3 --- /dev/null +++ b/queue-4.4/spi-spidev-fix-a-race-between-spidev_release-and-spi.patch @@ -0,0 +1,62 @@ +From b46be3fe645314ace6d0a1c4a45a61807319e1f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Jun 2020 11:21:24 +0800 +Subject: spi: spidev: fix a race between spidev_release and spidev_remove + +From: Zhenzhong Duan + +[ Upstream commit abd42781c3d2155868821f1b947ae45bbc33330d ] + +Imagine below scene, spidev is referenced after it's freed. + +spidev_release() spidev_remove() +... + spin_lock_irq(&spidev->spi_lock); + spidev->spi = NULL; + spin_unlock_irq(&spidev->spi_lock); +mutex_lock(&device_list_lock); +dofree = (spidev->spi == NULL); +if (dofree) + kfree(spidev); +mutex_unlock(&device_list_lock); + mutex_lock(&device_list_lock); + list_del(&spidev->device_entry); + device_destroy(spidev_class, spidev->devt); + clear_bit(MINOR(spidev->devt), minors); + if (spidev->users == 0) + kfree(spidev); + mutex_unlock(&device_list_lock); + +Fix it by resetting spidev->spi in device_list_lock's protection. + +Signed-off-by: Zhenzhong Duan +Link: https://lore.kernel.org/r/20200618032125.4650-1-zhenzhong.duan@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spidev.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c +index 3709088d4d244..80beb8406f200 100644 +--- a/drivers/spi/spidev.c ++++ b/drivers/spi/spidev.c +@@ -769,13 +769,13 @@ static int spidev_remove(struct spi_device *spi) + { + struct spidev_data *spidev = spi_get_drvdata(spi); + ++ /* prevent new opens */ ++ mutex_lock(&device_list_lock); + /* make sure ops on existing fds can abort cleanly */ + spin_lock_irq(&spidev->spi_lock); + spidev->spi = NULL; + spin_unlock_irq(&spidev->spi_lock); + +- /* prevent new opens */ +- mutex_lock(&device_list_lock); + list_del(&spidev->device_entry); + device_destroy(spidev_class, spidev->devt); + clear_bit(MINOR(spidev->devt), minors); +-- +2.25.1 + -- 2.47.3