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