The only 'new_state' values passed by upstream kernel code to
scsi_internal_device_unblock_nowait() are SDEV_RUNNING and
SDEV_TRANSPORT_OFFLINE. These are the only values that should be passed
to this function. Hence Check the value of the 'new_state' argument
to avoid that scsi_internal_device_unblock_nowait() would be used
to trigger an illegal SCSI device state transition. In this context
'illegal' means not allowed by scsi_device_set_state().

Cc: Christoph Hellwig <h...@lst.de>
Cc: Hannes Reinecke <h...@suse.com>
Cc: Johannes Thumshirn <jthumsh...@suse.de>
Cc: Ming Lei <ming....@redhat.com>
Signed-off-by: Bart Van Assche <bvanass...@acm.org>
---
 drivers/scsi/scsi_lib.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 9381171c2fc0..497cd4799e0a 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2676,6 +2676,14 @@ void scsi_start_queue(struct scsi_device *sdev)
 int scsi_internal_device_unblock_nowait(struct scsi_device *sdev,
                                        enum scsi_device_state new_state)
 {
+       switch (new_state) {
+       case SDEV_RUNNING:
+       case SDEV_TRANSPORT_OFFLINE:
+               break;
+       default:
+               return -EINVAL;
+       }
+
        /*
         * Try to transition the scsi device to SDEV_RUNNING or one of the
         * offlined states and goose the device queue if successful.
-- 
2.22.0.709.g102302147b-goog

Reply via email to